progress action approval
This commit is contained in:
parent
44c4689f77
commit
093a8f2b4d
@ -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(){
|
||||
|
||||
@ -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!'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ class LogActivityController extends Controller
|
||||
{
|
||||
public function index(){
|
||||
$data =[
|
||||
'title' => 'Log Activity'
|
||||
'title' => 'Log Aktivitas'
|
||||
];
|
||||
return view('logActivity.index', $data);
|
||||
}
|
||||
|
||||
@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
20
app/Models/AksesFileDetail.php
Normal file
20
app/Models/AksesFileDetail.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Models\UnitKerja;
|
||||
|
||||
class AksesFileDetail extends Model
|
||||
{
|
||||
protected $connection = 'dbDirectory';
|
||||
protected $table = 'public.akses_file_unit_detail';
|
||||
public $timestamps = false;
|
||||
protected $primaryKey = 'id';
|
||||
protected $guarded = ['id'];
|
||||
|
||||
public function unit()
|
||||
{
|
||||
return $this->belongsTo(UnitKerja::class, 'id_unit_kerja', 'id')->select('id', 'name');
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
|
||||
@ -25,15 +25,13 @@
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
`
|
||||
|
||||
buttons += `
|
||||
<button class="btn btn-sm btn-primary me-2" onclick="editAkses(this)"
|
||||
data-akses_file_id="${row.akses_file_id}" data-akses="${row?.all_akses ? 1 : row?.unit_akses}"
|
||||
data-pegawai_id="${row?.pegawai_id}"
|
||||
data-pegawai_nama="${row?.pegawai?.namalengkap}"
|
||||
data-unit_id="${row?.unit_akses}"
|
||||
data-unit_nama="${row?.akses?.name}"
|
||||
>
|
||||
data-unit_nama="${row?.akses?.name}">
|
||||
<i class="fa-solid fa-pencil"></i>
|
||||
</button>`
|
||||
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 || '-';
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@ -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 += `
|
||||
<div class="row mt-3" id="col-${colCount}">
|
||||
<hr/>
|
||||
<div class="col-md-6 mb-2">
|
||||
<div class="col-md-4 mb-2">
|
||||
<label>Nama</label>
|
||||
<select class="form-control" name="data[${colCount}][pegawai_id]" id="pegawai_id_${colCount}" required>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2">
|
||||
<label>Akses</label>
|
||||
<select class="form-control" name="data[${colCount}][akses]" id="akses_id_${colCount}" required>
|
||||
<option value="" disable>Select Choose</option>
|
||||
<option value="all">Semua Akses</option>
|
||||
<option value="unit">By Unit Akses</option>
|
||||
<div class="col-12 col-md-2">
|
||||
<label class="form-label mb-1 d-block">Akses</label>
|
||||
<div class="d-flex flex-wrap gap-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio"
|
||||
name="data[${colCount}][akses]" id="akses_all_${colCount}" value="all" checked
|
||||
onchange="toggleUnitAkses(${colCount})">
|
||||
<label class="form-check-label" for="akses_all_${colCount}">
|
||||
Semua Akses
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio"
|
||||
name="data[${colCount}][akses]" id="akses_unit_${colCount}" value="unit"
|
||||
onchange="toggleUnitAkses(${colCount})">
|
||||
<label class="form-check-label" for="akses_unit_${colCount}">
|
||||
By Unit Akses
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<small class="text-muted">Pilih salah satu.</small>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2 d-none" id="unit_akses_wrapper_${colCount}">
|
||||
<label>Unit Kerja</label>
|
||||
<select class="form-control" name="data[${colCount}][unit_akses][]" id="unit_akses_${colCount}" multiple>
|
||||
</select>
|
||||
<small class="text-muted">Bisa pilih lebih dari satu.</small>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="button" class="btn btn-danger mt-3 me-2" onclick="removeCol(${colCount})"><i class="fa-solid fa-trash"></i></button>
|
||||
@ -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()
|
||||
}
|
||||
|
||||
|
||||
@ -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){
|
||||
|
||||
@ -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 })
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
307
public/js/pendingFile/index.js
Normal file
307
public/js/pendingFile/index.js
Normal file
@ -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 = `
|
||||
<div class="d-flex gap-1">
|
||||
<button class="btn btn-sm btn-success" onclick="approvePending('${item.file_directory_id}', '${item.fileName || ''}')">
|
||||
<i class="fa-solid fa-check"></i>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-danger" onclick="rejectPending('${item.file_directory_id}', '${item.fileName || ''}')">
|
||||
<i class="fa-solid fa-xmark"></i>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
return `
|
||||
<tr>
|
||||
<td>${aksi}</td>
|
||||
<td>${item.no_dokumen || '-'}</td>
|
||||
<td><a href="#" class="file-link"
|
||||
data-file="${item.file}"
|
||||
data-fileName="${item.fileName}"
|
||||
data-id="${item.file_directory_id}"
|
||||
data-no_dokumen="${item.no_dokumen || '-'}"
|
||||
data-tanggal_terbit="${item.tanggal_terbit || '-'}"
|
||||
data-permission_file="${item.permission_file || '-'}">${item.fileName}</a></td>
|
||||
<td>${item.folder || '-'}</td>
|
||||
<td>${item.part || '-'}</td>
|
||||
<td class="text-nowrap">${tanggal}</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
|
||||
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 += `<button class="btn btn-outline-secondary btn-sm" data-page="prev" ${tableState.page === 1 ? 'disabled' : ''}>‹</button>`;
|
||||
for (let i = start; i <= end; i++) {
|
||||
buttons += `<button class="btn btn-sm ${i === tableState.page ? 'btn-primary' : 'btn-outline-secondary'}" data-page="${i}">${i}</button>`;
|
||||
}
|
||||
buttons += `<button class="btn btn-outline-secondary btn-sm" data-page="next" ${tableState.page === totalPages ? 'disabled' : ''}>›</button>`;
|
||||
|
||||
paginationEl.innerHTML = `
|
||||
<div class="d-flex align-items-center gap-2 flex-wrap">
|
||||
<div class="btn-group" role="group">${buttons}</div>
|
||||
<span class="small text-muted">Halaman ${tableState.page} dari ${totalPages}</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
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 = `
|
||||
<tr>
|
||||
<td colspan="4" class="text-center text-muted py-4">
|
||||
Tidak ada data
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
} 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 = `<iframe src="/file-preview/${idDirectory}" width="100%" height="500px" style="border:none;"></iframe>`;
|
||||
$("#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';
|
||||
}
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
<!-- Modal Header -->
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5">Aksi</h1>
|
||||
<h1 class="modal-title fs-5">Tambah Akses</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
@ -13,25 +13,51 @@
|
||||
@csrf
|
||||
<div class="modal-body">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-2">
|
||||
<label>Nama</label>
|
||||
<div class="border rounded-3 p-3 mb-2">
|
||||
<div class="row g-3 align-items-end">
|
||||
<div class="col-md-4 mb-2">
|
||||
<label class="form-label">Nama</label>
|
||||
<select class="form-control" name="data[0][pegawai_id]" id="pegawai_id_0" required>
|
||||
</select>
|
||||
<small class="text-muted">Cari nama pegawai.</small>
|
||||
</div>
|
||||
<div class="col-md-6 mb-2">
|
||||
<label>Akses</label>
|
||||
<select class="form-control" name="data[0][akses]" id="akses_id_0" required>
|
||||
<option value="" disable>Select Choose</option>
|
||||
<option value="all">Semua Akses</option>
|
||||
<option value="unit">By Unit Akses</option>
|
||||
<div class="col-12 col-md-4">
|
||||
<label class="form-label mb-1 d-block">Akses</label>
|
||||
|
||||
<div class="d-flex flex-wrap gap-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio"
|
||||
name="data[0][akses]" id="akses_all_0" value="all" checked
|
||||
onchange="toggleUnitAkses(0)">
|
||||
<label class="form-check-label" for="akses_all_0">
|
||||
Semua Akses
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio"
|
||||
name="data[0][akses]" id="akses_unit_0" value="unit"
|
||||
onchange="toggleUnitAkses(0)">
|
||||
<label class="form-check-label" for="akses_unit_0">
|
||||
By Unit Akses
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<small class="text-muted">Pilih salah satu.</small>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2 d-none" id="unit_akses_wrapper_0">
|
||||
<label class="form-label">Unit Kerja</label>
|
||||
<select class="form-control" name="data[0][unit_akses][]" id="unit_akses_0" multiple>
|
||||
</select>
|
||||
<small class="text-muted">Bisa pilih lebih dari satu.</small>
|
||||
</div>
|
||||
</div>
|
||||
<div id="col_add_akses"></div>
|
||||
<button type="button" class="btn btn-outline-primary btn-sm mt-2" onclick="addForm()">
|
||||
+ Tambah Form
|
||||
</button>
|
||||
+ Tambah Form
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
<!-- Modal Header -->
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5">Aksi</h1>
|
||||
<h1 class="modal-title fs-5">Edit Akses</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
@ -14,20 +14,43 @@
|
||||
@method('PUT')
|
||||
<div class="modal-body">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-6 mb-2">
|
||||
<label>Nama</label>
|
||||
<select class="form-control" name="pegawai_id" id="pegawai_id_edit" required>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6 mb-2">
|
||||
<label>Akses</label>
|
||||
<select class="form-control" name="akses" id="akses_id_edit" required>
|
||||
<option value="" disable>Select Choose</option>
|
||||
<option value="all">Semua Akses</option>
|
||||
<option value="unit">By Unit Akses</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="border rounded-3 p-3">
|
||||
<div class="row g-3 align-items-end">
|
||||
<div class="col-md-4 mb-2">
|
||||
<label class="form-label">Nama</label>
|
||||
<select class="form-control" name="pegawai_id" id="pegawai_id_edit" required>
|
||||
</select>
|
||||
<small class="text-muted">Cari nama pegawai.</small>
|
||||
</div>
|
||||
<div class="col-12 col-md-2">
|
||||
<label class="form-label mb-1 d-block">Akses</label>
|
||||
<div class="d-flex flex-wrap gap-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio"
|
||||
name="akses" id="akses_all_edit" value="all"
|
||||
onchange="toggleUnitAksesEdit()">
|
||||
<label class="form-check-label" for="akses_all_edit">
|
||||
Semua Akses
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio"
|
||||
name="akses" id="akses_unit_edit" value="unit"
|
||||
onchange="toggleUnitAksesEdit()">
|
||||
<label class="form-check-label" for="akses_unit_edit">
|
||||
By Unit Akses
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<small class="text-muted">Pilih salah satu.</small>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 d-none" id="unit_akses_wrapper_edit">
|
||||
<label class="form-label">Unit Kerja</label>
|
||||
<select class="form-control" name="unit_akses[]" id="unit_akses_edit" multiple>
|
||||
</select>
|
||||
<small class="text-muted">Bisa pilih lebih dari satu.</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -67,13 +67,13 @@
|
||||
<div class="row g-3 align-items-end">
|
||||
<div class="col-md-4">
|
||||
<label for="unit_kerja" class="form-label fw-semibold text-muted small">Unit Kerja</label>
|
||||
<select class="form-control unit_kerja" id="unit_kerja"{{ ($allAkses && ($allAkses->all_akses || $allAkses->unit_akses)) ? '' : 'disabled' }}>
|
||||
<select class="form-control unit_kerja" id="unit_kerja">
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label for="sub_unit_kerja" class="form-label fw-semibold text-muted small">Sub Unit Kerja</label>
|
||||
<select class="form-control sub_unit_kerja" id="sub_unit_kerja" @if($allAkses && ($allAkses->all_akses || $allAkses->unit_akses)) multiple="multiple" @else disabled @endif>
|
||||
<select class="form-control sub_unit_kerja" id="sub_unit_kerja" multiple="multiple">
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@ -265,19 +265,6 @@
|
||||
|
||||
}
|
||||
|
||||
// $("#download-file").off('click').on('click', function(){
|
||||
// if(currentFile){
|
||||
// let link = document.createElement('a');
|
||||
// link.href = 'file/' + currentFile; // alamat file
|
||||
// link.download = currentFile.split('/').pop(); // nama file otomatis
|
||||
// document.body.appendChild(link);
|
||||
// link.click();
|
||||
// document.body.removeChild(link);
|
||||
// }else{
|
||||
// console.error('error');
|
||||
|
||||
// }
|
||||
// })
|
||||
});
|
||||
|
||||
|
||||
|
||||
@ -38,7 +38,8 @@
|
||||
<tr>
|
||||
<th style="width:5%;" class="text-center">#</th>
|
||||
<th style="width:30%;">Unit</th>
|
||||
<th style="width:50%;">Folder</th>
|
||||
<th style="width:30%;">Sub Unit</th>
|
||||
<th style="width:20%;">Folder</th>
|
||||
<th style="width:15%;" class="text-center">Jumlah</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -102,6 +103,7 @@ function fetchRecap(){
|
||||
<tr>
|
||||
${i === 0 ? `<td rowspan="${row.data.length}" class="text-center align-middle fw-semibold">${idx+1}</td>` : ''}
|
||||
${i === 0 ? `<td rowspan="${row.data.length}" class="fw-semibold">${row.unit || '-'}</td>` : ''}
|
||||
<td>${f.subUnit || '-'}</td>
|
||||
<td>${f.folder || '-'}</td>
|
||||
<td class="text-center fw-bold">${f.count || 0}</td>
|
||||
</tr>
|
||||
|
||||
@ -272,11 +272,11 @@
|
||||
width: '100%',
|
||||
});
|
||||
|
||||
// --- isi default unit kerja ---
|
||||
if(authUnitKerja){
|
||||
let option = new Option(authUnitKerja.name, authUnitKerja.id, true, true);
|
||||
$('.unit_kerja').append(option).trigger('change');
|
||||
}
|
||||
// // --- isi default unit kerja ---
|
||||
// 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){
|
||||
|
||||
@ -18,13 +18,13 @@
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<a class="sidebar-link" href="/" aria-expanded="false">
|
||||
<i class="ti ti-atom"></i>
|
||||
<i class="ti ti-dashboard"></i>
|
||||
<span class="hide-menu">Dashboard</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<a class="sidebar-link" href="/new" aria-expanded="false">
|
||||
<i class="ti ti-atom"></i>
|
||||
<i class="ti ti-layout-dashboard"></i>
|
||||
<span class="hide-menu">Dashboard V2</span>
|
||||
</a>
|
||||
</li>
|
||||
@ -59,7 +59,7 @@
|
||||
href="/akses" aria-expanded="false">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<span class="d-flex">
|
||||
<i class="ti ti-layout-grid"></i>
|
||||
<i class="ti ti-lock-access"></i>
|
||||
</span>
|
||||
<span class="hide-menu">Akses</span>
|
||||
</div>
|
||||
@ -71,9 +71,9 @@
|
||||
href="/log-activity" aria-expanded="false">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<span class="d-flex">
|
||||
<i class="ti ti-layout-grid"></i>
|
||||
<i class="ti ti-activity"></i>
|
||||
</span>
|
||||
<span class="hide-menu">Log Aktivity</span>
|
||||
<span class="hide-menu">Log Aktivitas</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
@ -83,15 +83,54 @@
|
||||
href="/recap" aria-expanded="false">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<span class="d-flex">
|
||||
<i class="ti ti-layout-grid"></i>
|
||||
<i class="ti ti-report-analytics"></i>
|
||||
</span>
|
||||
<span class="hide-menu">Data Rekap</span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="sidebar-item">
|
||||
<a class="sidebar-link d-flex align-items-center justify-content-between"
|
||||
href="/pending-file" aria-expanded="false">
|
||||
|
||||
<!-- Left -->
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<i class="ti ti-clock sidebar-icon"></i>
|
||||
<span class="hide-menu">Persetujuan</span>
|
||||
</div>
|
||||
<!-- Right Badge -->
|
||||
<span class="badge bg-danger rounded-pill sidebar-badge" id="pendingCountBadge">
|
||||
0
|
||||
</span>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
<!-- End Sidebar navigation -->
|
||||
</div>
|
||||
<!-- End Sidebar scroll-->
|
||||
</aside>
|
||||
<script>
|
||||
function countData(){
|
||||
const badge = document.getElementById('pendingCountBadge');
|
||||
if (!badge) return;
|
||||
fetch('/data/count-pending')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
const count = data?.count ?? 0;
|
||||
badge.textContent = count;
|
||||
if (count <= 0) {
|
||||
badge.classList.add('d-none');
|
||||
} else {
|
||||
badge.classList.remove('d-none');
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
badge.classList.add('d-none');
|
||||
});
|
||||
}
|
||||
countData();
|
||||
</script>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header d-flex align-items-center justify-content-between">
|
||||
<h4 class="mb-0">Log Activity</h4>
|
||||
<h4 class="mb-0">Log Aktivitas</h4>
|
||||
</div>
|
||||
<div class="card-body p-3">
|
||||
<div class="d-flex flex-column flex-md-row align-items-md-center gap-2 mb-3 flex-wrap">
|
||||
|
||||
68
resources/views/pendingFile/index.blade.php
Normal file
68
resources/views/pendingFile/index.blade.php
Normal file
@ -0,0 +1,68 @@
|
||||
@extends('layout.main')
|
||||
@section('body_main')
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header d-flex align-items-center justify-content-between">
|
||||
<h4 class="mb-0">Data Pending</h4>
|
||||
</div>
|
||||
<div class="card-body p-3">
|
||||
<div class="d-flex flex-column flex-md-row align-items-md-center gap-2 mb-3 flex-wrap">
|
||||
<div class="input-group input-group-sm flex-grow-1" style="max-width:320px;">
|
||||
<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 / nomor dokumen"
|
||||
oninput="debouncedTableSearch(this.value)">
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<label class="small mb-0 text-muted">Mulai</label>
|
||||
<input type="date" id="startDate" class="form-control form-control-sm" onchange="applyDateFilter()">
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<label class="small mb-0 text-muted">Selesai</label>
|
||||
<input type="date" id="endDate" class="form-control form-control-sm" onchange="applyDateFilter()">
|
||||
</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>
|
||||
<button class="btn btn-outline-secondary btn-sm" onclick="refreshLog()">
|
||||
<i class="fa fa-rotate"></i> Refresh
|
||||
</button>
|
||||
<div class="small text-muted ms-md-auto" id="tableSummary"></div>
|
||||
</div>
|
||||
<div class="table-responsive" style="max-height: 55vh; overflow-y:auto;">
|
||||
<table class="table table-sm table-hover align-middle mb-0" id="lastUpdatedTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Aksi</th>
|
||||
<th>No Dokumen</th>
|
||||
<th>File</th>
|
||||
<th>Folder</th>
|
||||
<th>Unit/Sub Unit</th>
|
||||
<th>Tanggal</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tablePendingFile">
|
||||
<!-- data dari fetch masuk sini -->
|
||||
</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>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@include('pendingFile.modal.view')
|
||||
<script src="{{ ver('/js/pendingFile/index.js') }}"></script>
|
||||
@endsection
|
||||
58
resources/views/pendingFile/modal/view.blade.php
Normal file
58
resources/views/pendingFile/modal/view.blade.php
Normal file
@ -0,0 +1,58 @@
|
||||
<!-- Modal Preview -->
|
||||
<div class="modal fade" id="previewModal" tabindex="-1" aria-labelledby="previewModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
|
||||
<div class="modal-content">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="modal-header">
|
||||
<h6 class="modal-title" id="previewModalLabel">
|
||||
📄 Preview <strong id="confirm_preview_file"></strong>
|
||||
</h6>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
|
||||
<!-- Body -->
|
||||
<div class="modal-body p-2" style="min-height:250px; max-height:70vh; overflow:auto;">
|
||||
<div id="file-preview"
|
||||
class="text-center text-muted d-flex justify-content-center align-items-center"
|
||||
style="height:100%;">
|
||||
<p>📂 Pilih file untuk melihat preview</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="modal-footer d-flex justify-content-between align-items-center">
|
||||
|
||||
<div class="small text-muted">
|
||||
<span class="me-3">
|
||||
Nomor Dokumen:
|
||||
<strong id="confirm-upload-dokumen" class="text-dark">-</strong>
|
||||
</span>
|
||||
|
||||
<span class="me-3">
|
||||
Tanggal Terbit:
|
||||
<strong id="confirm-time-dokumen" class="text-dark">-</strong>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
Akses Dokumen:
|
||||
<span id="confirm-permission" class="badge bg-secondary">-</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- Button -->
|
||||
<div class="d-flex gap-2">
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" id="btn-view-full">
|
||||
Lihat Full
|
||||
</button>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">
|
||||
Tutup
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -40,6 +40,12 @@ Route::middleware(['auth'])->group(function(){
|
||||
|
||||
Route::get('/recap', [DashboardController::class, 'recapView']);
|
||||
Route::get('/data/recap', [DashboardController::class, 'recapData']);
|
||||
|
||||
Route::get('/pending-file', [DashboardController::class, 'pendingFile']);
|
||||
Route::get('/datatable/pending-file', [DashboardController::class, 'dataPendingFile']);
|
||||
Route::post('/pending-file/{id}/approve', [DashboardController::class, 'approvePendingFile']);
|
||||
Route::post('/pending-file/{id}/reject', [DashboardController::class, 'rejectPendingFile']);
|
||||
Route::get('/data/count-pending', [DashboardController::class, 'countDataPending']);
|
||||
});
|
||||
|
||||
Route::get('/login', [AuthController::class, 'index'])->name('login');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user