diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index 81da6d0..9110fbb 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -453,14 +453,45 @@ class DashboardController extends Controller public function downloadDataMultiple(){ try { - $rows = request('ids', []); // [[unit_id=>u, sub_unit_id=>s], ...] + $rows = request('ids', []); // [[file_directory_id=>x] | [sub_unit_id=>y] | "file_directory_id", ...] if (empty($rows)) { return response()->json(['message' => 'Tidak ada data'], 422); } $paths = []; foreach ($rows as $r) { - if(!empty($r['sub_unit_id'])){ - $files = FileDirectory::where('id_sub_unit_kerja', $r['sub_unit_id'])->where('statusenabled', true)->where('status_action', 'approved')->pluck('file'); + if (is_string($r) || is_numeric($r)) { + $file = FileDirectory::where('file_directory_id', $r) + ->where('statusenabled', true) + ->where('status_action', 'approved') + ->value('file'); + if ($file) { + $paths[] = $file; + } + continue; + } + + if (!empty($r['file_directory_id'] ?? null)) { + $file = FileDirectory::where('file_directory_id', $r['file_directory_id']) + ->where('statusenabled', true) + ->where('status_action', 'approved') + ->value('file'); + if ($file) { + $paths[] = $file; + } + continue; + } + + if (!empty($r['file'] ?? null)) { + $paths[] = $r['file']; + continue; + } + + $subUnitId = $r['sub_unit_id'] ?? $r['id_sub_unit_kerja'] ?? null; + if (!empty($subUnitId)) { + $files = FileDirectory::where('id_sub_unit_kerja', $subUnitId) + ->where('statusenabled', true) + ->where('status_action', 'approved') + ->pluck('file'); $paths = array_merge($paths, $files->toArray()); } @@ -632,13 +663,13 @@ class DashboardController extends Controller $status = null; - if(auth()->user()->masterPersetujuan){ + // if(auth()->user()->masterPersetujuan){ // $unitPegawaiIds = auth()->user()->masterPersetujuan->details->pluck('unit_pegawai_id')->unique()->toArray(); // $status = in_array($id_unit_kerja, $unitPegawaiIds) // ? 'approved' // : null; $status = $isAtasan ? 'approved' : null; - } + // } $payload = [ 'id_unit_kerja' => $id_unit_kerja, @@ -653,7 +684,6 @@ class DashboardController extends Controller 'action_by' => $status && $status === "approved" ? auth()->user()->objectpegawaifk : null, 'action_at' => $status && $status === "approved" ? now() : null ]; - $imageName = $uploadedFile->getClientOriginalName(); $path = "{$nama_unit_kerja}/{$nama_sub_unit_kerja}/{$nama_kategori}"; $uploadedFile->storeAs($path, $imageName, 'file_directory'); @@ -669,8 +699,8 @@ class DashboardController extends Controller 'text_notifikasi' => "Dokumen {$docNumber} memerlukan persetujuan. Diunggah oleh {$uploaderName}.", 'url' => '/pending-file', 'is_read' => false, - // 'pegawai_id' => $mapping?->objectatasanlangsungfk, - 'pegawai_id' => 23521, + 'pegawai_id' => $mapping?->objectatasanlangsungfk, + // 'pegawai_id' => 23521, ]; Notifkasi::create($payloadNotification); @@ -974,15 +1004,17 @@ class DashboardController extends Controller // ->orWhereNull('status_action'); // })->whereIn('id_unit_kerja', $authUnit)->orderBy('entry_at','desc'); $mapping = MappingUnitKerjaPegawai::where('statusenabled', true) - // ->where('objectatasanlangsungfk', auth()->user()->dataUser->id) - ->where('objectatasanlangsungfk', 22924) + ->where('objectatasanlangsungfk', auth()->user()->dataUser->id) + // ->where('objectatasanlangsungfk', 22924) ->get(['objectpegawaifk']); $objectpegawaifk = $mapping->pluck('objectpegawaifk') ->values() ->all(); $keyword = request('keyword'); $query = FileDirectory::where('statusenabled', true) - ->where('status_action', '!=', 'approved') + ->where(function($qsa){ + $qsa->where('status_action', '!=', 'approved')->orWhereNull('status_action'); + }) ->whereIn('pegawai_id_entry', $objectpegawaifk) ->when($keyword, function ($q) use ($keyword) { $q->where(function ($sub) use ($keyword) { @@ -1412,8 +1444,8 @@ class DashboardController extends Controller 'text_notifikasi' => "Dokumen {$docNumber} telah direvisi dan memerlukan persetujuan ulang. ". "Direvisi oleh {$uploaderName}.", 'url' => '/pending-file', 'is_read' => false, - // 'pegawai_id' => $mapping?->objectatasanlangsungfk, - 'pegawai_id' => 23521, + 'pegawai_id' => $mapping?->objectatasanlangsungfk, + // 'pegawai_id' => 23521, ]; Notifkasi::create($payloadNotification); diff --git a/public/js/pendingFile/index.js b/public/js/pendingFile/index.js index f80d384..5c62ec5 100644 --- a/public/js/pendingFile/index.js +++ b/public/js/pendingFile/index.js @@ -45,6 +45,13 @@ document.addEventListener('DOMContentLoaded', () => { if (status === 'revised') return 'Revised'; return 'Pending'; } + function aksesBadge(akses){ + if (akses){ + return 'Umum'; + } else{ + return 'Internal Unit'; + } + } function safeText(val){ return val ? String(val) : '-'; @@ -67,6 +74,7 @@ document.addEventListener('DOMContentLoaded', () => { ${item?.status_action !== "rejected" ? aksi : ''} ${safeText(item.no_dokumen)} ${statusBadge(item?.status_action)} + ${aksesBadge(item?.permission_file)} { if (pageData.length === 0) { tbody.innerHTML = ` - + Tidak ada data diff --git a/resources/views/dataUmum/index.blade.php b/resources/views/dataUmum/index.blade.php index 26d4eb8..d9de0d2 100644 --- a/resources/views/dataUmum/index.blade.php +++ b/resources/views/dataUmum/index.blade.php @@ -120,9 +120,39 @@
-
-

Data Unit

- +
+

Data Umum

+
+ +
+ + + + 0 dipilih + +
+ + +
@@ -150,6 +180,9 @@ + @@ -185,6 +218,10 @@ const paginationEl = document.getElementById('paginationControls'); const summaryEl = document.getElementById('tableSummary'); const pageSizeSelect = document.getElementById('tablePageSize'); + const downloadBtn = document.getElementById('btnDownloadMultiple'); + const selectedCountEl = document.getElementById('selectedCount'); + const checkAllEl = document.getElementById('checkAllRows'); + const selectedIds = new Set(); if(pageSizeSelect){ const initialSize = parseInt(pageSizeSelect.value); @@ -232,8 +269,15 @@ statusLabel = 'Internal Unit'; statusClass = 'bg-secondary'; } + const checked = selectedIds.has(String(item.file_directory_id)) ? 'checked' : ''; return ` + - @@ -384,6 +428,8 @@ } renderPagination(tableState.lastPage || 1); + syncCheckAllState(); + updateSelectedCount(); } function debouncedTableSearch(value){ @@ -429,6 +475,99 @@ } fetchData() + function updateSelectedCount(){ + if(!selectedCountEl) return; + selectedCountEl.textContent = `${selectedIds.size} dipilih`; + if(downloadBtn){ + downloadBtn.disabled = selectedIds.size === 0; + } + } + + function syncCheckAllState(){ + if(!checkAllEl) return; + const pageIds = (tableState.data || []).map(item => String(item.file_directory_id)); + if(pageIds.length === 0){ + checkAllEl.checked = false; + checkAllEl.indeterminate = false; + return; + } + const selectedOnPage = pageIds.filter(id => selectedIds.has(id)).length; + checkAllEl.checked = selectedOnPage === pageIds.length; + checkAllEl.indeterminate = selectedOnPage > 0 && selectedOnPage < pageIds.length; + } + + if(checkAllEl){ + checkAllEl.addEventListener('change', function(){ + const pageIds = (tableState.data || []).map(item => String(item.file_directory_id)); + if(this.checked){ + pageIds.forEach(id => selectedIds.add(id)); + }else{ + pageIds.forEach(id => selectedIds.delete(id)); + } + renderTable(); + }); + } + + if(tbody){ + tbody.addEventListener('change', function(e){ + const checkbox = e.target.closest('.row-check'); + if(!checkbox) return; + const id = String(checkbox.getAttribute('data-id')); + if(checkbox.checked){ + selectedIds.add(id); + }else{ + selectedIds.delete(id); + } + syncCheckAllState(); + updateSelectedCount(); + }); + } + + if(downloadBtn){ + downloadBtn.addEventListener('click', function(){ + if(selectedIds.size === 0){ + return; + } + const payload = { ids: Array.from(selectedIds) }; + downloadBtn.disabled = true; + downloadBtn.textContent = 'Menyiapkan...'; + fetch('/download-multiple', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content, + 'X-Requested-With': 'XMLHttpRequest' + }, + body: JSON.stringify(payload) + }) + .then(async (res) => { + const contentType = res.headers.get('content-type') || ''; + if(!res.ok || contentType.includes('application/json')){ + const err = await res.json().catch(() => ({})); + throw new Error(err?.message || 'Gagal download file'); + } + const blob = await res.blob(); + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + const disposition = res.headers.get('content-disposition') || ''; + const match = disposition.match(/filename="?([^"]+)"?/); + a.href = url; + a.download = match?.[1] || 'files.zip'; + document.body.appendChild(a); + a.click(); + a.remove(); + window.URL.revokeObjectURL(url); + }) + .catch(err => { + Swal.fire({ icon: 'error', title: 'Gagal', text: err.message || 'Gagal download file' }); + }) + .finally(() => { + downloadBtn.disabled = selectedIds.size === 0; + downloadBtn.textContent = 'Download Terpilih'; + }); + }); + } + document.addEventListener('click', function (e) { const btn = e.target.closest('.folder-prefill'); if (!btn) return; diff --git a/resources/views/dataUnit/index.blade.php b/resources/views/dataUnit/index.blade.php index a81aaf9..27fde2c 100644 --- a/resources/views/dataUnit/index.blade.php +++ b/resources/views/dataUnit/index.blade.php @@ -129,7 +129,7 @@ @@ -138,9 +138,39 @@
-
+

Data Unit

- +
+ +
+ + + + 0 dipilih + +
+ + +
@@ -162,12 +192,16 @@
+
Memuat data...
+ + Nomor Surat File Kategori
+ + ${item.no_dokumen || '-'}
@@ -368,7 +412,7 @@ if(pageData.length === 0){ tbody.innerHTML = `
+ Tidak ada data yang cocok
+ @@ -206,6 +240,10 @@ const paginationEl = document.getElementById('paginationControls'); const summaryEl = document.getElementById('tableSummary'); const pageSizeSelect = document.getElementById('tablePageSize'); + const downloadBtn = document.getElementById('btnDownloadMultiple'); + const selectedCountEl = document.getElementById('selectedCount'); + const checkAllEl = document.getElementById('checkAllRows'); + const selectedIds = new Set(); if(pageSizeSelect){ const initialSize = parseInt(pageSizeSelect.value); @@ -253,8 +291,15 @@ statusLabel = 'Internal Unit'; statusClass = 'bg-secondary'; } + const checked = selectedIds.has(String(item.file_directory_id)) ? 'checked' : ''; return ` + - @@ -351,6 +396,8 @@ } renderPagination(tableState.lastPage || 1); + syncCheckAllState(); + updateSelectedCount(); } function debouncedTableSearch(value){ @@ -396,6 +443,99 @@ } fetchData() + function updateSelectedCount(){ + if(!selectedCountEl) return; + selectedCountEl.textContent = `${selectedIds.size} dipilih`; + if(downloadBtn){ + downloadBtn.disabled = selectedIds.size === 0; + } + } + + function syncCheckAllState(){ + if(!checkAllEl) return; + const pageIds = (tableState.data || []).map(item => String(item.file_directory_id)); + if(pageIds.length === 0){ + checkAllEl.checked = false; + checkAllEl.indeterminate = false; + return; + } + const selectedOnPage = pageIds.filter(id => selectedIds.has(id)).length; + checkAllEl.checked = selectedOnPage === pageIds.length; + checkAllEl.indeterminate = selectedOnPage > 0 && selectedOnPage < pageIds.length; + } + + if(checkAllEl){ + checkAllEl.addEventListener('change', function(){ + const pageIds = (tableState.data || []).map(item => String(item.file_directory_id)); + if(this.checked){ + pageIds.forEach(id => selectedIds.add(id)); + }else{ + pageIds.forEach(id => selectedIds.delete(id)); + } + renderTable(); + }); + } + + if(tbody){ + tbody.addEventListener('change', function(e){ + const checkbox = e.target.closest('.row-check'); + if(!checkbox) return; + const id = String(checkbox.getAttribute('data-id')); + if(checkbox.checked){ + selectedIds.add(id); + }else{ + selectedIds.delete(id); + } + syncCheckAllState(); + updateSelectedCount(); + }); + } + + if(downloadBtn){ + downloadBtn.addEventListener('click', function(){ + if(selectedIds.size === 0){ + return; + } + const payload = { ids: Array.from(selectedIds) }; + downloadBtn.disabled = true; + downloadBtn.textContent = 'Menyiapkan...'; + fetch('/download-multiple', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content, + 'X-Requested-With': 'XMLHttpRequest' + }, + body: JSON.stringify(payload) + }) + .then(async (res) => { + const contentType = res.headers.get('content-type') || ''; + if(!res.ok || contentType.includes('application/json')){ + const err = await res.json().catch(() => ({})); + throw new Error(err?.message || 'Gagal download file'); + } + const blob = await res.blob(); + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + const disposition = res.headers.get('content-disposition') || ''; + const match = disposition.match(/filename="?([^"]+)"?/); + a.href = url; + a.download = match?.[1] || 'files.zip'; + document.body.appendChild(a); + a.click(); + a.remove(); + window.URL.revokeObjectURL(url); + }) + .catch(err => { + Swal.fire({ icon: 'error', title: 'Gagal', text: err.message || 'Gagal download file' }); + }) + .finally(() => { + downloadBtn.disabled = selectedIds.size === 0; + downloadBtn.textContent = 'Download Terpilih'; + }); + }); + } + document.addEventListener('click', function (e) { const btn = e.target.closest('.folder-prefill'); if (!btn) return; diff --git a/resources/views/layout/partials/sidenav.blade.php b/resources/views/layout/partials/sidenav.blade.php index 79a929f..61d3f3a 100644 --- a/resources/views/layout/partials/sidenav.blade.php +++ b/resources/views/layout/partials/sidenav.blade.php @@ -57,7 +57,7 @@ @php $isAtasan = \App\Models\MappingUnitKerjaPegawai::where('statusenabled', true)->where('objectatasanlangsungfk', auth()->user()->objectpegawaifk)->exists(); @endphp - @if($isAtasan || auth()->user()->objectpegawaifk === 23521) + @if($isAtasan) @endif @@ -198,7 +198,7 @@ countData(); - setInterval(countData, 60000); +// setInterval(countData, 60000); const masterCollapse = document.getElementById('menu-master'); const masterItem = masterCollapse diff --git a/resources/views/pendingFile/index.blade.php b/resources/views/pendingFile/index.blade.php index 306999f..f3670c5 100644 --- a/resources/views/pendingFile/index.blade.php +++ b/resources/views/pendingFile/index.blade.php @@ -47,6 +47,7 @@ +
+ + Nomor Surat File Kategori
+ + ${item.no_dokumen || '-'}
@@ -335,7 +380,7 @@ if(pageData.length === 0){ tbody.innerHTML = `
+ Tidak ada data yang cocok
Aksi No. Dokumen StatusAkses File Folder Unit / Sub Unit