502 lines
21 KiB
JavaScript
502 lines
21 KiB
JavaScript
document.addEventListener('DOMContentLoaded', () => {
|
||
const tableState = { data: [], page: 1, pageSize: 10, search: '', lastPage: 1, total: 0, startDate: '', endDate: '' };
|
||
const tbody = document.getElementById('tablePengajuanFile');
|
||
const paginationEl = document.getElementById('paginationControls');
|
||
const summaryEl = document.getElementById('tableSummary');
|
||
const pageSizeSelect = document.getElementById('tablePageSize');
|
||
const startDateInput = document.getElementById('startDate');
|
||
const endDateInput = document.getElementById('endDate');
|
||
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;
|
||
pageSizeSelect.addEventListener('change', (e) => {
|
||
const val = parseInt(e.target.value);
|
||
if (!isNaN(val) && val > 0) {
|
||
tableState.pageSize = val;
|
||
tableState.page = 1;
|
||
fetchData();
|
||
}
|
||
});
|
||
}
|
||
|
||
window.applyDateFilter = function(){
|
||
tableState.startDate = startDateInput.value || '';
|
||
tableState.endDate = endDateInput.value || '';
|
||
tableState.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 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-file-pdf"></i>
|
||
</button>
|
||
<button class="btn btn-sm btn-info" onclick="infoReject('${item.file_directory_id}')">
|
||
<i class="fa-solid fa-circle-info"></i>
|
||
</button>
|
||
<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 === "rejected" ? 'btn-danger' :
|
||
item?.status_action === "revised" ? 'btn-info' :
|
||
'btn-warning'}">
|
||
${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>
|
||
<td>${item.folder || '-'}</td>
|
||
<td>${item.part || '-'}</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){
|
||
if (!paginationEl) return;
|
||
if (totalPages <= 1) {
|
||
paginationEl.innerHTML = '';
|
||
return;
|
||
}
|
||
const maxButtons = 5;
|
||
let start = Math.max(1, tableState.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" ${tableState.page === 1 ? 'disabled' : ''}>‹</button>`;
|
||
for (let i = start; i <= end; i++) {
|
||
buttons += `<button class="btn btn-sm ${i === tableState.page ? 'btn-primary' : 'btn-outline-secondary'}" data-page="${i}">${i}</button>`;
|
||
}
|
||
buttons += `<button class="btn btn-outline-secondary btn-sm" data-page="next" ${tableState.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 ${tableState.page} dari ${totalPages}</span>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
if (paginationEl) {
|
||
paginationEl.addEventListener('click', (e) => {
|
||
const page = e.target.getAttribute('data-page');
|
||
if (!page) return;
|
||
if (page === 'prev' && tableState.page > 1) tableState.page--;
|
||
else if (page === 'next') {
|
||
if (tableState.page < tableState.lastPage) tableState.page++;
|
||
} else {
|
||
tableState.page = parseInt(page);
|
||
}
|
||
fetchData();
|
||
});
|
||
}
|
||
|
||
function renderTable(){
|
||
const pageData = tableState.data || [];
|
||
if (pageData.length === 0) {
|
||
tbody.innerHTML = `
|
||
<tr>
|
||
<td colspan="10" class="text-center text-muted py-4">
|
||
Tidak ada data
|
||
</td>
|
||
</tr>
|
||
`;
|
||
} else {
|
||
tbody.innerHTML = pageData.map(buildRow).join('');
|
||
}
|
||
|
||
const from = tableState.total === 0 ? 0 : ((tableState.page - 1) * tableState.pageSize) + 1;
|
||
const to = Math.min(((tableState.page - 1) * tableState.pageSize) + pageData.length, tableState.total);
|
||
if (summaryEl) {
|
||
summaryEl.textContent = tableState.total ? `Menampilkan ${from} - ${to} dari ${tableState.total} data` : 'Tidak ada data';
|
||
}
|
||
|
||
renderPagination(tableState.lastPage || 1);
|
||
}
|
||
|
||
let searchDebounce;
|
||
window.debouncedTableSearch = function(value){
|
||
clearTimeout(searchDebounce);
|
||
searchDebounce = setTimeout(() => {
|
||
tableState.search = value.trim();
|
||
tableState.page = 1;
|
||
fetchData();
|
||
}, 250);
|
||
}
|
||
|
||
window.refreshLog = function(){
|
||
tableState.search = '';
|
||
tableState.startDate = '';
|
||
tableState.endDate = '';
|
||
document.getElementById('tableSearch').value = '';
|
||
startDateInput.value = '';
|
||
endDateInput.value = '';
|
||
tableState.page = 1;
|
||
fetchData();
|
||
}
|
||
|
||
function fetchData(){
|
||
if (summaryEl) summaryEl.textContent = 'Memuat data...';
|
||
const params = new URLSearchParams({
|
||
page: tableState.page,
|
||
per_page: tableState.pageSize,
|
||
keyword: tableState.search || '',
|
||
start_date: tableState.startDate || '',
|
||
end_date: tableState.endDate || ''
|
||
});
|
||
fetch(`/datatable/pengajuan-file?${params.toString()}`)
|
||
.then(res => res.json())
|
||
.then(data => {
|
||
tableState.data = data?.data || [];
|
||
tableState.lastPage = data?.pagination?.last_page || 1;
|
||
tableState.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 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: `${item.id}/${item.name}`,
|
||
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;
|
||
const unitId = String(val).split('/')[0];
|
||
loadEditSubUnit(unitId, null, null);
|
||
});
|
||
}
|
||
|
||
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 = `${unit.id}/${unit.name}`;
|
||
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}/${selectedSubName}"]`).length === 0) {
|
||
editSubUnitSelect.append(new Option(selectedSubName, `${selectedSubId}/${selectedSubName}`, true, true));
|
||
}
|
||
editSubUnitSelect.trigger('change');
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
window.editFileReject = function(id){
|
||
const item = getItemById(id);
|
||
if (!item) {
|
||
Swal.fire({ icon: 'error', title: 'Gagal', text: 'Data tidak ditemukan.' });
|
||
return;
|
||
}
|
||
const idEl = document.getElementById('edit_file_directory_id');
|
||
const noEl = document.getElementById('edit_no_dokumen');
|
||
const namaEl = document.getElementById('edit_nama_dokumen');
|
||
const tglEl = document.getElementById('edit_tanggal_terbit');
|
||
const tglExpiredEl = document.getElementById('edit_tgl_expired');
|
||
const hasExpiredEl = document.getElementById('edit_has_expired');
|
||
const expiredFieldEl = document.getElementById('edit_expired_field');
|
||
const currentFileEl = document.getElementById('edit_current_file');
|
||
const permYes = document.getElementById('edit_perm_yes');
|
||
const permNo = document.getElementById('edit_perm_no');
|
||
const katEl = document.getElementById('edit_kategori');
|
||
|
||
if (idEl) idEl.value = item.file_directory_id || '';
|
||
if (noEl) noEl.value = item.no_dokumen || '';
|
||
if (namaEl) namaEl.value = item.nama_dokumen || '';
|
||
if (tglEl) tglEl.value = item.tanggal_terbit || '';
|
||
if (tglExpiredEl) tglExpiredEl.value = item.tgl_expired || '';
|
||
if (permYes && permNo) {
|
||
const isPublic = item.permission_file === true || item.permission_file === 1 || item.permission_file === '1';
|
||
permYes.checked = isPublic;
|
||
permNo.checked = !isPublic;
|
||
}
|
||
if (hasExpiredEl && expiredFieldEl) {
|
||
const hasExpired = !!item.tgl_expired;
|
||
hasExpiredEl.checked = hasExpired;
|
||
expiredFieldEl.classList.toggle('d-none', !hasExpired);
|
||
}
|
||
if (currentFileEl) {
|
||
const displayName = item.fileName || (item.file ? String(item.file).split('/').pop() : '');
|
||
currentFileEl.textContent = displayName ? `File saat ini: ${displayName}` : '';
|
||
}
|
||
|
||
const parts = (item.file || '').split('/');
|
||
const unitName = parts[0] || '';
|
||
const subName = parts[1] || '';
|
||
const kategoriName = parts[2] || '';
|
||
|
||
if (editUnitSelect.length && item.id_unit_kerja) {
|
||
const unitVal = `${item.id_unit_kerja}/${unitName}`;
|
||
editUnitSelect.append(new Option(unitName || 'Unit', unitVal, true, true)).trigger('change');
|
||
const unitId = String(item.id_unit_kerja);
|
||
loadEditSubUnit(unitId, item.id_sub_unit_kerja, subName);
|
||
}
|
||
|
||
if (katEl && item.master_kategori_directory_id) {
|
||
const katVal = `${item.master_kategori_directory_id}/${kategoriName}`;
|
||
if (katEl.querySelector(`option[value="${katVal}"]`)) {
|
||
katEl.value = katVal;
|
||
} else {
|
||
katEl.append(new Option(kategoriName || 'Kategori', katVal, true, true));
|
||
katEl.value = katVal;
|
||
}
|
||
}
|
||
|
||
const modalEl = document.getElementById('modalEditPengajuanFile');
|
||
if (modalEl) {
|
||
$("#modalEditPengajuanFile").modal('show');
|
||
}
|
||
}
|
||
|
||
const editHasExpired = document.getElementById('edit_has_expired');
|
||
if (editHasExpired) {
|
||
editHasExpired.addEventListener('change', () => {
|
||
const targetId = editHasExpired.getAttribute('data-target');
|
||
const container = targetId ? document.getElementById(targetId) : null;
|
||
if (container) {
|
||
container.classList.toggle('d-none', !editHasExpired.checked);
|
||
if (!editHasExpired.checked) {
|
||
const input = container.querySelector('input[type="date"]');
|
||
if (input) input.value = '';
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
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();
|
||
fetchData();
|
||
});
|
||
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';
|
||
}
|