document.addEventListener('DOMContentLoaded', () => { const tableState = { data: [], page: 1, pageSize: 10, search: '', lastPage: 1, total: 0, startDate: '', endDate: '', mode: 'pengajuan' }; const historyState = { data: [], page: 1, pageSize: 10, search: '', lastPage: 1, total: 0, startDate: '', endDate: '', mode: 'history' }; const tbodyPengajuan = document.getElementById('tablePengajuanFile'); const tbodyHistory = document.getElementById('tableHistoryFile'); const paginationPengajuan = document.getElementById('paginationPengajuan'); const paginationHistory = document.getElementById('paginationHistory'); const summaryEl = document.getElementById('tableSummary'); const pageSizeSelect = document.getElementById('tablePageSize'); const startDateInput = document.getElementById('startDate'); const endDateInput = document.getElementById('endDate'); const tabsEl = document.getElementById('pengajuanTabs'); const titleEl = document.getElementById('pengajuanTitle'); const tabPengajuanEl = document.getElementById('tabPengajuan'); const tabHistoryEl = document.getElementById('tabHistory'); const selectAllCheckbox = document.getElementById('selectAllPengajuan'); const bulkDeleteBtn = document.getElementById('bulkDeleteBtn'); const clearSelectionBtn = document.getElementById('clearSelectionBtn'); const selectedCountEl = document.getElementById('selectedCount'); const bulkActionsEl = document.getElementById('pengajuanBulkActions'); const deleteDataEl = document.getElementById('deleteData'); const pendingPersetujuanNotice = document.getElementById('pendingPersetujuanNotice'); const pendingPersetujuanNoticeCount = document.getElementById('pendingPersetujuanNoticeCount'); const formCreate = document.getElementById('formFile'); const modalCreate = document.getElementById('modalCreateFile'); let colCount = 1; const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content'); const editForm = document.getElementById('formEditPengajuanFile'); const editUnitSelect = $('#edit_id_unit_kerja'); const editSubUnitSelect = $('#edit_id_sub_unit_kerja'); const selectedIds = new Set(); const isKomiteMutu = !!window.isKomiteMutu; const isTurt = !!window.isTurt; const isAtasan = !!window.isAtasan; let editFromQueryId = new URLSearchParams(window.location.search).get('edit'); if (pageSizeSelect) { const initialSize = parseInt(pageSizeSelect.value); if (!isNaN(initialSize)) { tableState.pageSize = initialSize; historyState.pageSize = initialSize; } pageSizeSelect.addEventListener('change', (e) => { const val = parseInt(e.target.value); if (!isNaN(val) && val > 0) { tableState.pageSize = val; historyState.pageSize = val; tableState.page = 1; historyState.page = 1; fetchData(); } }); } window.applyDateFilter = function(){ const start = startDateInput.value || ''; const end = endDateInput.value || ''; tableState.startDate = start; tableState.endDate = end; historyState.startDate = start; historyState.endDate = end; tableState.page = 1; historyState.page = 1; fetchData(); } function formatTanggal(dateString) { if (!dateString) return '-'; const d = new Date(dateString); return d.toLocaleDateString('id-ID', { day: '2-digit', month: 'short', year: 'numeric' }); } function getSelectableIdsOnPage(){ return (tableState.data || []).map((row) => String(row.file_directory_id)); } function updateSelectAllState(){ if (!selectAllCheckbox) return; if (tableState.mode === 'history' || tableState.mode === 'persetujuan') { selectAllCheckbox.checked = false; selectAllCheckbox.indeterminate = false; selectAllCheckbox.disabled = true; return; } const pageIds = getSelectableIdsOnPage(); if (pageIds.length === 0) { selectAllCheckbox.checked = false; selectAllCheckbox.indeterminate = false; selectAllCheckbox.disabled = true; return; } selectAllCheckbox.disabled = false; const selectedOnPage = pageIds.filter((id) => selectedIds.has(id)).length; selectAllCheckbox.checked = selectedOnPage > 0 && selectedOnPage === pageIds.length; selectAllCheckbox.indeterminate = selectedOnPage > 0 && selectedOnPage < pageIds.length; } function updateSelectionUI(){ const count = selectedIds.size; if (selectedCountEl) selectedCountEl.textContent = String(count); if (bulkDeleteBtn) bulkDeleteBtn.disabled = count === 0 || tableState.mode === 'history' || tableState.mode === 'persetujuan'; if (clearSelectionBtn) clearSelectionBtn.disabled = count === 0 || tableState.mode === 'history' || tableState.mode === 'persetujuan'; updateSelectAllState(); } function approvalBadge(status, label){ const normalized = String(status || '').toLowerCase(); if (normalized === 'approved') return `Approved ${label}`; if (normalized.startsWith('rejected')) return `Rejected ${label}`; if (normalized.startsWith('revised')) return `Revised ${label}`; return `Pending ${label}`; } function hasRevisionInfo(item){ return !!(item?.revision || item?.mutu_revision || item?.turt_revision); } function collectRevisionNotes(item){ const notes = []; const genericRevision = String(item?.revision || '').trim(); const mutuRevision = String(item?.mutu_revision || '').trim(); const turtRevision = String(item?.turt_revision || '').trim(); if (genericRevision) { const lowerGeneric = genericRevision.toLowerCase(); if (!lowerGeneric.startsWith('komite mutu:') && !lowerGeneric.startsWith('turt:')) { notes.push({ label: 'Atasan/Bagian Terkait', text: genericRevision }); } } if (mutuRevision) { notes.push({ label: 'Komite Mutu', text: mutuRevision }); } if (turtRevision) { notes.push({ label: 'TURT', text: turtRevision }); } return notes; } function escapeHtml(value){ return String(value ?? '') .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } function buildRevisionNotesHtml(notes){ if (!notes.length) { return '
Tidak ada catatan revisi.
'; } return `
${notes.map(note => `
${escapeHtml(note.label)}
${escapeHtml(note.text)}
`).join('')}
`; } function isRejectedStatus(item){ return String(item?.status_action || '').toLowerCase().startsWith('rejected') || String(item?.status_mutu || '').toLowerCase().startsWith('rejected') || String(item?.status_turt || '').toLowerCase().startsWith('rejected'); } function isApprovedStatus(status){ return String(status || '').toLowerCase() === 'approved'; } function canProcessRoleStatus(status){ const normalized = String(status || '').toLowerCase(); return normalized === '' || normalized.startsWith('revised'); } function getPengajuanStatusBadges(item){ const actionStatus = String(item?.status_action || '').toLowerCase(); const mutuStatus = String(item?.status_mutu || '').toLowerCase(); const turtStatus = String(item?.status_turt || '').toLowerCase(); if (actionStatus.startsWith('revised')) { return `Revised`; } if (actionStatus.startsWith('rejected')) { return `Rejected Atasan`; } if (actionStatus !== 'approved') { return `Pending Atasan`; } const statuses = []; if (item?.is_akre) { if (mutuStatus.startsWith('rejected mutu')) { statuses.push(`Rejected Mutu`); } else if (mutuStatus === 'revised mutu') { statuses.push(`Revisi Mutu`); } else if(mutuStatus === 'approved'){ statuses.push(`Approved Mutu`); }else{ statuses.push(`Pending Mutu`); } } if (item?.master_kategori_directory_id) { if (turtStatus.startsWith('rejected turt')) { statuses.push(`Rejected TURT`); } else if (turtStatus === 'revised turt') { statuses.push(`Revisi TURT`); } else if(turtStatus === 'approved'){ statuses.push(`Approved TURT`); } else{ statuses.push(`Pending TURT`); } } if (statuses.length > 0) { return statuses.join(' '); } return `Approved`; } function buildRow(item){ let tanggal = item.entry_at ? formatTanggal(item.entry_at) : '-'; let tanggalExp = item.tgl_expired ? formatTanggal(item.tgl_expired) : '-'; let tanggalTerbit = item.tanggal_terbit ? formatTanggal(item.tanggal_terbit) : '-'; const isApproved = isApprovedStatus(item?.status_action); const isRejected = isRejectedStatus(item); const showEdit = isRejected; const showInfo = isRejected && hasRevisionInfo(item); const id = String(item.file_directory_id); const checked = selectedIds.has(id); const aksi = `
${showInfo ? ` ` : ''} ${showEdit ? ` ` : ''}
`; return ` ${aksi} ${item.no_dokumen || '-'}
${getPengajuanStatusBadges(item)}
${aksesBadge(item?.permission_file)} ${item.nama_dokumen} ${item.is_akre ? `Dokumen akreditasi` : ` ${item.name_kategori || '-'} ${item.name_unit || '-'} ` } ${tanggalTerbit} ${tanggalExp} ${tanggal} `; } function buildRowPersetujuan(item){ const tanggal = item.entry_at ? formatTanggal(item.entry_at) : '-'; const tanggalExp = item.tgl_expired ? formatTanggal(item.tgl_expired) : '-'; const tanggalTerbit = item.tanggal_terbit ? formatTanggal(item.tanggal_terbit) : '-'; const showMutu = isKomiteMutu && !!item.is_akre; const showTurt = isTurt; const actions = [ `` ]; if (showMutu && canProcessRoleStatus(item.status_mutu)) { actions.push(``); actions.push(``); } if (showTurt && canProcessRoleStatus(item.status_turt)) { actions.push(``); actions.push(``); } if (hasRevisionInfo(item)) { actions.push(``); } const statusParts = []; if (item.is_akre) { statusParts.push(approvalBadge(item.status_mutu, 'Mutu')); } if (item.master_kategori_directory_id) { statusParts.push(approvalBadge(item.status_turt, 'TURT')); } return `
${actions.join('')}
${item.no_dokumen || '-'}
${statusParts.join('')}
${aksesBadge(item?.permission_file)} ${item.nama_dokumen} ${item.is_akre ? `Dokumen akreditasi` : `${item.name_kategori || '-'}${item.name_unit || '-'}`} ${tanggalTerbit} ${tanggalExp} ${tanggal} `; } function buildHistoryRow(item){ const tanggal = item.entry_at ? formatTanggal(item.entry_at) : '-'; const tanggalExp = item.tgl_expired ? formatTanggal(item.tgl_expired) : '-'; const tanggalTerbit = item.tanggal_terbit ? formatTanggal(item.tanggal_terbit) : '-'; const actionType = item?.action_type || '-'; return ` ${item.no_dokumen || '-'} ${aksesBadge(item?.permission_file)} ${item.nama_dokumen || '-'} ${item.folder || '-'} ${item.part || '-'} ${item.action_type} ${tanggal} `; } function aksesBadge(akses){ if (akses){ return 'Umum'; } else{ return 'Internal Unit'; } } function getItemById(id){ return (tableState.data || []).find((row) => String(row.file_directory_id) === String(id)); } function deleteDocuments(ids, successMessage){ return fetch('/delete-file/bulk', { method: 'DELETE', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken }, body: JSON.stringify({ ids }) }).then(async(res) => { const data = await res.json(); if (!res.ok || !data?.success) { throw new Error(data?.message || 'Gagal menghapus dokumen.'); } ids.forEach((id) => selectedIds.delete(String(id))); if (window.idDirectory && ids.includes(String(window.idDirectory))) { window.idDirectory = null; window.currentFile = null; if (deleteDataEl) deleteDataEl.classList.add('d-none'); const modalEl = document.getElementById('previewModal'); const modalInstance = modalEl ? bootstrap.Modal.getInstance(modalEl) : null; modalInstance?.hide(); } Swal.fire({ icon: 'success', title: 'Berhasil', text: data.message || successMessage, timer: 1500, showConfirmButton: false }); fetchData(); }); } function renderPagination(totalPages){ const activeState = tableState.mode === 'history' ? historyState : tableState; const paginationEl = tableState.mode === 'history' ? paginationHistory : paginationPengajuan; if (!paginationEl) return; if (totalPages <= 1) { paginationEl.innerHTML = ''; return; } const maxButtons = 5; let start = Math.max(1, activeState.page - Math.floor(maxButtons/2)); let end = Math.min(totalPages, start + maxButtons - 1); start = Math.max(1, end - maxButtons + 1); let buttons = ''; buttons += ``; for (let i = start; i <= end; i++) { buttons += ``; } buttons += ``; paginationEl.innerHTML = `
${buttons}
Halaman ${activeState.page} dari ${totalPages}
`; } function bindPagination(paginationEl, state){ if (!paginationEl) return; paginationEl.addEventListener('click', (e) => { const page = e.target.getAttribute('data-page'); if (!page) return; if (page === 'prev' && state.page > 1) state.page--; else if (page === 'next') { if (state.page < state.lastPage) state.page++; } else { state.page = parseInt(page); } fetchData(); }); } bindPagination(paginationPengajuan, tableState); bindPagination(paginationHistory, historyState); function renderTable(){ const isHistoryMode = tableState.mode === 'history'; const isPersetujuan = tableState.mode === 'persetujuan'; const activeState = isHistoryMode ? historyState : tableState; const pageData = activeState.data || []; const targetBody = isHistoryMode ? tbodyHistory : tbodyPengajuan; const colSpan = isHistoryMode ? 9 : 11; const rowBuilder = isHistoryMode ? buildHistoryRow : (isPersetujuan ? buildRowPersetujuan : buildRow); if (pageData.length === 0) { targetBody.innerHTML = ` Tidak ada data `; } else { targetBody.innerHTML = pageData.map(rowBuilder).join(''); } const from = activeState.total === 0 ? 0 : ((activeState.page - 1) * activeState.pageSize) + 1; const to = Math.min(((activeState.page - 1) * activeState.pageSize) + pageData.length, activeState.total); if (summaryEl) { summaryEl.textContent = activeState.total ? `Menampilkan ${from} - ${to} dari ${activeState.total} data` : 'Tidak ada data'; } renderPagination(activeState.lastPage || 1); updateSelectionUI(); maybeOpenEditFromQuery(); } function maybeOpenEditFromQuery(){ if (!editFromQueryId || tableState.mode !== 'pengajuan') return; const item = getItemById(editFromQueryId); if (!item) return; const cleanUrl = new URL(window.location.href); cleanUrl.searchParams.delete('edit'); window.history.replaceState({}, '', cleanUrl.toString()); const pendingId = editFromQueryId; editFromQueryId = null; window.editFileReject(pendingId); } let searchDebounce; window.debouncedTableSearch = function(value){ clearTimeout(searchDebounce); searchDebounce = setTimeout(() => { const keyword = value.trim(); tableState.search = keyword; historyState.search = keyword; tableState.page = 1; historyState.page = 1; fetchData(); }, 250); } window.refreshLog = function(){ tableState.search = ''; tableState.startDate = ''; tableState.endDate = ''; historyState.search = ''; historyState.startDate = ''; historyState.endDate = ''; document.getElementById('tableSearch').value = ''; startDateInput.value = ''; endDateInput.value = ''; selectedIds.clear(); tableState.page = 1; historyState.page = 1; fetchData(); } function updateTabUI(){ if (tabsEl) { tabsEl.querySelectorAll('.nav-link').forEach((btn) => { btn.classList.toggle('active', btn.getAttribute('data-mode') === tableState.mode); }); } if (titleEl) { titleEl.textContent = tableState.mode === 'history' ? 'Log History' : (tableState.mode === 'persetujuan' ? 'Data Persetujuan' : 'Data Pengajuan'); } document.body.dataset.pengajuanMode = tableState.mode; if (tabPengajuanEl && tabHistoryEl) { tabPengajuanEl.classList.toggle('d-none', tableState.mode === 'history'); tabHistoryEl.classList.toggle('d-none', tableState.mode !== 'history'); } if (bulkActionsEl) { bulkActionsEl.classList.toggle('d-none', tableState.mode === 'history' || tableState.mode === 'persetujuan'); } if (deleteDataEl && (tableState.mode === 'history' || tableState.mode === 'persetujuan')) { deleteDataEl.classList.add('d-none'); } updateSelectionUI(); } function updatePendingPersetujuanIndicators(total){ const count = Number(total || 0); console.log(pendingPersetujuanNoticeCount); if (pendingPersetujuanNotice && pendingPersetujuanNoticeCount) { pendingPersetujuanNoticeCount.textContent = String(count); pendingPersetujuanNotice.classList.toggle('d-none', count <= 0); pendingPersetujuanNotice.classList.toggle('d-flex', count > 0); } } function fetchPendingPersetujuanCount(){ if (!(isKomiteMutu || isTurt || isAtasan)) return; fetch('/data/count-pending', { headers: { 'Accept': 'application/json' } }) .then(res => res.json()) .then(data => { updatePendingPersetujuanIndicators(data?.count || 0); }) .catch(() => { updatePendingPersetujuanIndicators(0); }); } if (tabsEl) { tabsEl.addEventListener('click', (e) => { const btn = e.target.closest('[data-mode]'); if (!btn) return; const mode = btn.getAttribute('data-mode'); if (!mode || mode === tableState.mode) return; tableState.mode = mode; tableState.page = 1; updateTabUI(); fetchData(); }); } if (tbodyPengajuan) { tbodyPengajuan.addEventListener('change', (e) => { const target = e.target; if (!target.classList.contains('row-select')) return; const id = target.getAttribute('data-id'); if (!id) return; if (target.checked) selectedIds.add(id); else selectedIds.delete(id); const row = target.closest('tr'); if (row) row.classList.toggle('table-active', target.checked); updateSelectionUI(); }); } if (selectAllCheckbox) { selectAllCheckbox.addEventListener('change', () => { const pageIds = getSelectableIdsOnPage(); if (selectAllCheckbox.checked) { pageIds.forEach((id) => selectedIds.add(id)); } else { pageIds.forEach((id) => selectedIds.delete(id)); } renderTable(); }); } if (clearSelectionBtn) { clearSelectionBtn.addEventListener('click', () => { selectedIds.clear(); renderTable(); }); } if (bulkDeleteBtn) { bulkDeleteBtn.addEventListener('click', () => { if (selectedIds.size === 0) return; const ids = Array.from(selectedIds); Swal.fire({ title: 'Hapus dokumen terpilih?', text: `Total ${ids.length} dokumen akan dihapus.`, icon: 'warning', showCancelButton: true, confirmButtonText: 'Hapus', cancelButtonText: 'Batal' }).then((result) => { if (!result.isConfirmed) return; deleteDocuments(ids, 'Dokumen berhasil dihapus.').catch((err) => { Swal.fire({ icon: 'error', title: 'Gagal', text: err.message || 'Terjadi kesalahan.' }); }); }); }); } function fetchData(){ if (summaryEl) summaryEl.textContent = 'Memuat data...'; const activeState = tableState.mode === 'history' ? historyState : tableState; const params = new URLSearchParams({ page: activeState.page, per_page: activeState.pageSize, keyword: activeState.search || '', start_date: activeState.startDate || '', end_date: activeState.endDate || '', mode: tableState.mode }); const endpoint = tableState.mode === 'history' ? `/data/log-dokumen?${params.toString()}` : `/datatable/pengajuan-file?${params.toString()}`; fetch(endpoint) .then(res => res.json()) .then(data => { activeState.data = data?.data || []; activeState.lastPage = data?.pagination?.last_page || 1; activeState.total = data?.pagination?.total || 0; renderTable(); fetchPendingPersetujuanCount(); }) .catch(err => { console.error(err); if (summaryEl) summaryEl.textContent = 'Gagal memuat data'; }); } window.infoReject = function(id){ const item = getItemById(id); Swal.fire({ title: 'Catatan Revisi', html: buildRevisionNotesHtml(collectRevisionNotes(item)), icon: 'info', confirmButtonText: 'Tutup' }); } window.approvePersetujuan = function(type, id, fileName){ const endpoint = type === 'mutu' ? `/pengajuan-file/${id}/approve-mutu` : `/pengajuan-file/${id}/approve-turt`; const label = type === 'mutu' ? 'Komite Mutu' : 'TURT'; Swal.fire({ title: `Approve ${label}?`, text: fileName || 'Dokumen akan disetujui.', icon: 'question', showCancelButton: true, confirmButtonText: 'Approve', cancelButtonText: 'Batal', }).then((result) => { if (!result.isConfirmed) return; fetch(endpoint, { method: 'POST', headers: { 'X-CSRF-TOKEN': csrfToken, 'Content-Type': 'application/json' }, }).then(async(res) => { const data = await res.json(); if (!res.ok || !data?.status) { throw new Error(data?.message || 'Gagal approve.'); } Swal.fire({ icon: 'success', title: 'Berhasil', text: data.message || 'Dokumen disetujui.', timer: 1500, showConfirmButton: false }); if (typeof window.refreshPendingCount === 'function') window.refreshPendingCount(); fetchData(); }).catch((err) => { Swal.fire({ icon: 'error', title: 'Gagal', text: err.message || 'Terjadi kesalahan.' }); }); }); } window.rejectPersetujuan = function(type, id, fileName){ const endpoint = type === 'mutu' ? `/pengajuan-file/${id}/reject-mutu` : `/pengajuan-file/${id}/reject-turt`; const label = type === 'mutu' ? 'Komite Mutu' : 'TURT'; Swal.fire({ title: `Reject ${label}?`, text: fileName || 'Dokumen akan ditolak.', icon: 'warning', showCancelButton: true, confirmButtonText: 'Reject', cancelButtonText: 'Batal', input: 'textarea', inputLabel: 'Catatan', inputPlaceholder: 'Tulis alasan atau catatan revisi...', inputAttributes: { 'aria-label': 'Catatan' }, preConfirm: (value) => { const revision = (value || '').trim(); if (!revision) { Swal.showValidationMessage('Catatan revisi wajib diisi.'); } return revision; } }).then((result) => { if (!result.isConfirmed) return; fetch(endpoint, { method: 'POST', headers: { 'X-CSRF-TOKEN': csrfToken, 'Content-Type': 'application/json' }, body: JSON.stringify({ revision: result.value }) }).then(async(res) => { const data = await res.json(); if (!res.ok || !data?.status) { throw new Error(data?.message || 'Gagal reject.'); } Swal.fire({ icon: 'success', title: 'Berhasil', text: data.message || 'Dokumen ditolak.', timer: 1500, showConfirmButton: false }); if (typeof window.refreshPendingCount === 'function') window.refreshPendingCount(); fetchData(); }).catch((err) => { Swal.fire({ icon: 'error', title: 'Gagal', text: err.message || 'Terjadi kesalahan.' }); }); }); } window.infoDok = function(e){ let fileUrl = $(e).data('file'); let noDokumen = $(e).data('no_dokumen') let tanggalTerbit = $(e).data('tanggal_terbit') let permissionFile = $(e).data('permission_file') let fileName = $(e).data('fileName') currentFile = fileUrl; idDirectory = $(e).data('id'); const titleEl = document.getElementById('confirm_preview_file'); if (titleEl) titleEl.textContent = fileName; const noEl = document.getElementById('confirm-upload-dokumen'); if (noEl) noEl.textContent = noDokumen; const tglEl = document.getElementById('confirm-time-dokumen'); if (tglEl) tglEl.textContent = tanggalTerbit; const permEl = document.getElementById('confirm-permission'); if (permEl) { const publicDoc = isPublic(permissionFile); permEl.textContent = publicDoc ? 'Umum' : 'Internal Unit'; permEl.className = 'badge ' + (publicDoc ? 'bg-success' : 'bg-secondary'); } if (deleteDataEl) { deleteDataEl.classList.remove('d-none'); } let previewBox = document.getElementById('file-preview'); previewBox.innerHTML = `
`; openPreview(idDirectory); $("#previewModal").modal('show') } function byId(id){ return document.getElementById(id); } function setInputValue(el, value){ if (!el) return; el.value = value ?? ''; } function setTextValue(el, value){ if (!el) return; el.textContent = value || ''; } function setChecked(el, value){ if (!el) return; el.checked = !!value; } function setSelectValue(selectEl, value, label){ if (!selectEl) return; if (value === undefined || value === null || value === '') { selectEl.value = ''; return; } const exists = Array.from(selectEl.options).some(opt => opt.value === value); if (!exists) { selectEl.append(new Option(label || value, value, true, true)); } selectEl.value = value; } function triggerSelect2(selectEl){ if (window.$ && $.fn.select2) $(selectEl).trigger('change'); } function formatDateForInput(date) { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); return `${year}-${month}-${day}`; } function formatDateDisplay(dateValue) { if (!dateValue) return ''; const date = new Date(`${dateValue}T00:00:00`); if (Number.isNaN(date.getTime())) return ''; const day = String(date.getDate()).padStart(2, '0'); const month = String(date.getMonth() + 1).padStart(2, '0'); const year = date.getFullYear(); return `${day}/${month}/${year}`; } function addYearsToDate(dateValue, years) { if (!dateValue || !years) return ''; const baseDate = new Date(`${dateValue}T00:00:00`); if (Number.isNaN(baseDate.getTime())) return ''; const originalDay = baseDate.getDate(); baseDate.setFullYear(baseDate.getFullYear() + Number(years)); if (baseDate.getDate() !== originalDay) { baseDate.setDate(0); } return formatDateForInput(baseDate); } function syncMasaBerlakuField(selectEl) { if (!selectEl) return; const fieldWrap = document.getElementById(selectEl.dataset.dateTarget); const input = document.getElementById(selectEl.dataset.inputTarget); const preview = document.getElementById(selectEl.dataset.previewTarget); const baseInput = document.getElementById(selectEl.dataset.baseTarget); if (!fieldWrap || !input) return; if (selectEl.value === 'custom') { fieldWrap.classList.remove('d-none'); input.disabled = false; if (preview) preview.textContent = ''; return; } fieldWrap.classList.add('d-none'); input.disabled = true; input.value = ''; if (!preview) return; if (!selectEl.value) { preview.textContent = ''; return; } if (!baseInput || !baseInput.value) { preview.textContent = 'Pilih Tanggal Terbit untuk melihat hasil masa berlaku.'; return; } const expiredDate = addYearsToDate(baseInput.value, selectEl.value); preview.textContent = expiredDate ? `Tanggal kedaluwarsa: ${formatDateDisplay(expiredDate)}` : ''; } function prepareExpiryInputs(formEl) { const selects = formEl.querySelectorAll('.masa-berlaku-select'); for (const selectEl of selects) { const option = selectEl.value; const dateInput = document.getElementById(selectEl.dataset.inputTarget); const baseInput = document.getElementById(selectEl.dataset.baseTarget); if (!dateInput) continue; if (!option) { dateInput.value = ''; dateInput.disabled = true; continue; } if (option === 'custom') { if (!dateInput.value) { return 'Tanggal kedaluwarsa wajib diisi saat memilih opsi Lainnya.'; } dateInput.disabled = false; continue; } if (!baseInput || !baseInput.value) { return 'Tanggal Terbit wajib diisi saat memilih masa berlaku 1, 2, atau 3 tahun.'; } dateInput.value = addYearsToDate(baseInput.value, option); dateInput.disabled = false; } return null; } function arrayFilterEmpty(arr){ return (arr || []).filter((val) => val !== null && val !== undefined && String(val).trim() !== ''); } function initSelect2($el, options){ if (!$el || !$el.length || !window.$ || !$.fn.select2) return; $el.select2(options); } function initEditSelects(){ if (editUnitSelect.length) { editUnitSelect.select2({ placeholder: '-- Pilih Unit Kerja --', allowClear: true, width: '100%', dropdownParent: $('#modalEditPengajuanFile'), ajax: { url: '/select-unit-kerja-mapping', dataType: 'json', delay: 250, data: function (params) { return { q: params.term || '' }; }, processResults: function (data) { return { results: (data?.data || []).map(item => ({ id: String(item.id), text: item.name })) }; }, cache: true }, minimumInputLength: 0 }); } if (editSubUnitSelect.length) { editSubUnitSelect.select2({ placeholder: '-- Pilih Sub Unit Kerja --', allowClear: true, width: '100%', dropdownParent: $('#modalEditPengajuanFile') }); } editUnitSelect.on('change', function(){ const val = $(this).val(); if (!val) return; loadEditSubUnit(String(val), null, null); }); } let akreData = []; let akreLoaded = false; let akreFlat = []; function initEditExtraSelects(){ const akreSelect = byId('edit_akre_select'); if (akreSelect) { loadAkreData().then(() => { fillAkreSelect(akreSelect); initSelect2($(akreSelect), { dropdownParent: $('#modalEditPengajuanFile'), placeholder: 'Pilih Instrumen', allowClear: true }); }); } const editKat = $('#edit_kategori'); const editHukum = $('#edit_kategori_hukum'); initSelect2(editKat, { dropdownParent: $('#modalEditPengajuanFile'), placeholder: 'Pilih Kategori', allowClear: true }); initSelect2(editHukum, { dropdownParent: $('#modalEditPengajuanFile'), placeholder: 'Pilih Kategori Hukum', allowClear: true }); } function loadEditSubUnit(unitId, selectedSubId, selectedSubName){ editSubUnitSelect.empty().append(''); if (!unitId) return; $.ajax({ url: `/select-sub-unit-kerja-mapping/${unitId}`, method: 'GET', success: function(response) { if (response?.data) { response.data.forEach(unit => { const optVal = String(unit.id); const isSelected = selectedSubId && String(unit.id) === String(selectedSubId); const option = new Option(unit.name, optVal, false, isSelected); editSubUnitSelect.append(option); }); if (selectedSubId && selectedSubName && editSubUnitSelect.find(`option[value="${selectedSubId}"]`).length === 0) { editSubUnitSelect.append(new Option(selectedSubName, String(selectedSubId), true, true)); } editSubUnitSelect.trigger('change'); } } }); } function setEditAkreValue(value){ const akreEl = byId('edit_akre_select'); if (!akreEl) return; loadAkreData().then(() => { fillAkreSelect(akreEl); if (value && akreValueExists(value)) { setSelectValue(akreEl, value, value); } else { akreEl.value = ''; } triggerSelect2(akreEl); }); } function setEditKategoriHukum(value){ const hukumEl = byId('edit_kategori_hukum'); if (!hukumEl) return; setSelectValue(hukumEl, value, value); triggerSelect2(hukumEl); } function setEditKategoriDir(item, kategoriName){ const katEl = byId('edit_kategori'); const katId = item?.master_kategori_directory_id; if (!katEl || !katId) return; const match = Array.from(katEl.options).find((opt) => String(opt.value).startsWith(`${katId}/`)); if (match) { katEl.value = match.value; } else { const label = kategoriName || 'Kategori'; const katVal = `${katId}/${label}`; setSelectValue(katEl, katVal, label); } triggerSelect2(katEl); } window.editFileReject = function(id){ const item = getItemById(id); if (!item) { Swal.fire({ icon: 'error', title: 'Gagal', text: 'Data tidak ditemukan.' }); return; } setInputValue(byId('edit_file_directory_id'), item.file_directory_id); setInputValue(byId('edit_no_dokumen'), item.no_dokumen); setInputValue(byId('edit_nama_dokumen'), item.nama_dokumen); setInputValue(byId('edit_tanggal_terbit'), item.tanggal_terbit); setInputValue(byId('edit_tgl_expired'), item.tgl_expired); const isPublic = item.permission_file === true || item.permission_file === 1 || item.permission_file === '1'; setChecked(byId('edit_perm_yes'), isPublic); setChecked(byId('edit_perm_no'), !isPublic); const editMasaBerlaku = byId('edit_masa_berlaku_option'); if (editMasaBerlaku) { editMasaBerlaku.value = item.tgl_expired ? 'custom' : ''; syncMasaBerlakuField(editMasaBerlaku); } const displayName = item.fileName || (item.file ? String(item.file).split('/').pop() : ''); setTextValue(byId('edit_current_file'), displayName ? `File saat ini: ${displayName}` : ''); const parts = arrayFilterEmpty((item.file || '').split('/')); const unitNameFromPath = parts[0] || ''; const subNameFromPath = parts[1] || ''; const kategoriName = parts[2] || ''; const unitName = item.unit_kerja_name || item.name_unit || item.nama_unit_kerja || item.unit_name || item.unit_kerja || ''; if (editUnitSelect.length && item.id_unit_kerja) { const unitLabel = unitName || String(item.id_unit_kerja); const unitVal = String(item.id_unit_kerja); setSelectValue(editUnitSelect[0], unitVal, unitLabel); triggerSelect2(editUnitSelect[0]); const subLabel = item.sub_unit_kerja_name || item.nama_sub_unit_kerja || item.sub_unit_name || item.sub_unit_kerja || String(item.id_sub_unit_kerja || ''); loadEditSubUnit(String(item.id_unit_kerja), item.id_sub_unit_kerja, subLabel || null); } setEditKategoriDir(item, kategoriName); if (item.kategori_hukum) setEditKategoriHukum(item.kategori_hukum); const akreFromFile = parts.length > 1 ? parts.slice(0, -1).join('/') : ''; setEditAkreValue(item.akre || akreFromFile || ''); $("#modalEditPengajuanFile").modal('show'); } const editMasaBerlaku = document.getElementById('edit_masa_berlaku_option'); if (editMasaBerlaku) { editMasaBerlaku.addEventListener('change', function() { syncMasaBerlakuField(editMasaBerlaku); }); } const editTanggalTerbit = document.getElementById('edit_tanggal_terbit'); if (editTanggalTerbit) { editTanggalTerbit.addEventListener('change', function() { if (editMasaBerlaku) syncMasaBerlakuField(editMasaBerlaku); }); } if (editForm) { editForm.addEventListener('submit', (e) => { e.preventDefault(); const id = document.getElementById('edit_file_directory_id')?.value; if (!id) { Swal.fire({ icon: 'error', title: 'Gagal', text: 'ID dokumen tidak ditemukan.' }); return; } const expiryError = prepareExpiryInputs(editForm); if (expiryError) { Swal.fire({ icon: 'warning', title: 'Validasi form', text: expiryError }); return; } const formData = new FormData(editForm); fetch(`/pengajuan-file/${id}/update`, { method: 'POST', headers: { 'X-CSRF-TOKEN': csrfToken }, body: formData }).then(async (res) => { const data = await res.json(); if (!res.ok || !data?.status) { throw new Error(data?.message || 'Gagal memperbarui data.'); } Swal.fire({ icon: 'success', title: 'Berhasil', text: data.message || 'Data berhasil diperbarui.', timer: 1500, showConfirmButton: false }); $("#modalEditPengajuanFile").modal('hide'); if (typeof window.refreshPendingCount === 'function') window.refreshPendingCount(); fetchData(); }).catch((err) => { Swal.fire({ icon: 'error', title: 'Gagal', text: err.message || 'Terjadi kesalahan.' }); }); }); } initEditSelects(); initEditExtraSelects(); updateTabUI(); fetchData(); // ===== Upload baru (seperti dataUnit) ===== document.addEventListener('change', function(e){ if(!e.target.classList.contains('masa-berlaku-select')) return; syncMasaBerlakuField(e.target); }); document.addEventListener('change', function(e){ if (!e.target.matches('input[type="date"][id^="dateActive_"]')) return; const index = e.target.id.replace('dateActive_', ''); const selectEl = document.querySelector(`.masa-berlaku-select[data-index="${index}"]`); if (selectEl) syncMasaBerlakuField(selectEl); }); function resetCreateForm(){ colCount = 1; const colAdd = document.getElementById('col_add_fileV2'); if (colAdd) colAdd.innerHTML = ''; if (formCreate) { formCreate.reset(); $(formCreate).find('select').val(null).trigger('change'); $(formCreate).find('input[type="file"]').val(''); $(formCreate).find('.file-name').addClass('d-none').text(''); } document.querySelectorAll('.masa-berlaku-select').forEach(syncMasaBerlakuField); resetAkreFields(0); enableAkreFields(0); } function loadAkreData(){ if(akreLoaded) return Promise.resolve(akreData); return fetch('/json/akreditasi.jff') .then(res => res.json()) .then(data => { akreData = Array.isArray(data) ? data : []; akreFlat = []; akreLoaded = true; return akreData; }) .catch(() => { akreData = []; akreFlat = []; akreLoaded = true; return akreData; }); } function getAkreFlat(){ if(akreFlat.length) return akreFlat; akreFlat = (akreData || []).flatMap(type => { const segments = Array.isArray(type.segment) ? type.segment : []; return segments.flatMap(seg => { const children = Array.isArray(seg.turunan) ? seg.turunan : []; return children.map(child => ({ value: `${type.name}/${seg.name}/${child.name}`, label: `${type.name} / ${child.name}`, type: type.name, segment: seg.name, item: child.name })); }); }); return akreFlat; } function akreValueExists(value){ if (!value) return false; return getAkreFlat().some(opt => String(opt.value) === String(value)); } function fillAkreSelect(selectEl){ if(!selectEl) return; selectEl.innerHTML = ''; getAkreFlat().forEach(optData => { const opt = document.createElement('option'); opt.value = optData.value; opt.textContent = optData.label; selectEl.appendChild(opt); }); } function setKategoriRequired(index, isRequired){ const katSelect = document.getElementById(`select_kategori_${index}`); if (!katSelect) return; if (isRequired) { katSelect.setAttribute('required', 'required'); } else { katSelect.removeAttribute('required'); } } function resetAkreFields(index){ const selectEl = document.getElementById(`akre_select_${index}`); const typeInput = document.getElementById(`akre_type_${index}`); const segmentInput = document.getElementById(`akre_segment_${index}`); const itemInput = document.getElementById(`akre_item_${index}`); if(selectEl){ selectEl.value = ''; if(window.$ && $.fn.select2) $(selectEl).val(null).trigger('change'); } if(typeInput) typeInput.value = ''; if(segmentInput) segmentInput.value = ''; if(itemInput) itemInput.value = ''; setKategoriRequired(index, false); } function enableAkreFields(index){ const selectEl = document.getElementById(`akre_select_${index}`); // if(selectEl){ // selectEl.disabled = false; // selectEl.required = true; // } setKategoriRequired(index, false); loadAkreData().then(() => { fillAkreSelect(selectEl); if(window.$ && $.fn.select2){ $(selectEl).select2({ dropdownParent: $('#modalCreateFile'), placeholder: 'Pilih Instrumen', allowClear:true }); } }); } function initKategoriSelect2(index){ if(!window.$ || !$.fn.select2) return; const katSelect = $(`#select_kategori_${index}`); const hukumSelect = $(`#select_kategori_hukum_${index}`); if(katSelect.length){ katSelect.select2({ dropdownParent: $('#modalCreateFile'), placeholder:'Pilih Kategori', allowClear:true }); } if(hukumSelect.length){ hukumSelect.select2({ dropdownParent: $('#modalCreateFile'), placeholder:'Pilih Kategori Hukum', allowClear:true }); } } function selectOptionUnitKerjaV1(localCol){ const selectUnit = $(`#select_id_unit_kerja_${localCol}`); const selectSubUnit = $(`#select_id_sub_unit_kerja_${localCol}`); selectUnit.select2({ placeholder: '-- Pilih Unit Kerja --', allowClear:true, width: '100%', dropdownParent: selectUnit.parent(), ajax:{ url : '/select-unit-kerja-mapping', dataType: 'json', delay: 250, data: function(params){ return { q: params.term } }, processResults: function(data){ return { results : (data?.data || []).map(item => ({ id: item.id+'/'+item.name, text: item.name, sub_units: item.sub_unit_kerja })) } }, cache: true, }, minimumInputLength: 0, }); selectSubUnit.select2({ placeholder: '-- Pilih Sub Unit Kerja --', allowClear: true, width: '100%', dropdownParent: selectSubUnit.parent() }); selectUnit.on('select2:select', function (e) { const data = e.params.data; selectSubUnit.empty().append(''); if (data.sub_units && data.sub_units.length > 0) { data.sub_units.forEach(sub => { selectSubUnit.append(``); }); } }); } window.addFormV2 = function(){ const col = document.getElementById('col_add_fileV2'); if (!col) return; const katDok = Array.isArray(window.katDok) ? window.katDok : []; const katOptions = katDok.map(k => ``).join(''); let html = `

#
Opsi 1, 2, dan 3 tahun dihitung dari Tanggal Terbit.
Isi form ini bila dokumen yang diunggah merupakan dokumen akreditasi.
Format yang didukung: PDF.
`; col.insertAdjacentHTML('beforeend', html); selectOptionUnitKerjaV1(colCount); initKategoriSelect2(colCount); enableAkreFields(colCount); setKategoriRequired(colCount, false); const insertedSelect = document.querySelector(`.masa-berlaku-select[data-index="${colCount}"]`); if (insertedSelect) syncMasaBerlakuField(insertedSelect); colCount++; } window.removeCol = function(count){ const el = document.getElementById(`col-${count}`); if (el) el.remove(); } if (formCreate) { const select0 = $('#select_id_unit_kerja_0'); if (select0.length) selectOptionUnitKerjaV1(0); initKategoriSelect2(0); enableAkreFields(0); document.querySelectorAll('.masa-berlaku-select').forEach(syncMasaBerlakuField); formCreate.addEventListener('submit', (e) => { e.preventDefault(); const submitBtn = formCreate.querySelector('button[type="submit"]'); if (submitBtn) submitBtn.disabled = true; if (submitBtn) submitBtn.textContent = 'menyimpan...'; const expiryError = prepareExpiryInputs(formCreate); if (expiryError) { Swal.fire({ icon: 'warning', title: 'Validasi form', text: expiryError }); if (submitBtn) submitBtn.disabled = false; if (submitBtn) submitBtn.textContent = 'Simpan'; return; } const formData = new FormData(formCreate); fetch(`/uploadv2`, { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('input[name="_token"]')?.value || '' }, body: formData }).then(async(res) => { const responseData = await res.json(); if(responseData.status){ Swal.fire({ icon: 'success', title: 'Berhasil', text: responseData.message || 'Data berhasil disimpan.', timer: 1500, showConfirmButton: false }); const modalInstance = bootstrap.Modal.getInstance(modalCreate); modalInstance?.hide(); resetCreateForm(); if (typeof window.refreshPendingCount === 'function') window.refreshPendingCount(); fetchData(); if(responseData.status_action === null || responseData.status_action === undefined){ Swal.fire({ icon: 'info', title: 'Perlu Persetujuan', text: 'Dokumen yang Anda upload butuh persetujuan dari atasan.', confirmButtonText: 'Tutup' }); } } else { throw new Error(responseData.message || 'Terjadi kesalahan saat menyimpan data.'); } }).catch(err => { Swal.fire({ icon: 'error', title: 'Gagal', text: err.message || 'Terjadi kesalahan.' }); }).finally(() => { if (submitBtn) submitBtn.disabled = false; if (submitBtn) submitBtn.textContent = 'Simpan'; }); }); } document.addEventListener('change', function(e){ if(e.target.classList.contains('akre-select')){ const id = e.target.id || ''; const idx = id.split('_').pop(); const [typeVal = '', segmentVal = '', itemVal = ''] = (e.target.value || '').split('/'); const typeInput = document.getElementById(`akre_type_${idx}`); const segmentInput = document.getElementById(`akre_segment_${idx}`); const itemInput = document.getElementById(`akre_item_${idx}`); if(typeInput) typeInput.value = typeVal; if(segmentInput) segmentInput.value = segmentVal; if(itemInput) itemInput.value = itemVal; return; } }); }); document.addEventListener('click', function(e){ if(e.target.matches('.file-link')){ e.preventDefault(); let fileUrl = e.target.getAttribute('data-file'); let noDokumen = e.target.getAttribute('data-no_dokumen') let tanggalTerbit = e.target.getAttribute('data-tanggal_terbit') let permissionFile = e.target.getAttribute('data-permission_file') let fileName = e.target.getAttribute('data-fileName') currentFile = fileUrl; idDirectory = e.target.getAttribute('data-id'); const titleEl = document.getElementById('confirm_preview_file'); if (titleEl) titleEl.textContent = fileName; // set footer info const noEl = document.getElementById('confirm-upload-dokumen'); if (noEl) noEl.textContent = noDokumen; const tglEl = document.getElementById('confirm-time-dokumen'); if (tglEl) tglEl.textContent = tanggalTerbit; const permEl = document.getElementById('confirm-permission'); if (permEl) { const publicDoc = isPublic(permissionFile); permEl.textContent = publicDoc ? 'Umum' : 'Internal Unit'; permEl.className = 'badge ' + (publicDoc ? 'bg-success' : 'bg-secondary'); } const deleteDataEl = document.getElementById('deleteData'); if (deleteDataEl) { deleteDataEl.classList.toggle('d-none', document.body.dataset.pengajuanMode !== 'pengajuan'); } let previewBox = document.getElementById('file-preview'); previewBox.innerHTML = `
`; openPreview(idDirectory); $("#previewModal").modal('show') } if(e.target.matches('#btn-view-full')){ window.open(`/full-preview/${idDirectory}`, '_blank'); } if(e.target.matches('#delete-file')){ if(!idDirectory){ Swal.fire({ icon: 'warning', title: 'Pilih dokumen', text: 'Dokumen belum dipilih.' }); return; } Swal.fire({ title: 'Hapus dokumen ini?', text: 'Dokumen yang dihapus tidak akan tampil lagi.', icon: 'warning', showCancelButton: true, confirmButtonText: 'Hapus', cancelButtonText: 'Batal' }).then((result) => { if (!result.isConfirmed) return; fetch('/delete-file/bulk', { method: 'DELETE', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '' }, body: JSON.stringify({ ids: [String(idDirectory)] }) }).then(async(res) => { const data = await res.json(); if (!res.ok || !data?.success) { throw new Error(data?.message || 'Gagal menghapus dokumen.'); } Swal.fire({ icon: 'success', title: 'Berhasil', text: data.message || 'Dokumen berhasil dihapus.', timer: 1500, showConfirmButton: false }).then(() => { window.location.reload(); }); }).catch((err) => { Swal.fire({ icon: 'error', title: 'Gagal', text: err.message || 'Terjadi kesalahan.' }); }); }); } }) function isPublic(permissionVal){ if(permissionVal === null || permissionVal === undefined) return false; const val = String(permissionVal).toLowerCase(); return val === '1' || val === 'true' || val === 'ya' || val === 'yes'; }