diff --git a/app/Http/Controllers/AksesFileController.php b/app/Http/Controllers/AksesFileController.php index be85742..5f3dcd1 100644 --- a/app/Http/Controllers/AksesFileController.php +++ b/app/Http/Controllers/AksesFileController.php @@ -3,9 +3,9 @@ namespace App\Http\Controllers; use App\Models\AksesFile; +use App\Models\AksesFileDetail; use App\Models\DataUser; use App\Models\FileDirectory; -use App\Models\MappingUnitKerjaPegawai; use App\Models\UnitKerja; use Carbon\Carbon; use Illuminate\Http\Request; @@ -41,21 +41,25 @@ class AksesFileController extends Controller try { $datas = request('data'); foreach ($datas as $data) { - $pegawai = MappingUnitKerjaPegawai::where(['objectpegawaifk'=> $data['pegawai_id'], 'statusenabled' => true])->first(); $payload = [ 'pegawai_id' => $data['pegawai_id'], 'pegawai_id_entry' => auth()->user()?->dataUser?->id, 'pegawai_nama_entry' => auth()->user()?->dataUser?->namalengkap, 'entry_at' => Carbon::now()->format('Y-m-d H:i:s.u'), + 'all_akses' => $data['akses'] === "all" ? true : false, ]; - if($data['akses'] === "all"){ - $payload['all_akses'] = true; - }else{ - $payload['all_akses'] = false; - $payload['unit_akses'] = $pegawai->objectunitkerjapegawaifk ?? null; - + $af = AksesFile::create($payload); + if($data['akses'] === "unit"){ + $unitIds = collect($data['unit_akses'] ?? [])->filter()->unique()->values(); + foreach ($unitIds as $unitId) { + $payloadDetail = [ + 'akses_file_id' => $af->akses_file_id, + 'statusenabled' => true, + 'id_unit_kerja' => $unitId, + ]; + AksesFileDetail::create($payloadDetail); + } } - AksesFile::create($payload); } DB::connection('dbDirectory')->commit(); return response()->json([ @@ -76,7 +80,55 @@ class AksesFileController extends Controller */ public function show(string $id) { - // + $data = AksesFile::where('akses_file_id', $id)->first(); + if (!$data) { + return response()->json([ + 'status' => false, + 'message' => 'Data tidak ditemukan' + ], 404); + } + + $aksesAll = $data->akses ?? null; + if (is_null($aksesAll)) { + $aksesAll = $data->all_akses ?? null; + } + $aksesType = $aksesAll ? 'all' : 'unit'; + + $units = []; + $detailUnits = AksesFileDetail::where('akses_file_id', $id) + ->where('statusenabled', true) + ->get(); + if ($detailUnits->isNotEmpty()) { + $unitIds = $detailUnits->pluck('id_unit_kerja'); + $units = UnitKerja::whereIn('id', $unitIds) + ->select('id', 'name') + ->get() + ->map(function ($unit) { + return [ + 'id' => $unit->id, + 'text' => $unit->name, + ]; + }) + ->values(); + } elseif (!empty($data->unit_akses)) { + $unit = UnitKerja::where('id', $data->unit_akses)->select('id', 'name')->first(); + if ($unit) { + $units[] = [ + 'id' => $unit->id, + 'text' => $unit->name, + ]; + } + } + + return response()->json([ + 'status' => true, + 'data' => [ + 'akses_type' => $aksesType, + 'pegawai_id' => $data->pegawai_id, + 'pegawai_nama' => $data?->pegawai?->namalengkap, + 'units' => $units, + ] + ], 200); } /** @@ -92,19 +144,40 @@ class AksesFileController extends Controller */ public function update(Request $request, string $id) { + DB::connection('dbDirectory')->beginTransaction(); try { $data = AksesFile::where('akses_file_id', $id)->first(); - $pegawai = MappingUnitKerjaPegawai::where(['objectpegawaifk' => request('pegawai_id'), 'statusenabled' => true])->first(); + if (!$data) { + return response()->json([ + 'status' => false, + 'message' => 'Data tidak ditemukan' + ], 404); + } + $payload = [ 'pegawai_id' => request('pegawai_id'), 'pegawai_id_modified' => auth()->user()?->dataUser?->id, 'pegawai_nama_modified' => auth()->user()?->dataUser?->namalengkap, 'modified_at' => Carbon::now()->format('Y-m-d H:i:s.u'), 'all_akses' => request('akses') === "all" ? true : false, - 'unit_akses' => $pegawai?->objectunitkerjapegawaifk ?? null ]; $data->update($payload); + AksesFileDetail::where('akses_file_id', $id)->delete(); + + if (request('akses') === 'unit') { + $unitIds = collect(request('unit_akses') ?? [])->filter()->unique()->values(); + foreach ($unitIds as $unitId) { + $payloadDetail = [ + 'akses_file_id' => $data->akses_file_id, + 'statusenabled' => true, + 'id_unit_kerja' => $unitId, + ]; + AksesFileDetail::create($payloadDetail); + } + } + + DB::connection('dbDirectory')->commit(); return response()->json([ 'status' => true, 'message' => 'Data berhasil diperbarui', @@ -123,26 +196,43 @@ class AksesFileController extends Controller */ public function destroy(string $id) { - $data = AksesFile::where('akses_file_id', $id)->first(); - if(!$data){ + try { + $data = AksesFile::where('akses_file_id', $id) + ->where('statusenabled', true) + ->first(); + + if (!$data) { + return response()->json([ + 'status' => false, + 'message' => 'Data tidak ditemukan' + ], 404); + } + + DB::transaction(function () use ($id, $data) { + AksesFileDetail::where('akses_file_id', $id) + ->where('statusenabled', true) + ->update(['statusenabled' => false]); + $data->update(['statusenabled' => false]); + }); + + return response()->json([ + 'status' => true, + 'message' => 'Data berhasil dihapus' + ], 200); + + } catch (\Throwable $th) { return response()->json([ 'status' => false, - 'message' => 'Data tidak ditemukan' - ], 404); + 'message' => 'Gagal menghapus data', + ], 500); } - $payload =[ - 'statusenabled' => false - ]; - $data->update($payload); - return response()->json([ - 'status' => true, - 'message' => 'Data berhasil dihapus' - ], 200); } public function datatable(){ - return AksesFile::where('statusenabled', true)->get(); + return AksesFile::with(['details.unit']) + ->where('statusenabled', true) + ->get(); } public function optionPegawai(){ diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index 55d4e56..3635379 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -3,12 +3,14 @@ namespace App\Http\Controllers; use App\Models\AksesFile; +use App\Models\AksesFileDetail; use App\Models\FileDirectory; use App\Models\LogActivity; use App\Models\MasterKategori; use App\Models\MasterKlasifikasi; use App\Models\SubUnitKerja; use App\Models\UnitKerja; +use Carbon\Carbon; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Storage; @@ -43,19 +45,37 @@ class DashboardController extends Controller public function dataUnitKerja(){ $user = auth()->user()?->dataUser; $akses = AksesFile::where(['pegawai_id' => $user->id, 'statusenabled' => true])->first(); + $aksesAll = $akses?->akses ?? $akses?->all_akses ?? false; + $detailUnitIds = collect(); + if ($akses?->akses_file_id) { + $detailUnitIds = AksesFileDetail::where('akses_file_id', $akses->akses_file_id) + ->where('statusenabled', true) + ->pluck('id_unit_kerja') + ->unique() + ->values(); + } + $allowedUnitIds = null; + if (!$aksesAll) { + if ($detailUnitIds->isNotEmpty()) { + $allowedUnitIds = $detailUnitIds; + } elseif (!empty($akses?->unit_akses)) { + $allowedUnitIds = collect([$akses->unit_akses]); + } + } $kategori = request('kategori'); $filterUnit = request('unitKerja'); $subUnit = request('subUnit'); - $klasifikasi = request('klasifikasi'); $keyword = request('keyword'); $subArray = $subUnit ? explode(',', $subUnit) : []; $katArray = $kategori ? explode(',', $kategori) : []; - $klaArray = $klasifikasi ? explode(',', $klasifikasi) : []; $katDok = MasterKategori::when($katArray, fn($q) => $q->whereIn('master_kategori_directory_id', $katArray))->where('statusenabled', true)->select('master_kategori_directory_id', 'nama_kategori_directory')->get(); - if ($katArray && $filterUnit && $subArray && $klaArray) { + if ($katArray && $filterUnit && $subArray) { /* mode pencarian lengkap */ + if ($allowedUnitIds && !$allowedUnitIds->contains((int) $filterUnit)) { + $unitKerja = collect(); + } else { $unitKerja = UnitKerja::where('statusenabled', true) ->where('id', $filterUnit) ->with(['subUnitKerja' => fn($q) => $q->whereIn('id', $subArray) @@ -63,7 +83,6 @@ class DashboardController extends Controller ->where('id_unit_kerja', $filterUnit) ->when($subArray, fn($q) => $q->whereIn('id_sub_unit_kerja', $subArray)) ->when($katArray, fn($q) => $q->whereIn('master_kategori_directory_id', $katArray)) - ->when($klaArray, fn($q) => $q->whereIn('master_klasifikasi_directory_id', $klaArray)) ->when($keyword, fn($q) => $q->where(function($query) use ($keyword) { $query->where('file', 'ilike', "%{$keyword}%") @@ -74,8 +93,9 @@ class DashboardController extends Controller ]) ->select('id', 'name') ->get(); + } - } elseif ($akses?->all_akses) { + } elseif ($aksesAll) { /* all akses */ $unitKerja = UnitKerja::where('statusenabled', true)->with([ // muat relasi 'subUnitKerja' => fn($q) => $q->with([ // sub-unit @@ -88,9 +108,10 @@ class DashboardController extends Controller ->select('id', 'name') ->get(); - } elseif ($akses?->unit_akses) { - /* akses per unit */ - $unitKerja = UnitKerja::where(['statusenabled' => true, 'id' => $akses->unit_akses]) + } elseif ($allowedUnitIds) { + /* akses per unit (single/multiple) */ + $unitKerja = UnitKerja::where('statusenabled', true) + ->whereIn('id', $allowedUnitIds) ->with([ // muat relasi 'subUnitKerja' => fn($q) => $q->with([ // sub-unit 'fileDirectory' => fn($f) => $f->when($keyword, fn($q) => @@ -378,23 +399,43 @@ class DashboardController extends Controller public function dataDocumentLast(){ $perPage = (int) request('per_page', 10); $authUnitId = auth()->user()->dataUser?->mappingUnitKerjaPegawai[0]?->objectunitkerjapegawaifk; + $user = auth()->user()?->dataUser; + $akses = AksesFile::where(['pegawai_id' => $user->id, 'statusenabled' => true])->first(); $keyword = request('keyword'); - $data = FileDirectory::where('statusenabled', true) - ->where(function ($query) use ($authUnitId) { - $query->where('permission_file', true) - ->orWhere(function ($sub) use ($authUnitId) { - $sub->where('permission_file', false) - ->where('id_unit_kerja', $authUnitId); - }); - }) + $query = FileDirectory::where('statusenabled', true) ->when($keyword, function ($q) use ($keyword) { $q->where(function ($sub) use ($keyword) { $sub->where('file', 'ILIKE', "%{$keyword}%") ->orWhere('no_dokumen', 'ILIKE', "%{$keyword}%"); }); - }) - ->orderBy('entry_at', 'desc') + }); + if($akses){ + if(!$akses->all_akses){ + $aksesFile = AksesFileDetail::where('akses_file_id', $akses->akses_file_id)->pluck('id_unit_kerja'); + $query->where(function ($query) use ($authUnitId, $aksesFile) { + $query->where('permission_file', true) + ->orWhere(function ($sub) use ($authUnitId, $aksesFile) { + $sub->where('permission_file', false) + ->whereIn('id_unit_kerja', $aksesFile); + }); + }); + }else{ + $query; + } + }else{ + $query->where(function ($query) use ($authUnitId) { + $query->where('permission_file', true) + ->orWhere(function ($sub) use ($authUnitId) { + $sub->where('permission_file', false) + ->where('id_unit_kerja', $authUnitId); + }); + }); + } + + + + $data = $query->orderBy('entry_at', 'desc') ->paginate($perPage); $payload = [ @@ -661,8 +702,10 @@ class DashboardController extends Controller foreach ($grouped as $unitName => $folders) { $data = []; foreach ($folders as $folder => $count) { + $sliceText = array_values(array_filter(explode('/', $folder))); $data[] = [ - 'folder'=> $folder, + 'subUnit' => $sliceText[0], + 'folder'=> $sliceText[1], 'count' => $count, ]; } @@ -701,4 +744,161 @@ class DashboardController extends Controller public function recapView(){ return view('dashboard.recap', ['title' => 'Rekap Dokumen']); } + + public function pendingFile(){ + return view('pendingFile.index', ['title' => 'Data Pending']); + } + + public function dataPendingFile(){ + $perPage = (int) request('per_page', 10); + $keyword = request('keyword'); + $start = request('start_date'); + $end = request('end_date'); + + $query = FileDirectory::where('statusenabled', true)->whereNull('status_action')->orderBy('entry_at','desc'); + if($keyword){ + $query->where(function($q) use ($keyword){ + $q->where('file', 'ILIKE', "%{$keyword}%") + ->orWhere('no_dokumen', 'ILIKE', "%{$keyword}%"); + }); + } + if($start){ + $query->whereDate('entry_at','>=',$start); + } + if($end){ + $query->whereDate('entry_at','<=',$end); + } + + $paginated = $query->paginate($perPage); + $data = $paginated->getCollection()->map(function($item){ + $dataSlice = array_values(array_filter(explode('/', $item->file))); + return [ + 'file_directory_id' => $item->file_directory_id, + 'pegawai_nama_entry' => $item->pegawai_nama_entry, + 'part' => $dataSlice[0] . '/' . $dataSlice[1], + 'folder' => $dataSlice[2], + 'fileName' =>$dataSlice[3], + 'file' => $item->file, + 'no_dokumen' => $item->no_dokumen, + 'entry_at' => $item->entry_at, + 'tanggal_terbit' => $item->tanggal_terbit, + 'permission_file' => $item->permission_file, + ]; + }); + return response()->json([ + 'status' => true, + 'data' => $data, + 'pagination' => [ + 'current_page' => $paginated->currentPage(), + 'next_page' => $paginated->hasMorePages() ? $paginated->currentPage() + 1 : null, + 'has_more' => $paginated->hasMorePages(), + 'last_page' => $paginated->lastPage(), + 'per_page' => $paginated->perPage(), + 'total' => $paginated->total(), + ] + ]); + + } + + public function approvePendingFile(string $id){ + try { + $data = FileDirectory::where('file_directory_id', $id)->first(); + if(!$data){ + return response()->json([ + 'status' => false, + 'message' => 'Data tidak ditemukan' + ], 404); + } + $data->update([ + 'status_action' => 'approved', + 'action_at' => Carbon::now(), + 'action_by' => auth()->user()->dataUser->id, + ]); + $payloadLog = [ + 'file_directory_id' => $data->file_directory_id, + 'pegawai_id_entry' => $data->action_by, + 'pegawai_nama_entry' => auth()->user()->dataUser->namalengkap, + 'entry_at' => $data->action_at, + 'action_type' => 'Approval Dokumen', + 'statusenabled' => true, + 'mod_change' => $data->entry_at, + 'id_unit_kerja' => $data->id_unit_kerja, + 'id_sub_unit_kerja' => $data->id_sub_unit_kerja, + 'file' => $data->file, + 'tanggal_terbit' => $data->tanggal_terbit, + 'no_dokumen' => $data->no_dokumen, + 'permission_file' => $data->permission_file, + ]; + LogActivity::create($payloadLog); + return response()->json([ + 'status' => true, + 'message' => 'File berhasil di-approve' + ], 200); + } catch (\Throwable $th) { + return response()->json([ + 'status' => false, + 'message' => $th->getMessage() + ], 500); + } + } + + public function rejectPendingFile(string $id){ + try { + $data = FileDirectory::where('file_directory_id', $id)->first(); + if(!$data){ + return response()->json([ + 'status' => false, + 'message' => 'Data tidak ditemukan' + ], 404); + } + $data->update([ + 'status_action' => 'rejected', + 'action_at' => Carbon::now(), + 'action_by' => auth()->user()->dataUser->id, + ]); + $payloadLog = [ + 'file_directory_id' => $data->file_directory_id, + 'pegawai_id_entry' => $data->action_by, + 'pegawai_nama_entry' => auth()->user()->dataUser->namalengkap, + 'entry_at' => $data->action_at, + 'action_type' => 'Reject Dokumen', + 'statusenabled' => true, + 'mod_change' => $data->entry_at, + 'id_unit_kerja' => $data->id_unit_kerja, + 'id_sub_unit_kerja' => $data->id_sub_unit_kerja, + 'file' => $data->file, + 'tanggal_terbit' => $data->tanggal_terbit, + 'no_dokumen' => $data->no_dokumen, + 'permission_file' => $data->permission_file, + ]; + LogActivity::create($payloadLog); + return response()->json([ + 'status' => true, + 'message' => 'File berhasil di-reject' + ], 200); + } catch (\Throwable $th) { + return response()->json([ + 'status' => false, + 'message' => $th->getMessage() + ], 500); + } + } + + public function countDataPending(){ + try { + $count = FileDirectory::where('statusenabled', true) + ->whereNull('status_action') + ->count(); + return response()->json([ + 'status' => true, + 'count' => $count, + 'message' => 'Berhasil mendapatkan data' + ]); + } catch (\Throwable $th) { + return response()->json([ + 'status' => false, + 'message' => 'Terdapat kesalahan!' + ]); + } + } } diff --git a/app/Http/Controllers/LogActivityController.php b/app/Http/Controllers/LogActivityController.php index b64c7d2..a969c0a 100644 --- a/app/Http/Controllers/LogActivityController.php +++ b/app/Http/Controllers/LogActivityController.php @@ -9,7 +9,7 @@ class LogActivityController extends Controller { public function index(){ $data =[ - 'title' => 'Log Activity' + 'title' => 'Log Aktivitas' ]; return view('logActivity.index', $data); } diff --git a/app/Models/AksesFile.php b/app/Models/AksesFile.php index 065fbe7..7991315 100644 --- a/app/Models/AksesFile.php +++ b/app/Models/AksesFile.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use App\Models\AksesFileDetail; class AksesFile extends Model { @@ -21,4 +22,9 @@ class AksesFile extends Model public function akses(){ return $this->belongsTo(UnitKerja::class, 'unit_akses', 'id')->select('id', 'name'); } + + public function details() + { + return $this->hasMany(AksesFileDetail::class, 'akses_file_id', 'akses_file_id'); + } } diff --git a/app/Models/AksesFileDetail.php b/app/Models/AksesFileDetail.php new file mode 100644 index 0000000..2b709ab --- /dev/null +++ b/app/Models/AksesFileDetail.php @@ -0,0 +1,20 @@ +belongsTo(UnitKerja::class, 'id_unit_kerja', 'id')->select('id', 'name'); + } +} diff --git a/public/js/akses/action.js b/public/js/akses/action.js index 299eec3..9c674a3 100644 --- a/public/js/akses/action.js +++ b/public/js/akses/action.js @@ -103,13 +103,36 @@ function editAkses(e){ const data = $(e).data(); new bootstrap.Modal(modalEdit).show(); formEditAkses.attr('action', `/akses/${data.akses_file_id}`) - $("#akses_id_edit").val(data.akses === 1 ? 'all' : 'unit') + $("#unit_akses_edit").empty().trigger('change'); + $("#unit_akses_wrapper_edit").addClass('d-none'); selectOptionPegawaiEdit() + selectOptionUnitKerjaEdit() if (data.pegawai_id) { setOldSelect2Value('#pegawai_id_edit', data.pegawai_id, data.pegawai_nama); } + fetch(`/akses/${data.akses_file_id}`) + .then(async(res) => { + const responseData = await res.json(); + if (!responseData.status) { + throw new Error(responseData.message || 'Gagal memuat data akses.'); + } + const detail = responseData.data; + if (detail?.akses_type === 'all') { + $("#akses_all_edit").prop('checked', true); + } else { + $("#akses_unit_edit").prop('checked', true); + } + toggleUnitAksesEdit(); + if (detail?.akses_type === 'unit' && Array.isArray(detail.units)) { + setOldSelect2Values('#unit_akses_edit', detail.units); + } + }) + .catch(() => { + $("#akses_all_edit").prop('checked', true); + toggleUnitAksesEdit(); + }); } @@ -143,6 +166,46 @@ function selectOptionPegawaiEdit() { }); } +function selectOptionUnitKerjaEdit() { + let selectUnit = $(`#unit_akses_edit`); + if (selectUnit.data('select2')) return; + selectUnit.select2({ + placeholder: '-- Pilih Unit Kerja --', + allowClear:true, + width: '100%', + dropdownParent: selectUnit.parent(), + ajax:{ + url : '/select-unit-kerja', + 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, + }, + minimumInputLength: 1, + }); +} + +function toggleUnitAksesEdit() { + const wrapper = $("#unit_akses_wrapper_edit"); + const unitSelect = $("#unit_akses_edit"); + const isUnit = $("#akses_unit_edit").is(':checked'); + if (isUnit) { + wrapper.removeClass('d-none'); + } else { + wrapper.addClass('d-none'); + unitSelect.val(null).trigger('change'); + } +} function setOldSelect2Value(selector, id, text) { @@ -151,6 +214,16 @@ function setOldSelect2Value(selector, id, text) { $(selector).append(option).trigger('change') } +function setOldSelect2Values(selector, items) { + if (!Array.isArray(items) || items.length === 0) return; + items.forEach(item => { + if (!item?.id || !item?.text) return; + let option = new Option(item.text, item.id, true, true); + $(selector).append(option); + }); + $(selector).trigger('change') +} + formEditAkses.on('submit', function(e){ e.preventDefault(); diff --git a/public/js/akses/dt.js b/public/js/akses/dt.js index 60b9987..5dc8206 100644 --- a/public/js/akses/dt.js +++ b/public/js/akses/dt.js @@ -25,15 +25,13 @@ ` - buttons += ` ` return ` @@ -50,7 +48,13 @@ { title:"Akses", formatter:function(value, row){ - return row?.all_akses ? 'Semua Akses' : row?.akses?.name; + if (row?.all_akses) return 'Semua Unit'; + const units = (row?.details || []) + .filter(detail => detail?.statusenabled) + .map(detail => detail?.unit?.name) + .filter(Boolean); + if (units.length > 0) return units.join(', '); + return row?.akses?.name || '-'; } } ], diff --git a/public/js/akses/functions.js b/public/js/akses/functions.js index 82cdf88..7471874 100644 --- a/public/js/akses/functions.js +++ b/public/js/akses/functions.js @@ -1,5 +1,6 @@ $(document).ready(function() { selectOptionPegawai(0) + selectOptionUnitKerja(0) }); function selectOptionPegawai(colCount) { @@ -31,6 +32,46 @@ function selectOptionPegawai(colCount) { }); } +function selectOptionUnitKerja(colCount) { + let selectUnit = $(`#unit_akses_${colCount}`); + selectUnit.select2({ + placeholder: '-- Pilih Unit Kerja --', + allowClear: true, + width: '100%', + dropdownParent: selectUnit.parent(), + ajax:{ + url : '/select-unit-kerja', + 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, + }, + minimumInputLength: 1, + }); +} + +function toggleUnitAkses(colCount) { + const wrapper = $(`#unit_akses_wrapper_${colCount}`); + const unitSelect = $(`#unit_akses_${colCount}`); + const isUnit = $(`#akses_unit_${colCount}`).is(':checked'); + if (isUnit) { + wrapper.removeClass('d-none'); + } else { + wrapper.addClass('d-none'); + unitSelect.val(null).trigger('change'); + } +} + let colCount = 1; @@ -42,18 +83,38 @@ function addForm(){ html += `

-
+
-
- - + +
+
+ + +
+
+ Pilih salah satu. +
+
+ + + Bisa pilih lebih dari satu.
@@ -63,6 +124,7 @@ function addForm(){ ` col.append(html) selectOptionPegawai(colCount) + selectOptionUnitKerja(colCount) colCount++; } @@ -71,4 +133,3 @@ function addForm(){ function removeCol(count){ $(`#col-${count}`).remove() } - diff --git a/public/js/dashboard/functions.js b/public/js/dashboard/functions.js index 5c242b6..8b23a57 100644 --- a/public/js/dashboard/functions.js +++ b/public/js/dashboard/functions.js @@ -37,10 +37,10 @@ $(document).ready(function() { }); // --- isi default unit kerja --- - if(authUnitKerja){ - let option = new Option(authUnitKerja.name, authUnitKerja.id, true, true); - $('.unit_kerja').append(option).trigger('change'); - } + // if(authUnitKerja){ + // let option = new Option(authUnitKerja.name, authUnitKerja.id, true, true); + // $('.unit_kerja').append(option).trigger('change'); + // } let initialUnit = $('.unit_kerja').val(); if(initialUnit){ diff --git a/public/js/dashboard/index.js b/public/js/dashboard/index.js index 1af6d30..ccb9305 100644 --- a/public/js/dashboard/index.js +++ b/public/js/dashboard/index.js @@ -273,7 +273,7 @@ function downloadMultiple(){ URL.revokeObjectURL(url); }) .catch(err => { - Swal.fire({ icon: 'error', title : 'Gagal mengunduh' }) + Swal.fire({ icon: 'error', title : err.message }) }) } diff --git a/public/js/pendingFile/index.js b/public/js/pendingFile/index.js new file mode 100644 index 0000000..2610fed --- /dev/null +++ b/public/js/pendingFile/index.js @@ -0,0 +1,307 @@ +document.addEventListener('DOMContentLoaded', () => { + const tableState = { data: [], page: 1, pageSize: 10, search: '', lastPage: 1, total: 0, startDate: '', endDate: '' }; + const tbody = document.getElementById('tablePendingFile'); + const paginationEl = document.getElementById('paginationControls'); + const summaryEl = document.getElementById('tableSummary'); + const pageSizeSelect = document.getElementById('tablePageSize'); + const startDateInput = document.getElementById('startDate'); + const endDateInput = document.getElementById('endDate'); + const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content'); + + if (pageSizeSelect) { + const initialSize = parseInt(pageSizeSelect.value); + if (!isNaN(initialSize)) tableState.pageSize = initialSize; + pageSizeSelect.addEventListener('change', (e) => { + const val = parseInt(e.target.value); + if (!isNaN(val) && val > 0) { + tableState.pageSize = val; + tableState.page = 1; + fetchData(); + } + }); + } + + window.applyDateFilter = function(){ + tableState.startDate = startDateInput.value || ''; + tableState.endDate = endDateInput.value || ''; + tableState.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', + hour: '2-digit', + minute: '2-digit' + }); + } + + function buildRow(item){ + let tanggal = item.entry_at ? formatTanggal(item.entry_at) : '-'; + const aksi = ` +
+ + +
+ `; + return ` + + ${aksi} + ${item.no_dokumen || '-'} + ${item.fileName} + ${item.folder || '-'} + ${item.part || '-'} + ${tanggal} + + `; + } + + function renderPagination(totalPages){ + if (!paginationEl) return; + if (totalPages <= 1) { + paginationEl.innerHTML = ''; + return; + } + const maxButtons = 5; + let start = Math.max(1, tableState.page - Math.floor(maxButtons/2)); + let end = Math.min(totalPages, start + maxButtons - 1); + start = Math.max(1, end - maxButtons + 1); + + let buttons = ''; + buttons += ``; + for (let i = start; i <= end; i++) { + buttons += ``; + } + buttons += ``; + + paginationEl.innerHTML = ` +
+
${buttons}
+ Halaman ${tableState.page} dari ${totalPages} +
+ `; + } + + if (paginationEl) { + paginationEl.addEventListener('click', (e) => { + const page = e.target.getAttribute('data-page'); + if (!page) return; + if (page === 'prev' && tableState.page > 1) tableState.page--; + else if (page === 'next') { + if (tableState.page < tableState.lastPage) tableState.page++; + } else { + tableState.page = parseInt(page); + } + fetchData(); + }); + } + + function renderTable(){ + const pageData = tableState.data || []; + if (pageData.length === 0) { + tbody.innerHTML = ` + + + Tidak ada data + + + `; + } else { + tbody.innerHTML = pageData.map(buildRow).join(''); + } + + const from = tableState.total === 0 ? 0 : ((tableState.page - 1) * tableState.pageSize) + 1; + const to = Math.min(((tableState.page - 1) * tableState.pageSize) + pageData.length, tableState.total); + if (summaryEl) { + summaryEl.textContent = tableState.total ? `Menampilkan ${from} - ${to} dari ${tableState.total} data` : 'Tidak ada data'; + } + + renderPagination(tableState.lastPage || 1); + } + + let searchDebounce; + window.debouncedTableSearch = function(value){ + clearTimeout(searchDebounce); + searchDebounce = setTimeout(() => { + tableState.search = value.trim(); + tableState.page = 1; + fetchData(); + }, 250); + } + + window.refreshLog = function(){ + tableState.search = ''; + tableState.startDate = ''; + tableState.endDate = ''; + document.getElementById('tableSearch').value = ''; + startDateInput.value = ''; + endDateInput.value = ''; + tableState.page = 1; + fetchData(); + } + + function fetchData(){ + if (summaryEl) summaryEl.textContent = 'Memuat data...'; + const params = new URLSearchParams({ + page: tableState.page, + per_page: tableState.pageSize, + keyword: tableState.search || '', + start_date: tableState.startDate || '', + end_date: tableState.endDate || '' + }); + fetch(`/datatable/pending-file?${params.toString()}`) + .then(res => res.json()) + .then(data => { + tableState.data = data?.data || []; + tableState.lastPage = data?.pagination?.last_page || 1; + tableState.total = data?.pagination?.total || 0; + renderTable(); + }) + .catch(err => { + console.error(err); + if (summaryEl) summaryEl.textContent = 'Gagal memuat data'; + }); + } + + window.approvePending = function(id, fileName){ + Swal.fire({ + title: 'Approve dokumen?', + text: fileName || 'Dokumen akan disetujui.', + icon: 'question', + showCancelButton: true, + confirmButtonText: 'Approve', + cancelButtonText: 'Batal', + }).then((result) => { + if (!result.isConfirmed) return; + fetch(`/pending-file/${id}/approve`, { + method: 'POST', + headers: { + 'X-CSRF-TOKEN': csrfToken, + 'Content-Type': 'application/json' + }, + }).then(async(res) => { + const data = await res.json(); + if (!res.ok || !data?.status) { + throw new Error(data?.message || 'Gagal approve.'); + } + Swal.fire({ + icon: 'success', + title: 'Berhasil', + text: data.message || 'Dokumen disetujui.', + timer: 1500, + showConfirmButton: false + }); + countData() + fetchData(); + }).catch((err) => { + Swal.fire({ + icon: 'error', + title: 'Gagal', + text: err.message || 'Terjadi kesalahan.' + }); + }); + }); + } + + window.rejectPending = function(id, fileName){ + Swal.fire({ + title: 'Reject dokumen?', + text: fileName || 'Dokumen akan ditolak.', + icon: 'warning', + showCancelButton: true, + confirmButtonText: 'Reject', + cancelButtonText: 'Batal', + }).then((result) => { + if (!result.isConfirmed) return; + fetch(`/pending-file/${id}/reject`, { + method: 'POST', + headers: { + 'X-CSRF-TOKEN': csrfToken, + 'Content-Type': 'application/json' + }, + }).then(async(res) => { + const data = await res.json(); + if (!res.ok || !data?.status) { + throw new Error(data?.message || 'Gagal reject.'); + } + Swal.fire({ + icon: 'success', + title: 'Berhasil', + text: data.message || 'Dokumen ditolak.', + timer: 1500, + showConfirmButton: false + }); + countData() + fetchData(); + }).catch((err) => { + Swal.fire({ + icon: 'error', + title: 'Gagal', + text: err.message || 'Terjadi kesalahan.' + }); + }); + }); + } + + fetchData(); + + +}); +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 ? 'Bisa dilihat unit lain' : 'Hanya unit ini'; + permEl.className = 'badge ' + (publicDoc ? 'bg-success' : 'bg-secondary'); + } + let previewBox = document.getElementById('file-preview'); + previewBox.innerHTML = ``; + $("#previewModal").modal('show') + } + + + if(e.target.matches('#btn-view-full')){ + window.open(`/file-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'; + } diff --git a/resources/views/akses/modal/add.blade.php b/resources/views/akses/modal/add.blade.php index d8334ef..a6dfff7 100644 --- a/resources/views/akses/modal/add.blade.php +++ b/resources/views/akses/modal/add.blade.php @@ -4,7 +4,7 @@ @@ -13,25 +13,51 @@ @csrf diff --git a/resources/views/akses/modal/edit.blade.php b/resources/views/akses/modal/edit.blade.php index 02c8f07..e55c927 100644 --- a/resources/views/akses/modal/edit.blade.php +++ b/resources/views/akses/modal/edit.blade.php @@ -4,7 +4,7 @@ @@ -14,20 +14,43 @@ @method('PUT')