done -> add aws save file
This commit is contained in:
parent
3739cefbdd
commit
a3fe338530
@ -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);
|
||||
|
||||
@ -267,7 +267,7 @@ function addForm(){
|
||||
</div>
|
||||
|
||||
<div class="form-text text-muted">
|
||||
Format yang didukung: <b>PDF</b>.
|
||||
Format yang didukung: <b>PDF</b> Maksimal <b>10mb</b>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -73,7 +73,7 @@
|
||||
<div class="mt-2 text-success fw-semibold d-none file-name"></div>
|
||||
</div>
|
||||
<div class="form-text text-muted">
|
||||
Format yang didukung: <b>PDF</b>.
|
||||
Format yang didukung: <b>PDF</b> Maksimal <b>10mb</b>.
|
||||
</div>
|
||||
</div>
|
||||
<div id="col_add_file" class="col-12"></div>
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<div class="d-flex flex-column flex-md-row align-items-md-center gap-2">
|
||||
<div>
|
||||
<h4 class="mb-0">Rekap Dokumen</h4>
|
||||
<small class="text-muted">Ringkasan jumlah file per Unit dan Folder</small>
|
||||
<small class="text-muted">Ringkasan jumlah file per Unit dan Kategori</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,118 +1,42 @@
|
||||
@extends('layout.main')
|
||||
<style>
|
||||
.file-cell {
|
||||
max-width: 420px;
|
||||
/* --- SELECT2: teks terlihat (hitam) --- */
|
||||
.select2-container--default .select2-selection--multiple {
|
||||
background: #fff !important;
|
||||
border: 1px solid #ced4da !important;
|
||||
min-height: 31px; /* cocok form-select-sm */
|
||||
}
|
||||
|
||||
.file-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
|
||||
color: #111 !important;
|
||||
}
|
||||
|
||||
.file-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-weight: 600;
|
||||
color: #1f2937;
|
||||
.select2-container--default .select2-search--inline .select2-search__field {
|
||||
color: #111 !important;
|
||||
}
|
||||
|
||||
.file-title i {
|
||||
font-size: 18px;
|
||||
color: #6366f1;
|
||||
.select2-container--default .select2-dropdown {
|
||||
background: #fff !important;
|
||||
border: 1px solid #ced4da !important;
|
||||
}
|
||||
|
||||
.file-link {
|
||||
color: #1f2937;
|
||||
text-decoration: none;
|
||||
line-height: 1.3;
|
||||
.select2-container--default .select2-results__option {
|
||||
color: #111 !important;
|
||||
}
|
||||
|
||||
.file-link:hover {
|
||||
color: #4f46e5;
|
||||
text-decoration: underline;
|
||||
.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
|
||||
background: #e9ecef !important;
|
||||
color: #111 !important;
|
||||
}
|
||||
|
||||
.file-meta {
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
/* tag chip */
|
||||
.select2-container--default .select2-selection--multiple .select2-selection__choice {
|
||||
background: #f1f3f5 !important;
|
||||
border: 1px solid #dee2e6 !important;
|
||||
color: #111 !important;
|
||||
}
|
||||
|
||||
.file-meta span {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
/* status pending */
|
||||
.file-pending {
|
||||
font-style: italic;
|
||||
color: #9ca3af !important;
|
||||
}
|
||||
|
||||
.dataunit-tabs .nav-link {
|
||||
border: 0;
|
||||
color: #475569;
|
||||
font-weight: 600;
|
||||
padding: 0.6rem 1rem;
|
||||
border-radius: 999px;
|
||||
transition: background-color .15s ease, color .15s ease, box-shadow .15s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dataunit-tabs .nav-link.active {
|
||||
background: color-mix(in srgb, var(--bs-primary) 12%, #ffffff);
|
||||
color: var(--bs-primary);
|
||||
+}
|
||||
|
||||
.dataunit-tabs .nav-link:hover {
|
||||
color: var(--bs-primary);
|
||||
background: color-mix(in srgb, var(--bs-primary) 8%, #ffffff);
|
||||
}
|
||||
|
||||
.dataunit-tabs .nav-link::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 18px;
|
||||
right: 18px;
|
||||
bottom: 6px;
|
||||
height: 2px;
|
||||
border-radius: 999px;
|
||||
background: var(--bs-primary);
|
||||
transform: scaleX(0);
|
||||
transform-origin: center;
|
||||
transition: transform .18s ease;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.dataunit-tabs .nav-link:hover::after {
|
||||
transform: scaleX(1);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.dataunit-tab-wrap {
|
||||
background: #f8fafc;
|
||||
border-radius: 999px;
|
||||
padding: 6px;
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dataunit-tabs {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dataunit-tabs .nav-item {
|
||||
flex: 1 1 0;
|
||||
}
|
||||
|
||||
.dataunit-tabs .nav-link {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@section('body_main')
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
@ -162,26 +86,25 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column flex-md-row align-items-md-center gap-2 mb-3">
|
||||
<div class="input-group input-group-sm flex-grow-1">
|
||||
<span class="input-group-text bg-white border-end-0">
|
||||
<i class="fa fa-search text-muted"></i>
|
||||
</span>
|
||||
<input type="search"
|
||||
id="tableSearch"
|
||||
class="form-control border-start-0"
|
||||
placeholder="Cari nama file, No Dokumen atau folder"
|
||||
oninput="debouncedTableSearch(this.value)">
|
||||
<div class="d-flex flex-column flex-md-row align-items-md-center gap-2 flex-grow-1">
|
||||
<select id="tableUnit" class="form-select form-select-sm unit_kerja_filter" style="max-width: 260px;" multiple></select>
|
||||
<select id="tableKategori" class="form-select form-select-sm kategori_kerja_filter" style="max-width: 260px;" multiple>
|
||||
@foreach ($katDok as $kat)
|
||||
<option value="{{ $kat->master_kategori_directory_id }}">
|
||||
{{ $kat->nama_kategori_directory }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<input type="search"
|
||||
id="tableSearch"
|
||||
class="form-control"
|
||||
placeholder="Cari nama dokumen atau No Dokumen"
|
||||
autocomplete="off">
|
||||
<button class="btn btn-outline-secondary" type="button" id="btnTableSearch">Cari</button>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<select id="tablePageSize" class="form-select form-select-sm" style="width: auto;">
|
||||
<option value="5">5</option>
|
||||
<option value="10"selected>10</option>
|
||||
<option value="20">20</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
<div class="small text-muted ms-md-auto" id="tableSummary">Memuat data...</div>
|
||||
</div>
|
||||
<div class="table-responsive" style="max-height: 70vh; overflow-y:auto;">
|
||||
<table class="table table-sm table-hover align-middle mb-0 table-fixed" id="lastUpdatedTable">
|
||||
@ -202,7 +125,26 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="d-flex flex-column flex-md-row align-items-md-center justify-content-between gap-2 mt-3" id="paginationControls"></div>
|
||||
<div class="d-flex flex-wrap align-items-center gap-2 mt-3">
|
||||
<div class="d-flex align-items-center gap-1">
|
||||
<span class="small text-muted">Tampilkan</span>
|
||||
<select id="tablePageSize" class="form-select form-select-sm" style="width: 80px;">
|
||||
<option value="5">5</option>
|
||||
<option value="10" selected>10</option>
|
||||
<option value="20">20</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
<span class="small text-muted">data</span>
|
||||
</div>
|
||||
|
||||
<div id="paginationControls" class="ms-auto"></div>
|
||||
|
||||
<div class="small text-muted text-nowrap" id="tableSummary">
|
||||
Memuat data...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -96,7 +96,7 @@
|
||||
<div class="mt-2 text-success fw-semibold d-none file-name"></div>
|
||||
</div>
|
||||
<div class="form-text text-muted">
|
||||
Format yang didukung: <b>PDF</b>.
|
||||
Format yang didukung: <b>PDF</b> Maksimal <b>10mb</b>.
|
||||
</div>
|
||||
</div>
|
||||
<div id="col_add_fileV2" class="col-12"></div>
|
||||
|
||||
@ -1,54 +1,40 @@
|
||||
@extends('layout.main')
|
||||
<style>
|
||||
.file-cell {
|
||||
max-width: 420px;
|
||||
/* --- SELECT2: teks terlihat (hitam) --- */
|
||||
.select2-container--default .select2-selection--multiple {
|
||||
background: #fff !important;
|
||||
border: 1px solid #ced4da !important;
|
||||
min-height: 31px; /* cocok form-select-sm */
|
||||
}
|
||||
|
||||
.file-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
|
||||
color: #111 !important;
|
||||
}
|
||||
|
||||
.file-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-weight: 600;
|
||||
color: #1f2937;
|
||||
.select2-container--default .select2-search--inline .select2-search__field {
|
||||
color: #111 !important;
|
||||
}
|
||||
|
||||
.file-title i {
|
||||
font-size: 18px;
|
||||
color: #6366f1;
|
||||
.select2-container--default .select2-dropdown {
|
||||
background: #fff !important;
|
||||
border: 1px solid #ced4da !important;
|
||||
}
|
||||
|
||||
.file-link {
|
||||
color: #1f2937;
|
||||
text-decoration: none;
|
||||
line-height: 1.3;
|
||||
.select2-container--default .select2-results__option {
|
||||
color: #111 !important;
|
||||
}
|
||||
|
||||
.file-link:hover {
|
||||
color: #4f46e5;
|
||||
text-decoration: underline;
|
||||
.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable {
|
||||
background: #e9ecef !important;
|
||||
color: #111 !important;
|
||||
}
|
||||
|
||||
.file-meta {
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
/* tag chip */
|
||||
.select2-container--default .select2-selection--multiple .select2-selection__choice {
|
||||
background: #f1f3f5 !important;
|
||||
border: 1px solid #dee2e6 !important;
|
||||
color: #111 !important;
|
||||
}
|
||||
|
||||
.file-meta span {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
/* status pending */
|
||||
.file-pending {
|
||||
font-style: italic;
|
||||
color: #9ca3af !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
@section('body_main')
|
||||
<div class="row">
|
||||
@ -98,27 +84,22 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column flex-md-row align-items-md-center gap-2 mb-3">
|
||||
<div class="input-group input-group-sm flex-grow-1">
|
||||
<span class="input-group-text bg-white border-end-0">
|
||||
<i class="fa fa-search text-muted"></i>
|
||||
</span>
|
||||
<input type="search"
|
||||
id="tableSearch"
|
||||
class="form-control border-start-0"
|
||||
placeholder="Cari nama file, No Dokumen atau folder"
|
||||
oninput="debouncedTableSearch(this.value)">
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<select id="tablePageSize" class="form-select form-select-sm" style="width: auto;">
|
||||
<option value="5">5</option>
|
||||
<option value="10"selected>10</option>
|
||||
<option value="20">20</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
<div class="d-flex flex-column flex-md-row align-items-md-center gap-2 flex-grow-1">
|
||||
<select id="tableUnit" class="form-select form-select-sm unit_kerja_filter" style="max-width: 260px;" multiple></select>
|
||||
<select id="tableKategori" class="form-select form-select-sm kategori_kerja_filter" style="max-width: 260px;" multiple>
|
||||
@foreach ($katDok as $kat)
|
||||
<option value="{{ $kat->master_kategori_directory_id }}">
|
||||
{{ $kat->nama_kategori_directory }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="small text-muted ms-md-auto" id="tableSummary">Memuat data...</div>
|
||||
<input type="search"
|
||||
id="tableSearch"
|
||||
class="form-control"
|
||||
placeholder="Cari nama dokumen atau No Dokumen"
|
||||
autocomplete="off">
|
||||
</div>
|
||||
<button class="btn btn-primary" type="button" id="btnTableSearch">Cari</button>
|
||||
</div>
|
||||
<div class="table-responsive" style="max-height: 70vh; overflow-y:auto;">
|
||||
<table class="table table-sm table-hover align-middle mb-0 table-fixed" id="lastUpdatedTable">
|
||||
@ -140,6 +121,25 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="d-flex flex-wrap align-items-center gap-2 mt-3">
|
||||
<div class="d-flex align-items-center gap-1">
|
||||
<span class="small text-muted">Tampilkan</span>
|
||||
<select id="tablePageSize" class="form-select form-select-sm" style="width: 80px;">
|
||||
<option value="5">5</option>
|
||||
<option value="10" selected>10</option>
|
||||
<option value="20">20</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
<span class="small text-muted">data</span>
|
||||
</div>
|
||||
|
||||
<div id="paginationControls" class="ms-auto"></div>
|
||||
|
||||
<div class="small text-muted text-nowrap" id="tableSummary">
|
||||
Memuat data...
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column flex-md-row align-items-md-center justify-content-between gap-2 mt-3" id="paginationControls"></div>
|
||||
|
||||
<hr class="my-4">
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -96,7 +96,7 @@
|
||||
<div class="mt-2 text-success fw-semibold d-none file-name"></div>
|
||||
</div>
|
||||
<div class="form-text text-muted">
|
||||
Format yang didukung: <b>PDF</b>.
|
||||
Format yang didukung: <b>PDF</b> Maksimal <b>10mb</b>.
|
||||
</div>
|
||||
</div>
|
||||
<div id="col_add_fileV2" class="col-12"></div>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
@if ($showRecapTitle)
|
||||
<div>
|
||||
<h4 class="mb-0">Rekap Dokumen</h4>
|
||||
<small class="text-muted">Ringkasan jumlah file per Unit dan Folder</small>
|
||||
<small class="text-muted">Ringkasan jumlah file per Unit dan Kategori</small>
|
||||
</div>
|
||||
@endif
|
||||
<div class="{{ $showRecapTitle ? 'ms-md-auto' : '' }} d-flex gap-2 align-items-center">
|
||||
@ -31,7 +31,7 @@
|
||||
<tr>
|
||||
<th style="width:5%;" class="text-center">#</th>
|
||||
<th style="width:30%;">Unit</th>
|
||||
<th style="width:20%;">Folder</th>
|
||||
<th style="width:20%;">Kategori</th>
|
||||
<th style="width:15%;" class="text-center">Jumlah File</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -86,6 +86,7 @@ function fetchRecap(){
|
||||
tbody.innerHTML = `<tr><td colspan="4" class="text-center text-muted py-4">Tidak ada data</td></tr>`;
|
||||
return;
|
||||
}
|
||||
let grandTotal = 0;
|
||||
const html = rows.map((row, idx) => {
|
||||
const folderRows = (row.data || []).map((f, i) => `
|
||||
<tr>
|
||||
@ -95,9 +96,15 @@ function fetchRecap(){
|
||||
<td class="text-center fw-bold">${f.count || 0}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
(row.data || []).forEach(f => { grandTotal += (parseInt(f.count, 10) || 0); });
|
||||
return folderRows;
|
||||
}).join('');
|
||||
tbody.innerHTML = html;
|
||||
tbody.innerHTML = html + `
|
||||
<tr class="table-light">
|
||||
<td colspan="3" class="text-end fw-semibold">Total File</td>
|
||||
<td class="text-center fw-bold">${grandTotal}</td>
|
||||
</tr>
|
||||
`;
|
||||
renderRecapPagination();
|
||||
})
|
||||
.catch(err => {
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
.modal-content,
|
||||
.modal-body,
|
||||
.message-body {
|
||||
color-scheme: light;
|
||||
color-scheme: black;
|
||||
scrollbar-color: auto;
|
||||
scrollbar-width: auto;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user