2026-03-03 14:04:31 +07:00

1104 lines
46 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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){
console.log(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.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 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 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 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 && tglExpiredEl) {
const hasExpired = !!item.tgl_expired;
hasExpiredEl.checked = hasExpired;
syncEditExpiredField();
}
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');
}
}
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();
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);
}
let akreData = [];
let akreLoaded = false;
function loadAkreData(){
if(akreLoaded) return Promise.resolve(akreData);
return fetch('/json/akreditasi.json')
.then(res => res.json())
.then(data => {
akreData = Array.isArray(data) ? data : [];
akreLoaded = true;
return akreData;
})
.catch(() => {
akreData = [];
akreLoaded = true;
return akreData;
});
}
function fillAkreType(selectEl){
if(!selectEl) return;
selectEl.innerHTML = '<option value="" disabled selected>Pilih Type</option>';
akreData.forEach(item => {
const opt = document.createElement('option');
opt.value = item.name;
opt.textContent = item.name;
selectEl.appendChild(opt);
});
}
function fillAkreSegment(selectEl, typeName){
if(!selectEl) return;
selectEl.innerHTML = '<option value="" disabled selected>Pilih Segmen</option>';
const typeItem = akreData.find(item => item.name === typeName);
if(typeItem && Array.isArray(typeItem.segment) && typeItem.segment.length){
typeItem.segment.forEach(seg => {
const opt = document.createElement('option');
opt.value = seg.name;
opt.textContent = seg.name;
selectEl.appendChild(opt);
});
selectEl.disabled = false;
selectEl.required = true;
}else{
selectEl.disabled = true;
selectEl.required = false;
}
}
function fillAkreItem(selectEl, typeName, segmentName){
if(!selectEl) return;
selectEl.innerHTML = '<option value="" disabled selected>Pilih Elemen</option>';
const typeItem = akreData.find(item => item.name === typeName);
const segmentItem = typeItem?.segment?.find(seg => seg.name === segmentName);
if(segmentItem && Array.isArray(segmentItem.turunan) && segmentItem.turunan.length){
segmentItem.turunan.forEach(child => {
const opt = document.createElement('option');
opt.value = child.name;
opt.textContent = child.name;
selectEl.appendChild(opt);
});
selectEl.disabled = false;
selectEl.required = true;
}else{
selectEl.disabled = true;
selectEl.required = false;
}
}
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 typeWrap = document.getElementById(`akre_type_wrap_${index}`);
const segmentWrap = document.getElementById(`akre_segment_wrap_${index}`);
const itemWrap = document.getElementById(`akre_item_wrap_${index}`);
const typeSelect = document.getElementById(`akre_type_${index}`);
const segmentSelect = document.getElementById(`akre_segment_${index}`);
const itemSelect = document.getElementById(`akre_item_${index}`);
if(typeWrap) typeWrap.classList.add('d-none');
if(segmentWrap) segmentWrap.classList.add('d-none');
if(itemWrap) itemWrap.classList.add('d-none');
if(typeSelect){
typeSelect.value = '';
typeSelect.disabled = true;
typeSelect.required = false;
}
if(segmentSelect){
segmentSelect.value = '';
segmentSelect.disabled = true;
segmentSelect.required = false;
}
if(itemSelect){
itemSelect.value = '';
itemSelect.disabled = true;
itemSelect.required = false;
}
setKategoriRequired(index, true);
}
function enableAkreFields(index){
const typeWrap = document.getElementById(`akre_type_wrap_${index}`);
const segmentWrap = document.getElementById(`akre_segment_wrap_${index}`);
const itemWrap = document.getElementById(`akre_item_wrap_${index}`);
const typeSelect = document.getElementById(`akre_type_${index}`);
const segmentSelect = document.getElementById(`akre_segment_${index}`);
const itemSelect = document.getElementById(`akre_item_${index}`);
if(typeWrap) typeWrap.classList.remove('d-none');
if(segmentWrap) segmentWrap.classList.remove('d-none');
if(itemWrap) itemWrap.classList.remove('d-none');
if(typeSelect){
typeSelect.disabled = false;
typeSelect.required = true;
}
if(segmentSelect){
segmentSelect.disabled = true;
segmentSelect.required = true;
}
if(itemSelect){
itemSelect.disabled = true;
itemSelect.required = true;
}
setKategoriRequired(index, false);
loadAkreData().then(() => {
fillAkreType(typeSelect);
if(typeSelect?.value){
fillAkreSegment(segmentSelect, typeSelect.value);
}
if(typeSelect?.value && segmentSelect?.value){
fillAkreItem(itemSelect, typeSelect.value, segmentSelect.value);
}
});
}
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-4">
<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-4">
<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">Kategori Dokumen <span class="text-danger">*</span></label>
<select class="form-select"
name="data[${colCount}][master_kategori_directory_id]"
id="select_kategori_${colCount}"
required>
<option value="" disabled selected>Pilih Kategori</option>
${katOptions}
</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-2">
<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-5">
<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">Apakah Dokumen Akreditasi? <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_akre]"
id="akre_yes_${colCount}"
value="1"
required>
<label class="form-check-label" for="akre_yes_${colCount}">Iya</label>
</div>
<div class="form-check mt-1">
<input class="form-check-input"
type="radio"
name="data[${colCount}][is_akre]"
id="akre_no_${colCount}"
value="2"
required>
<label class="form-check-label" for="akre_no_${colCount}">Tidak</label>
</div>
</div>
</div>
<div class="col-md-4 d-none" id="akre_type_wrap_${colCount}">
<label class="form-label fw-semibold">Type Akreditasi <span class="text-danger">*</span></label>
<select class="form-select akre-type"
name="data[${colCount}][akre_type]"
id="akre_type_${colCount}"
disabled>
<option value="" disabled selected>Pilih Type</option>
</select>
</div>
<div class="col-md-4 d-none" id="akre_segment_wrap_${colCount}">
<label class="form-label fw-semibold">Segmen <span class="text-danger">*</span></label>
<select class="form-select akre-segment"
name="data[${colCount}][akre_segment]"
id="akre_segment_${colCount}"
disabled>
<option value="" disabled selected>Pilih Segmen</option>
</select>
</div>
<div class="col-md-4 d-none" id="akre_item_wrap_${colCount}">
<label class="form-label fw-semibold">Elemen Penilaian <span class="text-danger">*</span></label>
<select class="form-select akre-item"
name="data[${colCount}][akre_item]"
id="akre_item_${colCount}"
disabled>
<option value="" disabled selected>Pilih Elemen</option>
</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);
setKategoriRequired(colCount, true);
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);
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-type')){
const id = e.target.id || '';
const idx = id.split('_').pop();
const segmentSelect = document.getElementById(`akre_segment_${idx}`);
const itemSelect = document.getElementById(`akre_item_${idx}`);
if(segmentSelect) fillAkreSegment(segmentSelect, e.target.value);
if(itemSelect){
itemSelect.innerHTML = '<option value="" disabled selected>Pilih Elemen</option>';
itemSelect.disabled = true;
}
return;
}
if(e.target.classList.contains('akre-segment')){
const id = e.target.id || '';
const idx = id.split('_').pop();
const typeSelect = document.getElementById(`akre_type_${idx}`);
const itemSelect = document.getElementById(`akre_item_${idx}`);
fillAkreItem(itemSelect, typeSelect?.value || '', e.target.value);
return;
}
if(e.target.matches('input[type="radio"][name$="[is_akre]"]')){
const name = e.target.getAttribute('name') || '';
const match = name.match(/data\[(\d+)\]\[is_akre\]/);
const idx = match ? match[1] : '0';
if(e.target.value === '1'){
enableAkreFields(idx);
}else{
resetAkreFields(idx);
}
}
});
});
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';
}