diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index 42aa711..f5a2c51 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -203,8 +203,8 @@ class DashboardController extends Controller $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); - $sheet->setCellValue('A1', "List Dokumen"); - $sheet->mergeCells('A1:F1'); + $sheet->setCellValue('A1', "List Dokumen Unit"); + $sheet->mergeCells('A1:I1'); $sheet->getStyle('A1')->getFont()->setBold(true)->setSize(14); $sheet->getStyle('A1')->getAlignment()->setHorizontal('center'); $headers = [ @@ -213,11 +213,13 @@ class DashboardController extends Controller 'Kategori', 'Unit', 'Sub Unit', + 'Tanggal Terbit', + 'Tanggal Expired', 'Tanggal Upload', 'Pengunggah' ]; $sheet->fromArray($headers, null, 'A4'); - $sheet->getStyle('A4:G4')->applyFromArray([ + $sheet->getStyle('A4:I4')->applyFromArray([ 'font' => ['bold' => true], 'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER], 'borders' => [ @@ -226,9 +228,9 @@ class DashboardController extends Controller ] ] ]); - $sheet->getStyle('A4:G4')->getFont()->setBold(true); - $sheet->getStyle('A4:G4')->getAlignment()->setHorizontal('center'); - $sheet->getStyle('A4:G4')->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN); + $sheet->getStyle('A4:I4')->getFont()->setBold(true); + $sheet->getStyle('A4:I4')->getAlignment()->setHorizontal('center'); + $sheet->getStyle('A4:I4')->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN); $rowIdx = 5; foreach ($rows as $item) { $parts = array_values(array_filter(explode('/', (string) $item->file))); @@ -242,6 +244,8 @@ class DashboardController extends Controller $kategoriName, $unitName, $subUnitName, + $item->tanggal_terbit ? Carbon::parse($item->tanggal_terbit)->format('d/m/Y') : '-', + $item->tgl_expired ? Carbon::parse($item->tgl_expired)->format('d/m/Y') : '-', $item->entry_at ? Carbon::parse($item->entry_at)->format('d/m/Y') : '-', $item->pegawai_nama_entry ?? '-' ], null, "A{$rowIdx}"); @@ -287,7 +291,7 @@ class DashboardController extends Controller } } - foreach(range('A', 'G') as $col){ + foreach(range('A', 'I') as $col){ $sheet->getColumnDimension($col)->setAutoSize(true); } $fileName = 'data-unit-' . now()->format('Ymd-His') . '.xlsx'; @@ -515,6 +519,46 @@ class DashboardController extends Controller ], 200); } + public function OptionUnitKerjaByMapping(){ + $q = request()->get('q'); + $pegawaiId = auth()->user()?->dataUser?->id; + $mapping = MappingUnitKerjaPegawai::where('statusenabled', true) + ->where('objectpegawaifk', $pegawaiId) + ->get(['objectunitkerjapegawaifk', 'objectsubunitkerjapegawaifk']); + + $unitIds = $mapping->pluck('objectunitkerjapegawaifk')->filter()->unique()->values(); + $subIds = $mapping->pluck('objectsubunitkerjapegawaifk')->filter()->unique()->values(); + + $units = UnitKerja::where('statusenabled', true) + ->when($unitIds->isNotEmpty(), fn($q2) => $q2->whereIn('id', $unitIds)) + ->when($q, fn($q2) => $q2->where('name', 'ILIKE', '%' . $q . '%')) + ->select('id', 'name') + ->get(); + + $subUnits = $subIds->isNotEmpty() + ? SubUnitKerja::where('statusenabled', true) + ->whereIn('id', $subIds) + ->get(['id', 'name', 'objectunitkerjapegawaifk']) + : collect(); + + $subMap = $subUnits->groupBy('objectunitkerjapegawaifk')->map(function($items){ + return $items->map(fn($s) => ['id' => $s->id, 'name' => $s->name])->values(); + }); + + $data = $units->map(function($u) use ($subMap){ + return [ + 'id' => $u->id, + 'name' => $u->name, + 'sub_unit_kerja' => $subMap[$u->id] ?? [] + ]; + })->values(); + + return response()->json([ + 'status' => true, + 'data' => $data + ], 200); + } + public function deleteFile(string $id){ DB::connection('dbDirectory')->beginTransaction(); try { @@ -586,6 +630,27 @@ class DashboardController extends Controller 'data' => $data, ]); } + + public function optionSubUnitKerjaByMapping(string $id){ + $pegawaiId = auth()->user()?->dataUser?->id; + $subIds = MappingUnitKerjaPegawai::where('statusenabled', true) + ->where('objectpegawaifk', $pegawaiId) + ->where('objectunitkerjapegawaifk', $id) + ->pluck('objectsubunitkerjapegawaifk') + ->filter() + ->unique() + ->values(); + + $data = SubUnitKerja::where('statusenabled', true) + ->where('objectunitkerjapegawaifk', $id) + ->when($subIds->isNotEmpty(), fn($q) => $q->whereIn('id', $subIds)) + ->get(); + + return response()->json([ + 'status' => true, + 'data' => $data, + ]); + } public function getFile($id_unit_kerja, $id_sub_unit_kerja, $master_kategori_directory_id){ $klasifikasi = request('klasifikasi'); $klaArray = explode(',', $klasifikasi); @@ -834,26 +899,17 @@ class DashboardController extends Controller public function downloadDataUmumExcel() { - $user = auth()->user()?->dataUser; - $akses = AksesFile::where(['pegawai_id' => $user->id, 'statusenabled' => true])->first(); - $keyword = request('keyword'); - - $query = FileDirectory::where('statusenabled', true) + $rows = FileDirectory::where('statusenabled', true) ->where('status_action', 'approved') - ->when($keyword, function ($q) use ($keyword) { - $q->where(function ($sub) use ($keyword) { - $sub->where('nama_dokumen', 'ILIKE', "%{$keyword}%") - ->orWhere('no_dokumen', 'ILIKE', "%{$keyword}%"); - }); - }); - if (!$akses || !$akses->all_akses) { - $query->where('permission_file', true); - } - - $rows = $query->orderBy('entry_at', 'desc')->get(); + ->where('permission_file', true) + ->orderBy('entry_at', 'desc')->get(); $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); + $sheet->setCellValue('A1', "List Dokumen Umum"); + $sheet->mergeCells('A1:H1'); + $sheet->getStyle('A1')->getFont()->setBold(true)->setSize(14); + $sheet->getStyle('A1')->getAlignment()->setHorizontal('center'); $headers = [ 'No Dokumen', 'Nama Dokumen', @@ -861,19 +917,28 @@ class DashboardController extends Controller 'Unit', 'Sub Unit', 'Tanggal Terbit', + 'Tanggal Expired', 'Tanggal Upload', - 'Pengunggah', - 'Akses' ]; - $sheet->fromArray($headers, null, 'A1'); - - $rowIdx = 2; + $sheet->fromArray($headers, null, 'A4'); + $sheet->getStyle('A4:H4')->applyFromArray([ + 'font' => ['bold' => true], + 'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER], + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN + ] + ] + ]); + $sheet->getStyle('A4:H4')->getFont()->setBold(true); + $sheet->getStyle('A4:H4')->getAlignment()->setHorizontal('center'); + $sheet->getStyle('A4:H4')->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN); + $rowIdx = 5; foreach ($rows as $item) { $parts = array_values(array_filter(explode('/', (string) $item->file))); $unitName = $parts[0] ?? '-'; $subName = $parts[1] ?? '-'; $kategoriName = $parts[2] ?? '-'; - $aksesLabel = $item->permission_file ? 'Umum' : 'Internal Unit'; $sheet->fromArray([ $item->no_dokumen ?? '-', @@ -882,13 +947,14 @@ class DashboardController extends Controller $unitName, $subName, $item->tanggal_terbit ? Carbon::parse($item->tanggal_terbit)->format('d/m/Y') : '-', - $item->entry_at ? Carbon::parse($item->entry_at)->format('d/m/Y H:i') : '-', - $item->pegawai_nama_entry ?? '-', - $aksesLabel + $item->tgl_expired ? Carbon::parse($item->tgl_expired)->format('d/m/Y') : '-', + $item->entry_at ? Carbon::parse($item->entry_at)->format('d/m/Y') : '-' ], null, "A{$rowIdx}"); $rowIdx++; } - + foreach(range('A', 'H') as $col){ + $sheet->getColumnDimension($col)->setAutoSize(true); + } $fileName = 'data-umum-' . now()->format('Ymd-His') . '.xlsx'; $tempPath = storage_path('app/temp'); if (!is_dir($tempPath)) { diff --git a/public/js/pendingFile/index.js b/public/js/pendingFile/index.js index d949b81..f12d699 100644 --- a/public/js/pendingFile/index.js +++ b/public/js/pendingFile/index.js @@ -102,10 +102,10 @@ document.addEventListener('DOMContentLoaded', () => { const checked = selectedIds.has(id); const aksi = `
- -
@@ -123,13 +123,13 @@ document.addEventListener('DOMContentLoaded', () => { ${safeText(item.no_dokumen)} ${statusBadge(item?.status_action)} ${aksesBadge(item?.permission_file)} - ${safeText(item.nama_dokumen)} + data-no_dokumen="${item.no_dokumen || '-'}" + data-tanggal_terbit="${item.tanggal_terbit || '-'}" + data-permission_file="${item.permission_file || '-'}">${item.nama_dokumen}
${safeText(item.folder)}
${safeText(item.part)}
${tanggalTerbit} @@ -443,6 +443,7 @@ document.addEventListener('DOMContentLoaded', () => { }); 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') @@ -471,7 +472,11 @@ document.addEventListener('click', function(e){ permEl.className = 'badge ' + (publicDoc ? 'bg-success' : 'bg-secondary'); } let previewBox = document.getElementById('file-preview'); - previewBox.innerHTML = ``; + previewBox.innerHTML = `
+
+
+ `; + openPreview(idDirectory); $("#previewModal").modal('show') } diff --git a/public/js/pengajuanFile/index.js b/public/js/pengajuanFile/index.js index a1db297..84f55ef 100644 --- a/public/js/pengajuanFile/index.js +++ b/public/js/pengajuanFile/index.js @@ -73,7 +73,7 @@ document.addEventListener('DOMContentLoaded', () => { ${aksesBadge(item?.permission_file)} { width: '100%', dropdownParent: $('#modalEditPengajuanFile'), ajax: { - url: '/select-unit-kerja', + url: '/select-unit-kerja-mapping', dataType: 'json', delay: 250, data: function (params) { @@ -266,7 +266,7 @@ document.addEventListener('DOMContentLoaded', () => { editSubUnitSelect.empty().append(''); if (!unitId) return; $.ajax({ - url: `/select-sub-unit-kerja/${unitId}`, + url: `/select-sub-unit-kerja-mapping/${unitId}`, method: 'GET', success: function(response) { if (response?.data) { @@ -437,8 +437,12 @@ document.addEventListener('click', function(e){ permEl.textContent = publicDoc ? 'Umum' : 'Internal Unit'; permEl.className = 'badge ' + (publicDoc ? 'bg-success' : 'bg-secondary'); } - let previewBox = document.getElementById('file-preview'); - previewBox.innerHTML = ``; + let previewBox = document.getElementById('file-preview'); + previewBox.innerHTML = `
+
+
+ `; + openPreview(idDirectory); $("#previewModal").modal('show') } diff --git a/resources/views/dataUmum/index.blade.php b/resources/views/dataUmum/index.blade.php index b5da677..1718650 100644 --- a/resources/views/dataUmum/index.blade.php +++ b/resources/views/dataUmum/index.blade.php @@ -273,6 +273,19 @@ return val === '1' || val === 'true' || val === 'iya' || val === 'yes'; } + function getExpiryStatus(dateStr){ + if (!dateStr) return false; + const d = new Date(dateStr); + if (Number.isNaN(d.getTime())) return null; + const today = new Date(); + today.setHours(0, 0, 0, 0); + d.setHours(0, 0, 0, 0); + if (d < today) return 'expired'; + const diffDays = Math.ceil((d - today) / 86400000); + if (diffDays <= 7) return 'soon'; + return null; + } + function buildRow(item){ const parts = (item.file || '').split('/'); const fileName = parts.pop() || '-'; @@ -281,6 +294,7 @@ const unitName = parts[0] || ''; const subName = parts[1] || ''; const kategoriName = parts[2] || ''; + const expiryStatus = getExpiryStatus(item.tgl_expired); let statusLabel = ''; let statusClass = ''; let badge @@ -292,8 +306,12 @@ statusClass = 'bg-secondary'; } const checked = selectedIds.has(String(item.file_directory_id)) ? 'checked' : ''; + const rowClass = expiryStatus === 'expired' ? 'table-danger' : (expiryStatus === 'soon' ? 'table-warning' : ''); + const expiryBadge = expiryStatus === 'expired' + ? `Expired` + : (expiryStatus === 'soon' ? `Akan Expired` : ''); return ` - + ${item.nama_dokumen || '-'}
+ ${expiryBadge} @@ -588,7 +607,7 @@ allowClear: true, width: '100%', ajax: { - url : '/select-unit-kerja', + url : '/select-unit-kerja-mapping', dataType: 'json', delay: 250, data: function(params){ @@ -645,7 +664,7 @@ $('.sub_unit_kerja').empty().append(''); $.ajax({ - url: `/select-sub-unit-kerja/${unitId}`, + url: `/select-sub-unit-kerja-mapping/${unitId}`, method: 'GET', success: function(response) { if (response?.data) { @@ -813,7 +832,7 @@ width: '100%', dropdownParent: selectUnit.parent(), ajax:{ - url : '/select-unit-kerja', + url : '/select-unit-kerja-mapping', dataType: 'json', delay: 250, data: function(params){ @@ -830,7 +849,7 @@ }, cache: true, }, - minimumInputLength: 1, + minimumInputLength: 0, }); selectSubUnit.select2({ diff --git a/resources/views/dataUnit/index.blade.php b/resources/views/dataUnit/index.blade.php index bf8d2d7..21339ce 100644 --- a/resources/views/dataUnit/index.blade.php +++ b/resources/views/dataUnit/index.blade.php @@ -216,6 +216,19 @@ return val === '1' || val === 'true' || val === 'iya' || val === 'yes'; } + function getExpiryStatus(dateStr){ + if (!dateStr) return false; + const d = new Date(dateStr); + if (Number.isNaN(d.getTime())) return null; + const today = new Date(); + today.setHours(0, 0, 0, 0); + d.setHours(0, 0, 0, 0); + if (d < today) return 'expired'; + const diffDays = Math.ceil((d - today) / 86400000); + if (diffDays <= 7) return 'soon'; + return null; + } + function buildRow(item){ const parts = (item.file || '').split('/'); const fileName = parts.pop() || '-'; @@ -224,6 +237,7 @@ const unitName = parts[0] || ''; const subName = parts[1] || ''; const kategoriName = parts[2] || ''; + const expiryStatus = getExpiryStatus(item.tgl_expired); let statusLabel = ''; let statusClass = ''; @@ -235,8 +249,12 @@ statusClass = 'bg-secondary'; } const checked = selectedIds.has(String(item.file_directory_id)) ? 'checked' : ''; + const rowClass = expiryStatus === 'expired' ? 'table-danger' : (expiryStatus === 'soon' ? 'table-warning' : ''); + const expiryBadge = expiryStatus === 'expired' + ? `Expired` + : (expiryStatus === 'soon' ? `Akan Expired` : ''); return ` - + ${item.nama_dokumen || '-'} + ${expiryBadge} @@ -517,7 +536,7 @@ allowClear: true, width: '100%', ajax: { - url : '/select-unit-kerja', + url : '/select-unit-kerja-mapping', dataType: 'json', delay: 250, data: function(params){ @@ -574,7 +593,7 @@ $('.sub_unit_kerja').empty().append(''); $.ajax({ - url: `/select-sub-unit-kerja/${unitId}`, + url: `/select-sub-unit-kerja-mapping/${unitId}`, method: 'GET', success: function(response) { if (response?.data) { @@ -748,7 +767,7 @@ width: '100%', dropdownParent: selectUnit.parent(), ajax:{ - url : '/select-unit-kerja', + url : '/select-unit-kerja-mapping', dataType: 'json', delay: 250, data: function(params){ @@ -765,7 +784,7 @@ }, cache: true, }, - minimumInputLength: 1, + minimumInputLength: 0, }); selectSubUnit.select2({ diff --git a/routes/web.php b/routes/web.php index 8eca3e0..5d80830 100644 --- a/routes/web.php +++ b/routes/web.php @@ -39,7 +39,9 @@ Route::middleware(['auth'])->group(function(){ }); Route::get('/select-unit-kerja', [DashboardController::class, 'OptionUnitKerja']); + Route::get('/select-unit-kerja-mapping', [DashboardController::class, 'OptionUnitKerjaByMapping']); Route::get('/select-sub-unit-kerja/{id}', [DashboardController::class, 'optionSubUnitKerja']); + Route::get('/select-sub-unit-kerja-mapping/{id}', [DashboardController::class, 'optionSubUnitKerjaByMapping']); Route::delete('/delete-file/{id}', [DashboardController::class, 'deleteFile']); Route::get('/getFile/{id_unit_kerja}/{id_sub_unit_kerja}/{master_kategori_directory_id}', [DashboardController::class, 'getFile']);