1129 lines
46 KiB
JavaScript
1129 lines
46 KiB
JavaScript
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 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');
|
||
|
||
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 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 = item?.status_action === 'approved';
|
||
const isRejected = item?.status_action === 'rejected';
|
||
const showEdit = !isApproved;
|
||
const showInfo = isRejected;
|
||
const aksi = `
|
||
<div class="d-flex gap-1">
|
||
<button href="#" class="btn btn-sm btn-primary" onclick="infoDok(this)"
|
||
data-file="${item.file}"
|
||
data-fileName="${item.nama_dokumen}"
|
||
data-id="${item.file_directory_id}"
|
||
data-no_dokumen="${item.no_dokumen || '-'}"
|
||
data-tanggal_terbit="${item.tanggal_terbit || '-'}"
|
||
data-permission_file="${item.permission_file || '-'}">
|
||
<i class="fa-solid fa-eye"></i>
|
||
</button>
|
||
${showInfo ? `
|
||
<button class="btn btn-sm btn-info" onclick="infoReject('${item.file_directory_id}')">
|
||
<i class="fa-solid fa-circle-info"></i>
|
||
</button>
|
||
` : ''}
|
||
${showEdit ? `
|
||
<button class="btn btn-sm btn-primary" onclick="editFileReject('${item.file_directory_id}')">
|
||
<i class="fa-solid fa-pen-to-square"></i>
|
||
</button>
|
||
` : ''}
|
||
</div>
|
||
`;
|
||
return `
|
||
<tr>
|
||
<td>${aksi}</td>
|
||
<td>${item.no_dokumen || '-'}</td>
|
||
<td>
|
||
<button class="btn btn-sm
|
||
${item?.status_action === "approved" ? 'btn-success' :
|
||
item?.status_action === "rejected" ? 'btn-danger' :
|
||
item?.status_action === "revised" ? 'btn-info' :
|
||
'btn-warning'}">
|
||
${item?.status_action === "approved" ? 'Approved' :
|
||
item?.status_action === "rejected" ? 'Rejected' :
|
||
item?.status_action === "revised" ? 'Revised' :
|
||
'Pending'}
|
||
</button>
|
||
</td>
|
||
<td>${aksesBadge(item?.permission_file)}</td>
|
||
<td><a href="#" class="file-link"
|
||
data-file="${item.file}"
|
||
data-fileName="${item.nama_dokumen}"
|
||
data-id="${item.file_directory_id}"
|
||
data-no_dokumen="${item.no_dokumen || '-'}"
|
||
data-tanggal_terbit="${item.tanggal_terbit || '-'}"
|
||
data-permission_file="${item.permission_file || '-'}">${item.nama_dokumen}</a></td>
|
||
${item.is_akre ? `<td colspan="2" class="text-center">Dokumen akreditasi</td>` :
|
||
`
|
||
<td>${item.name_kategori || '-'}</td>
|
||
<td>${item.name_unit || '-'}</td>
|
||
`
|
||
}
|
||
|
||
<td class="text-nowrap">${tanggalTerbit}</td>
|
||
<td class="text-nowrap">${tanggalExp}</td>
|
||
<td class="text-nowrap">${tanggal}</td>
|
||
</tr>
|
||
`;
|
||
}
|
||
|
||
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 `
|
||
<tr>
|
||
<td>${item.no_dokumen || '-'}</td>
|
||
<td>${aksesBadge(item?.permission_file)}</td>
|
||
<td><a href="#" class="file-link"
|
||
data-file="${item.file || ''}"
|
||
data-fileName="${item.nama_dokumen || '-'}"
|
||
data-id="${item.file_directory_id || ''}"
|
||
data-no_dokumen="${item.no_dokumen || '-'}"
|
||
data-tanggal_terbit="${item.tanggal_terbit || '-'}"
|
||
data-permission_file="${item.permission_file || '-'}">${item.nama_dokumen || '-'}</a></td>
|
||
<td>${item.folder || '-'}</td>
|
||
<td>${item.part || '-'}</td>
|
||
<td><span class="badge bg-info">${item.action_type}</span></td>
|
||
<td class="text-nowrap">${tanggalTerbit}</td>
|
||
<td class="text-nowrap">${tanggalExp}</td>
|
||
<td class="text-nowrap">${tanggal}</td>
|
||
</tr>
|
||
`;
|
||
}
|
||
|
||
function aksesBadge(akses){
|
||
if (akses){
|
||
return '<span class="badge bg-success">Umum</span>';
|
||
} else{
|
||
return '<span class="badge bg-primary">Internal Unit</span>';
|
||
}
|
||
}
|
||
|
||
function getItemById(id){
|
||
return (tableState.data || []).find((row) => String(row.file_directory_id) === String(id));
|
||
}
|
||
|
||
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 += `<button class="btn btn-outline-secondary btn-sm" data-page="prev" ${activeState.page === 1 ? 'disabled' : ''}>‹</button>`;
|
||
for (let i = start; i <= end; i++) {
|
||
buttons += `<button class="btn btn-sm ${i === activeState.page ? 'btn-primary' : 'btn-outline-secondary'}" data-page="${i}">${i}</button>`;
|
||
}
|
||
buttons += `<button class="btn btn-outline-secondary btn-sm" data-page="next" ${activeState.page === totalPages ? 'disabled' : ''}>›</button>`;
|
||
|
||
paginationEl.innerHTML = `
|
||
<div class="d-flex align-items-center gap-2 flex-wrap">
|
||
<div class="btn-group" role="group">${buttons}</div>
|
||
<span class="small text-muted">Halaman ${activeState.page} dari ${totalPages}</span>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
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 activeState = isHistoryMode ? historyState : tableState;
|
||
const pageData = activeState.data || [];
|
||
const targetBody = isHistoryMode ? tbodyHistory : tbodyPengajuan;
|
||
const colSpan = isHistoryMode ? 9 : 10;
|
||
const rowBuilder = isHistoryMode ? buildHistoryRow : buildRow;
|
||
if (pageData.length === 0) {
|
||
targetBody.innerHTML = `
|
||
<tr>
|
||
<td colspan="${colSpan}" class="text-center text-muted py-4">
|
||
Tidak ada data
|
||
</td>
|
||
</tr>
|
||
`;
|
||
} 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);
|
||
}
|
||
|
||
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 = '';
|
||
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' : 'Data Pengajuan';
|
||
}
|
||
if (tabPengajuanEl && tabHistoryEl) {
|
||
tabPengajuanEl.classList.toggle('d-none', tableState.mode === 'history');
|
||
tabHistoryEl.classList.toggle('d-none', tableState.mode !== 'history');
|
||
}
|
||
}
|
||
|
||
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();
|
||
});
|
||
}
|
||
|
||
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 || ''
|
||
});
|
||
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();
|
||
})
|
||
.catch(err => {
|
||
console.error(err);
|
||
if (summaryEl) summaryEl.textContent = 'Gagal memuat data';
|
||
});
|
||
}
|
||
|
||
window.infoReject = function(id){
|
||
const item = getItemById(id);
|
||
const revision = item?.revision ? String(item.revision) : 'Tidak ada catatan revisi.';
|
||
Swal.fire({
|
||
title: 'Catatan Revisi',
|
||
text: revision,
|
||
icon: 'info',
|
||
confirmButtonText: 'Tutup'
|
||
});
|
||
}
|
||
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');
|
||
}
|
||
let previewBox = document.getElementById('file-preview');
|
||
previewBox.innerHTML = `<div id="pdfWrap" style="height:500px; overflow:auto; background:#f7f7f7; padding:8px;">
|
||
<div id="pdfPages"></div>`;
|
||
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 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('<option value="" disabled selected>-- Pilih Sub Unit Kerja --</option>');
|
||
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 hasExpired = !!item.tgl_expired;
|
||
setChecked(byId('edit_has_expired'), hasExpired);
|
||
syncEditExpiredField();
|
||
|
||
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');
|
||
}
|
||
|
||
function syncEditExpiredField() {
|
||
const editHasExpired = document.getElementById('edit_has_expired');
|
||
const editExpiredInput = document.getElementById('edit_tgl_expired');
|
||
if (!editHasExpired || !editExpiredInput) return;
|
||
editExpiredInput.disabled = !editHasExpired.checked;
|
||
if (!editHasExpired.checked) {
|
||
editExpiredInput.value = '';
|
||
}
|
||
}
|
||
|
||
const editHasExpired = document.getElementById('edit_has_expired');
|
||
if (editHasExpired) {
|
||
editHasExpired.addEventListener('change', syncEditExpiredField);
|
||
}
|
||
|
||
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 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');
|
||
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('toggle-expired')) return;
|
||
const targetId = e.target.getAttribute('data-target');
|
||
if(!targetId) return;
|
||
const fieldWrap = document.getElementById(targetId);
|
||
const input = fieldWrap?.querySelector('input');
|
||
if (input) input.disabled = !e.target.checked;
|
||
});
|
||
|
||
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('');
|
||
}
|
||
resetAkreFields(0);
|
||
enableAkreFields(0);
|
||
}
|
||
|
||
function loadAkreData(){
|
||
if(akreLoaded) return Promise.resolve(akreData);
|
||
return fetch('/json/akreditasi.json')
|
||
.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 = '<option value="">Pilih Instrumen</option>';
|
||
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('<option value="" disabled selected>-- Pilih Sub Unit Kerja --</option>');
|
||
if (data.sub_units && data.sub_units.length > 0) {
|
||
data.sub_units.forEach(sub => {
|
||
selectSubUnit.append(`<option value="${sub.id}/${sub.name}">${sub.name}</option>`);
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
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 => `<option value="${k.master_kategori_directory_id}/${k.nama_kategori_directory}">${k.nama_kategori_directory}</option>`).join('');
|
||
|
||
let html = `
|
||
<div class="row g-3 align-items-start" id="col-${colCount}">
|
||
<hr class="my-3" />
|
||
<div class="col-12 d-flex justify-content-end">
|
||
<button type="button"
|
||
class="btn btn-sm btn-danger"
|
||
onclick="removeCol(${colCount})">
|
||
<i class="fa-solid fa-trash"></i> Hapus
|
||
</button>
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<label class="form-label fw-semibold">Unit <span class="text-danger">*</span></label>
|
||
<select class="form-select"
|
||
name="data[${colCount}][id_unit_kerja]"
|
||
id="select_id_unit_kerja_${colCount}"
|
||
required>
|
||
<option value="" disabled selected>Pilih Unit</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<label class="form-label fw-semibold">Sub Unit <span class="text-danger">*</span></label>
|
||
<select class="form-select"
|
||
name="data[${colCount}][id_sub_unit_kerja]"
|
||
id="select_id_sub_unit_kerja_${colCount}"
|
||
required>
|
||
<option value="" disabled selected>Pilih Sub Unit</option>
|
||
</select>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="col-md-4">
|
||
<label class="form-label fw-semibold">Nomor Dokumen</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text">#</span>
|
||
<input type="text"
|
||
class="form-control"
|
||
name="data[${colCount}][no_dokumen]"
|
||
placeholder="Contoh: 001/RS/IT/I/2026">
|
||
</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label fw-semibold">Nama Dokumen<span class="text-danger">*</span></label>
|
||
<input type="text"
|
||
class="form-control"
|
||
name="data[${colCount}][nama_dokumen]"
|
||
placeholder="Contoh: Panduan Mencuci Tangan" required>
|
||
</div>
|
||
|
||
<div class="col-md-4">
|
||
<label class="form-label fw-semibold">Tanggal Terbit</label>
|
||
<input class="form-control"
|
||
type="date"
|
||
name="data[${colCount}][date_active]">
|
||
</div>
|
||
<div class="col-md-3">
|
||
<div class="form-check">
|
||
<input class="form-check-input toggle-expired"
|
||
type="checkbox"
|
||
id="hasExpired_${colCount}"
|
||
data-target="expiredField_${colCount}">
|
||
<label class="form-check-label" for="hasExpired_${colCount}">Masa Berlaku Dokumen??</label>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-md-5" id="expiredField_${colCount}">
|
||
<label class="form-label fw-semibold">Tanggal Kedaluwarsa Dokumen</label>
|
||
<input class="form-control"
|
||
type="date"
|
||
name="data[${colCount}][tgl_expired]" disabled>
|
||
</div>
|
||
|
||
<div class="col-md-4">
|
||
<label class="form-label fw-semibold">Boleh dilihat unit lain? <span class="text-danger">*</span></label>
|
||
<div class="border rounded-3 p-2 bg-light">
|
||
<div class="form-check">
|
||
<input class="form-check-input"
|
||
type="radio"
|
||
name="data[${colCount}][is_permission]"
|
||
id="perm_yes_${colCount}"
|
||
value="1"
|
||
required>
|
||
<label class="form-check-label" for="perm_yes_${colCount}">Iya</label>
|
||
</div>
|
||
|
||
<div class="form-check mt-1">
|
||
<input class="form-check-input"
|
||
type="radio"
|
||
name="data[${colCount}][is_permission]"
|
||
id="perm_no_${colCount}"
|
||
value="2"
|
||
required>
|
||
<label class="form-check-label" for="perm_no_${colCount}">Tidak</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-md-4">
|
||
<label class="form-label fw-semibold">Instrumen Akreditasi </label>
|
||
<select class="form-select akre-select" id="akre_select_${colCount}" name="data[${colCount}][akre]" style="width: 350px;">
|
||
<option value="">Pilih Instrumen</option>
|
||
</select>
|
||
<div class="form-text text-muted">Isi form ini bila dokumen yang diunggah merupakan dokumen <strong>akreditasi</strong>.</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label fw-semibold">Kategori Hukum</label>
|
||
<select class="form-select select-kat-hukum" name="data[${colCount}][kategori_hukum]" id="select_kategori_hukum_${colCount}" style="width: 350px;">
|
||
<option value="Kebijakan - Peraturan Direktur">Kebijakan - Peraturan Direktur</option>
|
||
<option value="Kebijakan - Keputusan Direktur Utama">Kebijakan - Keputusan Direktur Utama</option>
|
||
<option value="Kebijakan - Surat Edaran">Kebijakan - Surat Edaran</option>
|
||
<option value="Kebijakan - Pengumuman">Kebijakan - Pengumuman</option>
|
||
<option value="Kerjasama - Pelayanan Kesehatan">Kerjasama - Pelayanan Kesehatan</option>
|
||
<option value="Kerjasama - Management">Kerjasama - Management</option>
|
||
<option value="Kerjasama - Pemeliharan">Kerjasama - Pemeliharan</option>
|
||
<option value="Kerjasama - Diklat">Kerjasama - Diklat</option>
|
||
<option value="Kerjasama - Luar Negeri">Kerjasama - Luar Negeri</option>
|
||
<option value="Kerjasama - Area Bisnis">Kerjasama - Area Bisnis</option>
|
||
<option value="Kerjasama - Pendidikan">Kerjasama - Pendidikan</option>
|
||
<option value="Kerjasama - Pengampuan KIA">Kerjasama- Pengampuan KIA</option>
|
||
</select>
|
||
<div class="form-text text-muted">Isi form ini bila dokumen yang diunggah merupakan dokumen <strong>akreditasi</strong>.</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label fw-semibold">Kategori Lainnya</label>
|
||
<select class="form-select"
|
||
name="data[${colCount}][master_kategori_directory_id]"
|
||
id="select_kategori_${colCount}" style="width: 350px;">
|
||
<option value="">Pilih Kategori</option>
|
||
${katOptions}
|
||
</select>
|
||
</div>
|
||
|
||
<div class="col-md-12">
|
||
<label for="fileUpload_${colCount}" class="form-label fw-semibold">📂 Upload Dokumen (PDF)</label>
|
||
<div class="border rounded-3 p-3 bg-white shadow-sm">
|
||
<input class="form-control"
|
||
type="file"
|
||
id="fileUpload_${colCount}"
|
||
accept=".pdf"
|
||
name="data[${colCount}][file]">
|
||
<div class="mt-2 text-success fw-semibold d-none file-name" id="fileName_${colCount}"></div>
|
||
</div>
|
||
<div class="form-text text-muted">Format yang didukung: <b>PDF</b>.</div>
|
||
</div>
|
||
</div>`;
|
||
col.insertAdjacentHTML('beforeend', html);
|
||
selectOptionUnitKerjaV1(colCount);
|
||
initKategoriSelect2(colCount);
|
||
enableAkreFields(colCount);
|
||
setKategoriRequired(colCount, false);
|
||
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);
|
||
|
||
formCreate.addEventListener('submit', (e) => {
|
||
e.preventDefault();
|
||
const submitBtn = formCreate.querySelector('button[type="submit"]');
|
||
if (submitBtn) submitBtn.disabled = true;
|
||
if (submitBtn) submitBtn.textContent = 'menyimpan...';
|
||
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();
|
||
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');
|
||
}
|
||
let previewBox = document.getElementById('file-preview');
|
||
previewBox.innerHTML = `<div id="pdfWrap" style="height:500px; overflow:auto; background:#f7f7f7; padding:8px;">
|
||
<div id="pdfPages"></div>
|
||
</div>
|
||
`;
|
||
openPreview(idDirectory);
|
||
$("#previewModal").modal('show')
|
||
}
|
||
|
||
|
||
if(e.target.matches('#btn-view-full')){
|
||
window.open(`/full-preview/${idDirectory}`, '_blank');
|
||
}
|
||
})
|
||
function isPublic(permissionVal){
|
||
if(permissionVal === null || permissionVal === undefined) return false;
|
||
const val = String(permissionVal).toLowerCase();
|
||
return val === '1' || val === 'true' || val === 'iya' || val === 'yes';
|
||
}
|