diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index f5a2c51..f6ba20c 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -154,9 +154,23 @@ class DashboardController extends Controller ->values() ->all(); $keyword = request('keyword'); + $kategori = request('kategori'); + $unitFilter = request('unit'); + $kategoriIds = is_array($kategori) + ? array_values(array_filter($kategori)) + : array_values(array_filter(explode(',', (string) $kategori))); + $unitFilterIds = is_array($unitFilter) + ? array_values(array_filter($unitFilter)) + : array_values(array_filter(explode(',', (string) $unitFilter))); + if (!empty($unitFilterIds)) { + $unitIds = array_values(array_intersect($unitIds, $unitFilterIds)); + } $query = FileDirectory::where('statusenabled', true) ->where('status_action', 'approved') ->whereIn('id_unit_kerja', $unitIds) + ->when(!empty($kategoriIds), function ($q) use ($kategoriIds) { + $q->whereIn('master_kategori_directory_id', $kategoriIds); + }) ->when($keyword, function ($q) use ($keyword) { $q->where(function ($sub) use ($keyword) { $sub->where('nama_dokumen', 'ILIKE', "%{$keyword}%") @@ -274,6 +288,7 @@ class DashboardController extends Controller ]); $rowIdx++; + $grandTotal = 0; foreach ($recapData as $recap) { $unitName = $recap['unit'] ?? '-'; $folders = $recap['data'] ?? []; @@ -281,6 +296,7 @@ class DashboardController extends Controller foreach ($folders as $folderItem) { $sheet->setCellValue("F{$rowIdx}", $folderItem['folder'] ?? '-'); $sheet->setCellValue("G{$rowIdx}", $folderItem['count'] ?? 0); + $grandTotal += (int) ($folderItem['count'] ?? 0); $rowIdx++; } $unitEndRow = max($unitStartRow, $rowIdx - 1); @@ -289,6 +305,16 @@ class DashboardController extends Controller $sheet->mergeCells("E{$unitStartRow}:E{$unitEndRow}"); } } + $sheet->setCellValue("F{$rowIdx}", 'Total File'); + $sheet->setCellValue("G{$rowIdx}", $grandTotal); + $sheet->getStyle("F{$rowIdx}:G{$rowIdx}")->applyFromArray([ + 'font' => ['bold' => true], + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN + ] + ] + ]); } foreach(range('A', 'I') as $col){ @@ -828,12 +854,14 @@ class DashboardController extends Controller public function dataUmum(){ $katDok = MasterKategori::where('statusenabled', true)->select('master_kategori_directory_id', 'nama_kategori_directory')->get(); + $unitKerja = UnitKerja::where('statusenabled', true)->select('id', 'name')->orderBy('name')->get(); $authMapping = auth()->user()?->dataUser?->mappingUnitKerjaPegawai[0]; $authUnitKerja = $authMapping->objectunitkerjapegawaifk; $authSubUnitKerja = $authMapping->objectsubunitkerjapegawaifk; $data = [ 'title' => 'Dashboard', 'katDok' => $katDok, + 'unitKerja' => $unitKerja, 'authUnitKerja' => $authUnitKerja, 'authSubUnitKerja' => $authSubUnitKerja, ]; @@ -847,6 +875,14 @@ class DashboardController extends Controller // $entryPegawaiId = auth()->user()?->objectpegawaifk; $akses = AksesFile::where(['pegawai_id' => $user->id, 'statusenabled' => true])->first(); $keyword = request('keyword'); + $unitId = request('unit'); + $kategori = request('kategori'); + $unitIds = is_array($unitId) + ? array_values(array_filter($unitId)) + : array_values(array_filter(explode(',', (string) $unitId))); + $kategoriIds = is_array($kategori) + ? array_values(array_filter($kategori)) + : array_values(array_filter(explode(',', (string) $kategori))); $mapping = MappingUnitKerjaPegawai::where('statusenabled', true) ->where('objectpegawaifk', $user->id) ->get(['objectunitkerjapegawaifk', 'objectsubunitkerjapegawaifk']); @@ -863,6 +899,12 @@ class DashboardController extends Controller // ->values() // ->all(); $query = FileDirectory::where('statusenabled', true)->where('status_action', 'approved') + ->when(!empty($unitIds), function ($q) use ($unitIds) { + $q->whereIn('id_unit_kerja', $unitIds); + }) + ->when(!empty($kategoriIds), function ($q) use ($kategoriIds) { + $q->whereIn('master_kategori_directory_id', $kategoriIds); + }) ->when($keyword, function ($q) use ($keyword) { $q->where(function ($sub) use ($keyword) { $sub->where('nama_dokumen', 'ILIKE', "%{$keyword}%") @@ -970,6 +1012,7 @@ class DashboardController extends Controller DB::connection('dbDirectory')->beginTransaction(); try { $datas = request('data'); + $maxUploadBytes = 10 * 1024 * 1024; $mapping = MappingUnitKerjaPegawai::where('statusenabled', true) ->where('objectpegawaifk', auth()->user()?->dataUser?->id) ->first(); @@ -986,15 +1029,13 @@ class DashboardController extends Controller if(!$uploadedFile){ throw new \RuntimeException('File wajib diunggah pada baris ke-' . ($index+1)); } - - - // if(auth()->user()->masterPersetujuan){ - // $unitPegawaiIds = auth()->user()->masterPersetujuan->details->pluck('unit_pegawai_id')->unique()->toArray(); - // $status = in_array($id_unit_kerja, $unitPegawaiIds) - // ? 'approved' - // : null; + if (!$uploadedFile->isValid()) { + throw new \RuntimeException('Upload file gagal pada baris ke-' . ($index+1)); + } + if ($uploadedFile->getSize() > $maxUploadBytes) { + throw new \RuntimeException('Ukuran file maksimal 10MB pada baris ke-' . ($index+1)); + } $status = $isAtasan ? 'approved' : null; - // } $payload = [ 'id_unit_kerja' => $id_unit_kerja, @@ -1011,9 +1052,15 @@ class DashboardController extends Controller 'action_by' => $status && $status === "approved" ? auth()->user()->objectpegawaifk : null, 'action_at' => $status && $status === "approved" ? now() : null ]; - $imageName = $uploadedFile->getClientOriginalName(); + $imageName = trim((string) $uploadedFile->getClientOriginalName()); + if ($imageName === '') { + $ext = $uploadedFile->getClientOriginalExtension(); + $imageName = $ext ? (Str::uuid()->toString() . '.' . $ext) : Str::uuid()->toString(); + } $path = "{$nama_unit_kerja}/{$nama_sub_unit_kerja}/{$nama_kategori}"; - $uploadedFile->storeAs($path, $imageName, 'file_directory'); + $disk = Storage::disk('file_directory'); + $disk->makeDirectory($path); + $disk->putFileAs($path, $uploadedFile, $imageName); $payload['file'] =$path .'/' .$imageName; $fd = FileDirectory::create($payload); diff --git a/public/js/dashboard/functions.js b/public/js/dashboard/functions.js index 21fbe0e..a8f6c50 100644 --- a/public/js/dashboard/functions.js +++ b/public/js/dashboard/functions.js @@ -267,7 +267,7 @@ function addForm(){
- Format yang didukung: PDF. + Format yang didukung: PDF Maksimal 10mb.
diff --git a/resources/views/dashboard/modal/create.blade.php b/resources/views/dashboard/modal/create.blade.php index 7381506..2ef30c5 100644 --- a/resources/views/dashboard/modal/create.blade.php +++ b/resources/views/dashboard/modal/create.blade.php @@ -73,7 +73,7 @@
- Format yang didukung: PDF. + Format yang didukung: PDF Maksimal 10mb.
diff --git a/resources/views/dashboard/recap.blade.php b/resources/views/dashboard/recap.blade.php index 8a73ba0..de44745 100644 --- a/resources/views/dashboard/recap.blade.php +++ b/resources/views/dashboard/recap.blade.php @@ -7,7 +7,7 @@

Rekap Dokumen

- Ringkasan jumlah file per Unit dan Folder + Ringkasan jumlah file per Unit dan Kategori
diff --git a/resources/views/dataUmum/index.blade.php b/resources/views/dataUmum/index.blade.php index 1718650..0c87480 100644 --- a/resources/views/dataUmum/index.blade.php +++ b/resources/views/dataUmum/index.blade.php @@ -1,118 +1,42 @@ @extends('layout.main') + @section('body_main')
@@ -162,26 +86,25 @@
-
- - - - +
+ + + +
- +
-
Memuat data...
@@ -202,7 +125,26 @@
-
+
+
+ Tampilkan + + data +
+ +
+ +
+ Memuat data... +
+
+
@@ -220,11 +162,15 @@ const authPegawai = @json(auth()->user()->objectpegawaifk); const formCreate = $("#formFile") const modalCreate = document.getElementById('modalCreateFile') - const tableState = { data: [], page: 1, pageSize: 8, search: '', lastPage: 1, total: 0 }; + const tableState = { data: [], page: 1, pageSize: 8, search: '', unit: [], kategori: [], lastPage: 1, total: 0 }; const tbody = document.getElementById('tableDataUmum'); const paginationEl = document.getElementById('paginationControls'); const summaryEl = document.getElementById('tableSummary'); const pageSizeSelect = document.getElementById('tablePageSize'); + const unitSelect = document.getElementById('tableUnit'); + const kategoriSelect = document.getElementById('tableKategori'); + const searchInput = document.getElementById('tableSearch'); + const searchBtn = document.getElementById('btnTableSearch'); const downloadBtn = document.getElementById('btnDownloadMultiple'); const selectedCountEl = document.getElementById('selectedCount'); const checkAllEl = document.getElementById('checkAllRows'); @@ -257,6 +203,47 @@ } }); } + if (window.$ && $.fn.select2) { + if (unitSelect) { + $('#tableUnit').select2({ + placeholder: 'Pilih Unit', + allowClear: true, + width: '100%', + closeOnSelect: false, + ajax: { + url: '/select-unit-kerja-option', + dataType: 'json', + delay: 250, + data: function (params) { + return { q: params.term }; + }, + processResults: function (data) { + return { + results: (data?.data || []).map(item => ({ + id: item.id, + text: item.name + })) + }; + }, + cache: true + } + }); + $('#tableUnit').on('change', function () { + tableState.unit = $(this).val() || []; + }); + } + if (kategoriSelect) { + $('#tableKategori').select2({ + placeholder: 'Pilih Kategori', + allowClear: true, + width: '100%', + closeOnSelect: false + }); + $('#tableKategori').on('change', function () { + tableState.kategori = $(this).val() || []; + }); + } + } function resetCreateForm(){ colCount = 1; @@ -432,13 +419,13 @@ updateSelectedCount(); } - function debouncedTableSearch(value){ - clearTimeout(window.tableSearchTimer); - window.tableSearchTimer = setTimeout(() => { - tableState.search = value.trim(); - tableState.page = 1; - fetchData(); - }, 250); + function applyTableSearch(){ + const value = searchInput ? searchInput.value : ''; + tableState.search = (value || '').trim(); + tableState.unit = unitSelect && window.$ ? ($('#tableUnit').val() || []) : (tableState.unit || []); + tableState.kategori = kategoriSelect && window.$ ? ($('#tableKategori').val() || []) : (tableState.kategori || []); + tableState.page = 1; + fetchData(); } function fetchData(){ @@ -448,6 +435,12 @@ per_page: tableState.pageSize, keyword: tableState.search }); + if (tableState.unit && tableState.unit.length > 0) { + tableState.unit.forEach(id => params.append('unit[]', id)); + } + if (tableState.kategori && tableState.kategori.length > 0) { + tableState.kategori.forEach(kat => params.append('kategori[]', kat)); + } fetch(`/datatable-umum?${params.toString()}`) .then(response => response.json()) .then(data => { @@ -462,6 +455,18 @@ }) } + if (searchBtn) { + searchBtn.addEventListener('click', applyTableSearch); + } + if (searchInput) { + searchInput.addEventListener('keydown', (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + applyTableSearch(); + } + }); + } + function formatTanggal(dateString) { const d = new Date(dateString); diff --git a/resources/views/dataUmum/modal/create.blade.php b/resources/views/dataUmum/modal/create.blade.php index 14b996f..6a8d705 100644 --- a/resources/views/dataUmum/modal/create.blade.php +++ b/resources/views/dataUmum/modal/create.blade.php @@ -96,7 +96,7 @@
- Format yang didukung: PDF. + Format yang didukung: PDF Maksimal 10mb.
diff --git a/resources/views/dataUnit/index.blade.php b/resources/views/dataUnit/index.blade.php index 21339ce..1c5e3aa 100644 --- a/resources/views/dataUnit/index.blade.php +++ b/resources/views/dataUnit/index.blade.php @@ -1,54 +1,40 @@ @extends('layout.main') @section('body_main')
@@ -98,27 +84,22 @@
-
- - - - -
-
- + -
- -
Memuat data...
+ +
+
@@ -140,6 +121,25 @@
+
+
+ Tampilkan + + data +
+ +
+ +
+ Memuat data... +
+

@@ -163,11 +163,15 @@ const authPegawai = @json(auth()->user()->objectpegawaifk); const formCreate = $("#formFile"); const modalCreate = document.getElementById('modalCreateFile'); - const tableState = { data: [], page: 1, pageSize: 8, search: '', lastPage: 1, total: 0 }; + const tableState = { data: [], page: 1, pageSize: 8, search: '', unit: [], kategori: [], lastPage: 1, total: 0 }; const tbody = document.getElementById('tableDataUnit'); const paginationEl = document.getElementById('paginationControls'); const summaryEl = document.getElementById('tableSummary'); const pageSizeSelect = document.getElementById('tablePageSize'); + const unitSelect = document.getElementById('tableUnit'); + const kategoriSelect = document.getElementById('tableKategori'); + const searchInput = document.getElementById('tableSearch'); + const searchBtn = document.getElementById('btnTableSearch'); const downloadBtn = document.getElementById('btnDownloadMultiple'); const selectedCountEl = document.getElementById('selectedCount'); const checkAllEl = document.getElementById('checkAllRows'); @@ -200,6 +204,51 @@ } }); } + if (window.$ && $.fn.select2) { + if (unitSelect) { + $('#tableUnit').select2({ + placeholder: 'Pilih Unit', + allowClear: true, + width: '100%', + closeOnSelect: false, + selectionCssClass: 'select2-filter-selection', + dropdownCssClass: 'select2-filter-dropdown', + ajax: { + url: '/select-unit-kerja-option', + dataType: 'json', + delay: 250, + data: function (params) { + return { q: params.term }; + }, + processResults: function (data) { + return { + results: (data?.data || []).map(item => ({ + id: item.id, + text: item.name + })) + }; + }, + cache: true + } + }); + $('#tableUnit').on('change', function () { + tableState.unit = $(this).val() || []; + }); + } + if (kategoriSelect) { + $('#tableKategori').select2({ + placeholder: 'Pilih Kategori', + allowClear: true, + width: '100%', + closeOnSelect: false, + selectionCssClass: 'select2-filter-selection', + dropdownCssClass: 'select2-filter-dropdown' + }); + $('#tableKategori').on('change', function () { + tableState.kategori = $(this).val() || []; + }); + } + } function resetCreateForm(){ colCount = 1; @@ -361,13 +410,13 @@ updateSelectedCount(); } - function debouncedTableSearch(value){ - clearTimeout(window.tableSearchTimer); - window.tableSearchTimer = setTimeout(() => { - tableState.search = value.trim(); - tableState.page = 1; - fetchData(); - }, 250); + function applyTableSearch(){ + const value = searchInput ? searchInput.value : ''; + tableState.search = (value || '').trim(); + tableState.unit = unitSelect && window.$ ? ($('#tableUnit').val() || []) : (tableState.unit || []); + tableState.kategori = kategoriSelect && window.$ ? ($('#tableKategori').val() || []) : (tableState.kategori || []); + tableState.page = 1; + fetchData(); } function fetchData(){ @@ -377,6 +426,12 @@ per_page: tableState.pageSize, keyword: tableState.search }); + if (tableState.unit && tableState.unit.length > 0) { + tableState.unit.forEach(id => params.append('unit[]', id)); + } + if (tableState.kategori && tableState.kategori.length > 0) { + tableState.kategori.forEach(kat => params.append('kategori[]', kat)); + } fetch(`/data-internal?${params.toString()}`) .then(response => response.json()) .then(data => { @@ -391,6 +446,18 @@ }) } + if (searchBtn) { + searchBtn.addEventListener('click', applyTableSearch); + } + if (searchInput) { + searchInput.addEventListener('keydown', (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + applyTableSearch(); + } + }); + } + function formatTanggal(dateString) { const d = new Date(dateString); diff --git a/resources/views/dataUnit/modal/create.blade.php b/resources/views/dataUnit/modal/create.blade.php index a8c1aaa..9f254db 100644 --- a/resources/views/dataUnit/modal/create.blade.php +++ b/resources/views/dataUnit/modal/create.blade.php @@ -96,7 +96,7 @@
- Format yang didukung: PDF. + Format yang didukung: PDF Maksimal 10mb.
diff --git a/resources/views/dataUnit/section/recap.blade.php b/resources/views/dataUnit/section/recap.blade.php index b01c426..6afd619 100644 --- a/resources/views/dataUnit/section/recap.blade.php +++ b/resources/views/dataUnit/section/recap.blade.php @@ -3,7 +3,7 @@ @if ($showRecapTitle)

Rekap Dokumen

- Ringkasan jumlah file per Unit dan Folder + Ringkasan jumlah file per Unit dan Kategori
@endif
@@ -31,7 +31,7 @@ # Unit - Folder + Kategori Jumlah File @@ -86,6 +86,7 @@ function fetchRecap(){ tbody.innerHTML = `Tidak ada data`; return; } + let grandTotal = 0; const html = rows.map((row, idx) => { const folderRows = (row.data || []).map((f, i) => ` @@ -95,9 +96,15 @@ function fetchRecap(){ ${f.count || 0} `).join(''); + (row.data || []).forEach(f => { grandTotal += (parseInt(f.count, 10) || 0); }); return folderRows; }).join(''); - tbody.innerHTML = html; + tbody.innerHTML = html + ` + + Total File + ${grandTotal} + + `; renderRecapPagination(); }) .catch(err => { diff --git a/resources/views/layout/main.blade.php b/resources/views/layout/main.blade.php index 2e6dba7..48e0bd2 100644 --- a/resources/views/layout/main.blade.php +++ b/resources/views/layout/main.blade.php @@ -25,7 +25,7 @@ .modal-content, .modal-body, .message-body { - color-scheme: light; + color-scheme: black; scrollbar-color: auto; scrollbar-width: auto; }