done approval add mutu & turt -> review
This commit is contained in:
parent
353efd16b0
commit
f8c3816ca7
@ -1991,7 +1991,7 @@ class DashboardController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$paginated = $query->paginate($perPage);
|
$paginated = $query->paginate($perPage);
|
||||||
$data = $paginated->getCollection()->map(function($item) use($objectpegawaifk){
|
$data = $paginated->getCollection()->map(function($item) use($objectpegawaifk, $pegawaiId){
|
||||||
$dataSlice = array_values(array_filter(explode('/', $item->file)));
|
$dataSlice = array_values(array_filter(explode('/', $item->file)));
|
||||||
return [
|
return [
|
||||||
'file_directory_id' => $item->file_directory_id,
|
'file_directory_id' => $item->file_directory_id,
|
||||||
@ -3369,6 +3369,9 @@ class DashboardController extends Controller
|
|||||||
'no_dokumen',
|
'no_dokumen',
|
||||||
'file',
|
'file',
|
||||||
'entry_at',
|
'entry_at',
|
||||||
|
'tanggal_terbit',
|
||||||
|
'permission_file',
|
||||||
|
'pegawai_id_entry',
|
||||||
'id_unit_kerja',
|
'id_unit_kerja',
|
||||||
'is_akre',
|
'is_akre',
|
||||||
])
|
])
|
||||||
|
|||||||
@ -19,6 +19,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const selectedCountEl = document.getElementById('selectedCount');
|
const selectedCountEl = document.getElementById('selectedCount');
|
||||||
const bulkActionsEl = document.getElementById('pengajuanBulkActions');
|
const bulkActionsEl = document.getElementById('pengajuanBulkActions');
|
||||||
const deleteDataEl = document.getElementById('deleteData');
|
const deleteDataEl = document.getElementById('deleteData');
|
||||||
|
const pendingPersetujuanTabBadge = document.getElementById('pendingPersetujuanTabBadge');
|
||||||
|
const pendingPersetujuanNotice = document.getElementById('pendingPersetujuanNotice');
|
||||||
|
const pendingPersetujuanNoticeCount = document.getElementById('pendingPersetujuanNoticeCount');
|
||||||
const formCreate = document.getElementById('formFile');
|
const formCreate = document.getElementById('formFile');
|
||||||
const modalCreate = document.getElementById('modalCreateFile');
|
const modalCreate = document.getElementById('modalCreateFile');
|
||||||
let colCount = 1;
|
let colCount = 1;
|
||||||
@ -29,6 +32,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const selectedIds = new Set();
|
const selectedIds = new Set();
|
||||||
const isKomiteMutu = !!window.isKomiteMutu;
|
const isKomiteMutu = !!window.isKomiteMutu;
|
||||||
const isTurt = !!window.isTurt;
|
const isTurt = !!window.isTurt;
|
||||||
|
const isAtasan = !!window.isAtasan;
|
||||||
let editFromQueryId = new URLSearchParams(window.location.search).get('edit');
|
let editFromQueryId = new URLSearchParams(window.location.search).get('edit');
|
||||||
|
|
||||||
if (pageSizeSelect) {
|
if (pageSizeSelect) {
|
||||||
@ -493,6 +497,41 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
updateSelectionUI();
|
updateSelectionUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updatePendingPersetujuanIndicators(total){
|
||||||
|
const count = Number(total || 0);
|
||||||
|
if (pendingPersetujuanTabBadge) {
|
||||||
|
pendingPersetujuanTabBadge.textContent = String(count);
|
||||||
|
pendingPersetujuanTabBadge.classList.toggle('d-none', count <= 0);
|
||||||
|
}
|
||||||
|
if (pendingPersetujuanNotice && pendingPersetujuanNoticeCount) {
|
||||||
|
pendingPersetujuanNoticeCount.textContent = String(count);
|
||||||
|
pendingPersetujuanNotice.classList.toggle('d-none', count <= 0);
|
||||||
|
pendingPersetujuanNotice.classList.toggle('d-flex', count > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchPendingPersetujuanCount(){
|
||||||
|
if (!(isKomiteMutu || isTurt || isAtasan)) return;
|
||||||
|
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
page: 1,
|
||||||
|
per_page: 1,
|
||||||
|
keyword: '',
|
||||||
|
start_date: '',
|
||||||
|
end_date: '',
|
||||||
|
mode: 'persetujuan'
|
||||||
|
});
|
||||||
|
|
||||||
|
fetch(`/datatable/pengajuan-file?${params.toString()}`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
updatePendingPersetujuanIndicators(data?.pagination?.total || 0);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
updatePendingPersetujuanIndicators(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (tabsEl) {
|
if (tabsEl) {
|
||||||
tabsEl.addEventListener('click', (e) => {
|
tabsEl.addEventListener('click', (e) => {
|
||||||
const btn = e.target.closest('[data-mode]');
|
const btn = e.target.closest('[data-mode]');
|
||||||
@ -584,6 +623,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
activeState.lastPage = data?.pagination?.last_page || 1;
|
activeState.lastPage = data?.pagination?.last_page || 1;
|
||||||
activeState.total = data?.pagination?.total || 0;
|
activeState.total = data?.pagination?.total || 0;
|
||||||
renderTable();
|
renderTable();
|
||||||
|
fetchPendingPersetujuanCount();
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
|||||||
@ -56,6 +56,49 @@
|
|||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#lastUpdatedTable {
|
||||||
|
table-layout: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
#lastUpdatedTable td,
|
||||||
|
#lastUpdatedTable th {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-row-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 8px;
|
||||||
|
min-width: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-text-wrap {
|
||||||
|
min-width: 0;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-name-trigger {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
line-height: 1.3;
|
||||||
|
white-space: normal;
|
||||||
|
word-break: break-word;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-name-trigger strong {
|
||||||
|
display: block;
|
||||||
|
white-space: normal;
|
||||||
|
word-break: break-word;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-meta-path {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@section('body_main')
|
@section('body_main')
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -167,6 +210,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@include('dataUnit.modal.create')
|
@include('dataUnit.modal.create')
|
||||||
|
@include('dataUnit.modal.view')
|
||||||
|
|
||||||
@if(Auth::guard('admin')->check())
|
@if(Auth::guard('admin')->check())
|
||||||
<div class="modal fade" id="modalAkreInstrumen" tabindex="-1" aria-hidden="true">
|
<div class="modal fade" id="modalAkreInstrumen" tabindex="-1" aria-hidden="true">
|
||||||
@ -214,6 +258,7 @@
|
|||||||
let currentData = [];
|
let currentData = [];
|
||||||
let selectedIds = [];
|
let selectedIds = [];
|
||||||
let expandedFolders = new Set();
|
let expandedFolders = new Set();
|
||||||
|
let currentPreviewId = null;
|
||||||
let searchTimer;
|
let searchTimer;
|
||||||
const isAdminUser = @json(Auth::guard('admin')->check());
|
const isAdminUser = @json(Auth::guard('admin')->check());
|
||||||
const btn = document.getElementById('btnDownloadMultiple');
|
const btn = document.getElementById('btnDownloadMultiple');
|
||||||
@ -349,6 +394,16 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-sm btn-outline-secondary btn-preview-file"
|
||||||
|
data-id="${item.file_directory_id}"
|
||||||
|
data-name="${escapeAttribute(item.nama_dokumen || fileName)}"
|
||||||
|
data-no="${escapeAttribute(item.no_dokumen || '-')}"
|
||||||
|
data-date="${escapeAttribute(formatPreviewDate(item.tanggal_terbit || item.entry_at))}"
|
||||||
|
data-permission="${item.permission_file === true ? '1' : '0'}"
|
||||||
|
title="Preview">
|
||||||
|
<i class="ti ti-eye"></i>
|
||||||
|
</button>
|
||||||
<a href="/file-download/${item.file_directory_id}" target="_blank"
|
<a href="/file-download/${item.file_directory_id}" target="_blank"
|
||||||
class="btn btn-sm btn-outline-primary" download title="Download">
|
class="btn btn-sm btn-outline-primary" download title="Download">
|
||||||
<i class="ti ti-download"></i>
|
<i class="ti ti-download"></i>
|
||||||
@ -356,9 +411,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex flex-column">
|
<div class="file-row-content">
|
||||||
<strong>${item.nama_dokumen}</strong>
|
<i class="ti ti-file-type-pdf file-icon text-danger"></i>
|
||||||
<small class="text-muted" style="font-size: 10px;">Path: ${item.file}</small>
|
<div class="d-flex flex-column file-text-wrap">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-link btn-sm p-0 text-start text-decoration-none btn-preview-file file-name-trigger"
|
||||||
|
data-id="${item.file_directory_id}"
|
||||||
|
data-name="${escapeAttribute(item.nama_dokumen || fileName)}"
|
||||||
|
data-no="${escapeAttribute(item.no_dokumen || '-')}"
|
||||||
|
data-date="${escapeAttribute(formatPreviewDate(item.tanggal_terbit || item.entry_at))}"
|
||||||
|
data-permission="${item.permission_file === true ? '1' : '0'}">
|
||||||
|
<strong>${escapeHtml(item.nama_dokumen || fileName)}</strong>
|
||||||
|
</button>
|
||||||
|
<small class="text-muted file-meta-path" style="font-size: 10px;">Path: ${item.file}</small>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td><span class="badge bg-light text-primary border">${typeDok}</span></td>
|
<td><span class="badge bg-light text-primary border">${typeDok}</span></td>
|
||||||
@ -495,18 +561,40 @@
|
|||||||
value="${item.file_directory_id}" ${isChecked} onchange="handleRowCheck(this)">
|
value="${item.file_directory_id}" ${isChecked} onchange="handleRowCheck(this)">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-sm btn-outline-secondary btn-preview-file"
|
||||||
|
data-id="${item.file_directory_id}"
|
||||||
|
data-name="${escapeAttribute(item.nama_dokumen || fileName)}"
|
||||||
|
data-no="${escapeAttribute(item.no_dokumen || '-')}"
|
||||||
|
data-date="${escapeAttribute(formatPreviewDate(item.tanggal_terbit || item.entry_at))}"
|
||||||
|
data-permission="${item.permission_file === true ? '1' : '0'}"
|
||||||
|
title="Preview">
|
||||||
|
<i class="ti ti-eye"></i>
|
||||||
|
</button>
|
||||||
<a href="/file-download/${item.file_directory_id}" target="_blank"
|
<a href="/file-download/${item.file_directory_id}" target="_blank"
|
||||||
class="btn btn-sm btn-primary text-white border">
|
class="btn btn-sm btn-primary text-white border">
|
||||||
<i class="ti ti-download"></i>
|
<i class="ti ti-download"></i>
|
||||||
</a>
|
</a>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="indent-container">
|
<div class="indent-container">
|
||||||
${lines}
|
${lines}
|
||||||
<span style="width: 24px;"></span> <i class="ti ti-file-text file-icon me-2"></i>
|
<span style="width: 24px;"></span>
|
||||||
<div class="d-flex flex-column">
|
<div class="file-row-content">
|
||||||
<span class="text-dark fw-medium">${item.nama_dokumen}</span>
|
<i class="ti ti-file-text file-icon text-danger"></i>
|
||||||
<small class="text-muted" style="font-size: 10px;">${fileName}</small>
|
<div class="d-flex flex-column file-text-wrap">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-link btn-sm p-0 text-start text-decoration-none text-dark fw-medium btn-preview-file file-name-trigger"
|
||||||
|
data-id="${item.file_directory_id}"
|
||||||
|
data-name="${escapeAttribute(item.nama_dokumen || fileName)}"
|
||||||
|
data-no="${escapeAttribute(item.no_dokumen || '-')}"
|
||||||
|
data-date="${escapeAttribute(formatPreviewDate(item.tanggal_terbit || item.entry_at))}"
|
||||||
|
data-permission="${item.permission_file === true ? '1' : '0'}">
|
||||||
|
${escapeHtml(item.nama_dokumen || fileName)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -651,6 +739,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
document.addEventListener('click', function(e){
|
document.addEventListener('click', function(e){
|
||||||
|
const previewTrigger = e.target.closest('.btn-preview-file');
|
||||||
|
if (previewTrigger) {
|
||||||
|
openDocumentPreview({
|
||||||
|
id: previewTrigger.getAttribute('data-id'),
|
||||||
|
name: previewTrigger.getAttribute('data-name'),
|
||||||
|
noDokumen: previewTrigger.getAttribute('data-no'),
|
||||||
|
tanggalTerbit: previewTrigger.getAttribute('data-date'),
|
||||||
|
permissionFile: previewTrigger.getAttribute('data-permission')
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const toggle = e.target.closest('.folder-toggle');
|
const toggle = e.target.closest('.folder-toggle');
|
||||||
if (!toggle) return;
|
if (!toggle) return;
|
||||||
const folderPath = toggle.getAttribute('data-folder');
|
const folderPath = toggle.getAttribute('data-folder');
|
||||||
@ -671,11 +771,84 @@
|
|||||||
return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} `
|
return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} `
|
||||||
+ `${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
+ `${pad(d.getHours())}:${pad(d.getMinutes())}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatPreviewDate(value) {
|
||||||
|
if (!value) return '-';
|
||||||
|
const d = new Date(value);
|
||||||
|
if (isNaN(d)) return value;
|
||||||
|
const pad = n => String(n).padStart(2, '0');
|
||||||
|
return `${pad(d.getDate())}/${pad(d.getMonth()+1)}/${d.getFullYear()}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPublic(permissionVal){
|
||||||
|
return permissionVal === true || permissionVal === 'true' || permissionVal === 1 || permissionVal === '1';
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeHtml(value) {
|
||||||
|
return String(value ?? '')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, ''');
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeAttribute(value) {
|
||||||
|
return escapeHtml(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openDocumentPreview({ id, name, noDokumen, tanggalTerbit, permissionFile }) {
|
||||||
|
currentPreviewId = id;
|
||||||
|
|
||||||
|
const titleEl = document.getElementById('confirm_preview_file');
|
||||||
|
if (titleEl) titleEl.textContent = name || '-';
|
||||||
|
|
||||||
|
const noEl = document.getElementById('confirm-upload-dokumen');
|
||||||
|
if (noEl) noEl.textContent = noDokumen || '-';
|
||||||
|
|
||||||
|
const tglEl = document.getElementById('confirm-time-dokumen');
|
||||||
|
if (tglEl) tglEl.textContent = tanggalTerbit || '-';
|
||||||
|
|
||||||
|
const permEl = document.getElementById('confirm-permission');
|
||||||
|
if (permEl) {
|
||||||
|
const publicDoc = isPublic(permissionFile);
|
||||||
|
permEl.textContent = publicDoc ? 'Umum' : 'Internal Unit';
|
||||||
|
permEl.className = 'badge ' + (publicDoc ? 'bg-success' : 'bg-secondary');
|
||||||
|
}
|
||||||
|
|
||||||
|
const downloadBtn = document.getElementById('btn-download');
|
||||||
|
if (downloadBtn) {
|
||||||
|
downloadBtn.setAttribute('href', `/file-download/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteWrapper = document.getElementById('deleteData');
|
||||||
|
if (deleteWrapper) {
|
||||||
|
deleteWrapper.classList.add('d-none');
|
||||||
|
}
|
||||||
|
|
||||||
|
const previewBox = document.getElementById('file-preview');
|
||||||
|
if (previewBox) {
|
||||||
|
previewBox.innerHTML = `<div id="pdfWrap" style="height:500px; overflow:auto; background:#f7f7f7; padding:8px;">
|
||||||
|
<div id="pdfPages"></div>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
openPreview(id);
|
||||||
|
$("#previewModal").modal('show');
|
||||||
|
}
|
||||||
|
|
||||||
const katDok = @json($katDok);
|
const katDok = @json($katDok);
|
||||||
const formCreate = document.getElementById('formFile');
|
const formCreate = document.getElementById('formFile');
|
||||||
const modalCreate = document.getElementById('modalCreateFile');
|
const modalCreate = document.getElementById('modalCreateFile');
|
||||||
let colCount = 1;
|
let colCount = 1;
|
||||||
|
|
||||||
|
document.addEventListener('click', function(e){
|
||||||
|
if(e.target.closest('#btn-view-full')){
|
||||||
|
if (!currentPreviewId) return;
|
||||||
|
window.open(`/full-preview/${currentPreviewId}`, '_blank');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
document.addEventListener('change', function(e){
|
document.addEventListener('change', function(e){
|
||||||
if(!e.target.classList.contains('toggle-expired')) return;
|
if(!e.target.classList.contains('toggle-expired')) return;
|
||||||
const targetId = e.target.getAttribute('data-target');
|
const targetId = e.target.getAttribute('data-target');
|
||||||
|
|||||||
@ -408,6 +408,30 @@
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function escapeHtml(value){
|
||||||
|
return String(value ?? '')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, ''');
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderDeleteRecommendation(item){
|
||||||
|
const recommendation = item?.delete_recommendation;
|
||||||
|
if (!recommendation?.visible || !recommendation?.note) return '';
|
||||||
|
|
||||||
|
const actorRole = recommendation.actor_role || 'TURT';
|
||||||
|
const actorName = recommendation.actor_name ? ` (${escapeHtml(recommendation.actor_name)})` : '';
|
||||||
|
const note = escapeHtml(recommendation.note);
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="mt-1 px-2 py-1 rounded border border-warning-subtle bg-warning-subtle text-warning-emphasis" style="font-size:12px; line-height:1.35;">
|
||||||
|
Dokumen ini direkomendasikan dihapus oleh ${escapeHtml(actorRole)}${actorName}. Catatan: ${note}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
function buildRow(item){
|
function buildRow(item){
|
||||||
const parts = (item.file || '').split('/');
|
const parts = (item.file || '').split('/');
|
||||||
const fileName = parts.pop() || '-';
|
const fileName = parts.pop() || '-';
|
||||||
@ -520,6 +544,7 @@
|
|||||||
${expiryBadge}
|
${expiryBadge}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
${renderDeleteRecommendation(item)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
|||||||
@ -649,6 +649,30 @@
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function escapeHtml(value){
|
||||||
|
return String(value ?? '')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, ''');
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderDeleteRecommendation(item){
|
||||||
|
const recommendation = item?.delete_recommendation;
|
||||||
|
if (!recommendation?.visible || !recommendation?.note) return '';
|
||||||
|
|
||||||
|
const actorRole = recommendation.actor_role || 'TURT';
|
||||||
|
const actorName = recommendation.actor_name ? ` (${escapeHtml(recommendation.actor_name)})` : '';
|
||||||
|
const note = escapeHtml(recommendation.note);
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="mt-1 px-2 py-1 rounded border border-warning-subtle bg-warning-subtle text-warning-emphasis" style="font-size:12px; line-height:1.35;">
|
||||||
|
Dokumen ini direkomendasikan dihapus oleh ${escapeHtml(actorRole)}${actorName}. Catatan: ${note}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
function buildRow(item){
|
function buildRow(item){
|
||||||
const parts = (item.file || '').split('/');
|
const parts = (item.file || '').split('/');
|
||||||
const fileName = parts.pop() || '-';
|
const fileName = parts.pop() || '-';
|
||||||
@ -748,6 +772,7 @@
|
|||||||
</a>
|
</a>
|
||||||
${akreBadge}${expiryBadge}
|
${akreBadge}${expiryBadge}
|
||||||
</div>
|
</div>
|
||||||
|
${renderDeleteRecommendation(item)}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
${item.nama_kategori || '-'}
|
${item.nama_kategori || '-'}
|
||||||
|
|||||||
@ -66,7 +66,7 @@
|
|||||||
})->exists();
|
})->exists();
|
||||||
$isRoleApprover = in_array(51, $userUnitIds, true) || in_array(22, $userUnitIds, true);
|
$isRoleApprover = in_array(51, $userUnitIds, true) || in_array(22, $userUnitIds, true);
|
||||||
@endphp
|
@endphp
|
||||||
@if($isAtasan || $isRoleApprover)
|
@if($isAtasan)
|
||||||
@if(!Auth::guard('admin')->check())
|
@if(!Auth::guard('admin')->check())
|
||||||
<li class="sidebar-item">
|
<li class="sidebar-item">
|
||||||
<a class="sidebar-link d-flex align-items-center justify-content-between"
|
<a class="sidebar-link d-flex align-items-center justify-content-between"
|
||||||
@ -91,6 +91,10 @@
|
|||||||
<i class="ti ti-clock"></i>
|
<i class="ti ti-clock"></i>
|
||||||
<span class="hide-menu">Pengajuan</span>
|
<span class="hide-menu">Pengajuan</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if($isRoleApprover)
|
||||||
|
<span class="badge bg-danger rounded-pill d-none" id="pengajuanPendingCountBadge">0</span>
|
||||||
|
@endif
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@endif
|
@endif
|
||||||
@ -204,10 +208,11 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const badge = document.getElementById('pendingCountBadge');
|
const pendingBadge = document.getElementById('pendingCountBadge');
|
||||||
|
const pengajuanBadge = document.getElementById('pengajuanPendingCountBadge');
|
||||||
|
|
||||||
async function countData() {
|
async function countData() {
|
||||||
if (!badge) return;
|
if (!pendingBadge && !pengajuanBadge) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/data/count-pending', {
|
const res = await fetch('/data/count-pending', {
|
||||||
@ -219,11 +224,19 @@
|
|||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
const count = Number(data?.count ?? 0);
|
const count = Number(data?.count ?? 0);
|
||||||
|
|
||||||
badge.textContent = count;
|
if (pendingBadge) {
|
||||||
badge.classList.toggle('d-none', count <= 0);
|
pendingBadge.textContent = count;
|
||||||
|
pendingBadge.classList.toggle('d-none', count <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pengajuanBadge) {
|
||||||
|
pengajuanBadge.textContent = count;
|
||||||
|
pengajuanBadge.classList.toggle('d-none', count <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
badge.classList.add('d-none');
|
if (pendingBadge) pendingBadge.classList.add('d-none');
|
||||||
|
if (pengajuanBadge) pengajuanBadge.classList.add('d-none');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -48,13 +48,24 @@
|
|||||||
</li>
|
</li>
|
||||||
@if($isKomiteMutu || $isTurt || $isAtasan)
|
@if($isKomiteMutu || $isTurt || $isAtasan)
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<button class="nav-link" type="button" data-mode="persetujuan">Data Persetujuan</button>
|
<button class="nav-link d-flex align-items-center gap-2" type="button" data-mode="persetujuan">
|
||||||
|
<span>Data Persetujuan</span>
|
||||||
|
<span class="badge bg-danger rounded-pill d-none" id="pendingPersetujuanTabBadge">0</span>
|
||||||
|
</button>
|
||||||
</li>
|
</li>
|
||||||
@endif
|
@endif
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<button class="nav-link" type="button" data-mode="history">Log History</button>
|
<button class="nav-link" type="button" data-mode="history">Log History</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@if(($isKomiteMutu || $isTurt) && !$isAtasan)
|
||||||
|
<div class="alert alert-warning d-none align-items-center justify-content-between gap-3 py-2" id="pendingPersetujuanNotice" role="alert">
|
||||||
|
<div>
|
||||||
|
Ada <strong id="pendingPersetujuanNoticeCount">0</strong> data yang menunggu persetujuan Anda.
|
||||||
|
</div>
|
||||||
|
<a href="{{ url('/pending-file') }}" class="btn btn-sm btn-outline-warning">Lihat Persetujuan</a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
<div class="d-flex flex-column flex-md-row align-items-md-center gap-2 mb-3 flex-wrap">
|
<div class="d-flex flex-column flex-md-row align-items-md-center gap-2 mb-3 flex-wrap">
|
||||||
<div class="input-group input-group-sm flex-grow-1" style="max-width:320px;">
|
<div class="input-group input-group-sm flex-grow-1" style="max-width:320px;">
|
||||||
<span class="input-group-text bg-white border-end-0">
|
<span class="input-group-text bg-white border-end-0">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user