progress rapiin dashboard
This commit is contained in:
parent
8654e70e9a
commit
fc9f6d280b
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
|||||||
|
|
||||||
use App\Models\AksesFile;
|
use App\Models\AksesFile;
|
||||||
use App\Models\FileDirectory;
|
use App\Models\FileDirectory;
|
||||||
|
use App\Models\LogActivity;
|
||||||
use App\Models\MasterKategori;
|
use App\Models\MasterKategori;
|
||||||
use App\Models\MasterKlasifikasi;
|
use App\Models\MasterKlasifikasi;
|
||||||
use App\Models\SubUnitKerja;
|
use App\Models\SubUnitKerja;
|
||||||
@ -12,6 +13,7 @@ use Illuminate\Http\Request;
|
|||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use setasign\Fpdi\Fpdi;
|
||||||
use ZipArchive;
|
use ZipArchive;
|
||||||
|
|
||||||
use function PHPUnit\Framework\isEmpty;
|
use function PHPUnit\Framework\isEmpty;
|
||||||
@ -182,32 +184,7 @@ class DashboardController extends Controller
|
|||||||
|
|
||||||
public function OptionUnitKerja(){
|
public function OptionUnitKerja(){
|
||||||
$q = request()->get('q');
|
$q = request()->get('q');
|
||||||
$authPegawai = auth()->user()?->dataUser;
|
|
||||||
|
|
||||||
$authUnitKerja = optional($authPegawai->mappingUnitKerjaPegawai[0] ?? null)->objectunitkerjapegawaifk;
|
|
||||||
$authSubUnitKerja = optional($authPegawai->mappingUnitKerjaPegawai[0] ?? null)->objectsubunitkerjapegawaifk;
|
|
||||||
|
|
||||||
$aksesFile = AksesFile::where('pegawai_id', $authPegawai->id)
|
|
||||||
->where('statusenabled', true)
|
|
||||||
->first();
|
|
||||||
$query = UnitKerja::where('statusenabled', true);
|
$query = UnitKerja::where('statusenabled', true);
|
||||||
if($aksesFile){
|
|
||||||
if($aksesFile->all_akses){
|
|
||||||
|
|
||||||
}elseif($aksesFile->unit_akses){
|
|
||||||
$query->where('id', $aksesFile->unit_akses);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
$data= $query->where('id', $authUnitKerja)
|
|
||||||
->with(['subUnitKerja' => function($query) use($authSubUnitKerja){
|
|
||||||
$query->where('id', $authSubUnitKerja);
|
|
||||||
}])->select('id', 'name')->get();
|
|
||||||
|
|
||||||
return response()->json([
|
|
||||||
'status' => true,
|
|
||||||
'data' => $data
|
|
||||||
], 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = $query->when($q, function ($query, $q){
|
$data = $query->when($q, function ($query, $q){
|
||||||
$query->where('name', 'ILIKE', '%' .$q . '%');
|
$query->where('name', 'ILIKE', '%' .$q . '%');
|
||||||
@ -220,30 +197,60 @@ class DashboardController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function deleteFile(string $id){
|
public function deleteFile(string $id){
|
||||||
$data = FileDirectory::where('file_directory_id', $id)->first();
|
DB::connection('dbDirectory')->beginTransaction();
|
||||||
if(!$data){
|
try {
|
||||||
return response()->json([
|
$data = FileDirectory::where('file_directory_id', $id)->first();
|
||||||
'success' => false,
|
if(!$data){
|
||||||
'message' => 'File tidak ditemukan'
|
return response()->json([
|
||||||
]);
|
'success' => false,
|
||||||
}
|
'message' => 'File tidak ditemukan'
|
||||||
$oldPath= public_path('file/' . $data->file);
|
]);
|
||||||
$fileInfo = pathinfo($data->file);
|
|
||||||
$newFileName = $fileInfo['filename'] . '_deleted.' . $fileInfo['extension'];
|
|
||||||
$newPath = public_path('file/' . $fileInfo['dirname'] . '/' . $newFileName);
|
|
||||||
if (file_exists($oldPath)) {
|
|
||||||
// pastikan folder tujuan ada
|
|
||||||
if (!is_dir(dirname($newPath))) {
|
|
||||||
mkdir(dirname($newPath), 0777, true);
|
|
||||||
}
|
|
||||||
rename($oldPath, $newPath);
|
|
||||||
}
|
}
|
||||||
|
$oldPath= public_path('file/' . $data->file);
|
||||||
|
$fileInfo = pathinfo($data->file);
|
||||||
|
$newFileName = $fileInfo['filename'] . '_deleted.' . $fileInfo['extension'];
|
||||||
|
$newPath = public_path('file/' . $fileInfo['dirname'] . '/' . $newFileName);
|
||||||
|
if (file_exists($oldPath)) {
|
||||||
|
// pastikan folder tujuan ada
|
||||||
|
if (!is_dir(dirname($newPath))) {
|
||||||
|
mkdir(dirname($newPath), 0777, true);
|
||||||
|
}
|
||||||
|
rename($oldPath, $newPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data->update(['statusenabled' => false, 'file' => $fileInfo['dirname'].'/'. $newFileName]);
|
||||||
|
|
||||||
|
$payloadLog = [
|
||||||
|
'file_directory_id' => $data->file_directory_id,
|
||||||
|
'pegawai_id_entry' => $data->pegawai_id_entry,
|
||||||
|
'pegawai_nama_entry' => $data->pegawai_nama_entry,
|
||||||
|
'entry_at' => $data->entry_at,
|
||||||
|
'action_type' => 'Hapus 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);
|
||||||
|
|
||||||
|
DB::connection('dbDirectory')->commit();
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Berhasil menghapus data'
|
||||||
|
]);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
DB::connection('dbDirectory')->rollBack();
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Gagal menghapus data'
|
||||||
|
]);
|
||||||
|
//throw $th;
|
||||||
|
}
|
||||||
|
|
||||||
$data->update(['statusenabled' => false, 'file' => $fileInfo['dirname'].'/'. $newFileName]);
|
|
||||||
return response()->json([
|
|
||||||
'success' => true,
|
|
||||||
'message' => 'Berhasil menghapus data'
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function optionSubUnitKerja(string $id){
|
public function optionSubUnitKerja(string $id){
|
||||||
@ -349,8 +356,15 @@ class DashboardController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function dashboardVersion2(){
|
public function dashboardVersion2(){
|
||||||
|
$katDok = MasterKategori::where('statusenabled', true)->select('master_kategori_directory_id', 'nama_kategori_directory')->get();
|
||||||
|
$authMapping = auth()->user()?->dataUser?->mappingUnitKerjaPegawai[0];
|
||||||
|
$authUnitKerja = $authMapping->objectunitkerjapegawaifk;
|
||||||
|
$authSubUnitKerja = $authMapping->objectsubunitkerjapegawaifk;
|
||||||
$data = [
|
$data = [
|
||||||
'title' => 'Dashboard',
|
'title' => 'Dashboard',
|
||||||
|
'katDok' => $katDok,
|
||||||
|
'authUnitKerja' => $authUnitKerja,
|
||||||
|
'authSubUnitKerja' => $authSubUnitKerja,
|
||||||
];
|
];
|
||||||
return view('dashboardV2.index', $data);
|
return view('dashboardV2.index', $data);
|
||||||
}
|
}
|
||||||
@ -372,4 +386,148 @@ class DashboardController extends Controller
|
|||||||
];
|
];
|
||||||
return response()->json($payload);
|
return response()->json($payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function storeVersion2(){
|
||||||
|
DB::connection('dbDirectory')->beginTransaction();
|
||||||
|
try {
|
||||||
|
$datas = request('data');
|
||||||
|
foreach ($datas as $data) {
|
||||||
|
list($id_unit_kerja, $nama_unit_kerja) = explode('/', $data['id_unit_kerja'],2);
|
||||||
|
list($id_sub_unit_kerja, $nama_sub_unit_kerja) = explode('/', $data['id_sub_unit_kerja'],2);
|
||||||
|
list($master_kategori_directory_id, $nama_kategori) = explode('/', $data['master_kategori_directory_id'],2);
|
||||||
|
$payload = [
|
||||||
|
'id_unit_kerja' => $id_unit_kerja,
|
||||||
|
'id_sub_unit_kerja' => $id_sub_unit_kerja,
|
||||||
|
'master_kategori_directory_id' => $master_kategori_directory_id,
|
||||||
|
'pegawai_id_entry' => auth()->user()->dataUser->id ?? 1,
|
||||||
|
'pegawai_nama_entry' => auth()->user()->dataUser->namalengkap ?? null,
|
||||||
|
'tanggal_terbit' => $data['date_active'] ?? null,
|
||||||
|
'no_dokumen' => $data['no_dokumen'] ?? null,
|
||||||
|
'permission_file' => $data['is_permission'] === "1" ? true : false,
|
||||||
|
];
|
||||||
|
if(!empty($data['file'])){
|
||||||
|
$file = $data['file'];
|
||||||
|
$imageName = $file->getClientOriginalName();
|
||||||
|
$path = "{$nama_unit_kerja}/{$nama_sub_unit_kerja}/{$nama_kategori}";
|
||||||
|
$file->storeAs($path, $imageName, 'file_directory');
|
||||||
|
$payload['file'] =$path .'/' .$imageName;
|
||||||
|
}
|
||||||
|
$fd = FileDirectory::create($payload);
|
||||||
|
$payloadLog = [
|
||||||
|
'file_directory_id' => $fd->file_directory_id,
|
||||||
|
'pegawai_id_entry' => $fd->pegawai_id_entry,
|
||||||
|
'pegawai_nama_entry' => $fd->pegawai_nama_entry,
|
||||||
|
'entry_at' => $fd->entry_at,
|
||||||
|
'action_type' => 'Upload Dokumen',
|
||||||
|
'statusenabled' => true,
|
||||||
|
'mod_change' => $fd->entry_at,
|
||||||
|
'id_unit_kerja' => $fd->id_unit_kerja,
|
||||||
|
'id_sub_unit_kerja' => $fd->id_sub_unit_kerja,
|
||||||
|
'file' => $fd->file,
|
||||||
|
'tanggal_terbit' => $fd->tanggal_terbit,
|
||||||
|
'no_dokumen' => $fd->no_dokumen,
|
||||||
|
'permission_file' => $fd->permission_file,
|
||||||
|
];
|
||||||
|
LogActivity::create($payloadLog);
|
||||||
|
}
|
||||||
|
DB::connection('dbDirectory')->commit();
|
||||||
|
return response()->json([
|
||||||
|
'status' => true,
|
||||||
|
'message' => 'Data berhasil disimpan'
|
||||||
|
], 200);
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
DB::connection('dbDirectory')->rollback();
|
||||||
|
return response()->json([
|
||||||
|
'status' => false,
|
||||||
|
'message' => $th->getMessage()
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dataPdf($fileDirectoryId)
|
||||||
|
{
|
||||||
|
$data = FileDirectory::where('file_directory_id', $fileDirectoryId)->first();
|
||||||
|
|
||||||
|
$filePath = public_path('file/' . $data->file);
|
||||||
|
|
||||||
|
if (!file_exists($filePath)) {
|
||||||
|
abort(404, 'PDF Tidak ditemukan');
|
||||||
|
}
|
||||||
|
|
||||||
|
$stampFile = public_path('assets/copy.png');
|
||||||
|
if (!file_exists($stampFile)) {
|
||||||
|
// kalau watermark tidak ada, tampilkan file asli
|
||||||
|
return response()->file($filePath, [
|
||||||
|
'Content-Type' => 'application/pdf',
|
||||||
|
'Content-Disposition' => 'inline; filename="preview.pdf"',
|
||||||
|
'Cache-Control' => 'no-store, no-cache, must-revalidate, max-age=0',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$tempConverted = storage_path('app/temp/' . uniqid('conv_') . '.pdf');
|
||||||
|
|
||||||
|
try {
|
||||||
|
// coba watermark langsung
|
||||||
|
return $this->watermarkCenterAndStream($filePath, $stampFile);
|
||||||
|
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
// kalau gagal (PDF modern) -> convert dulu
|
||||||
|
// dd($e);
|
||||||
|
$this->convertWithGhostscript($filePath, $tempConverted);
|
||||||
|
|
||||||
|
$resp = $this->watermarkCenterAndStream($tempConverted, $stampFile);
|
||||||
|
|
||||||
|
@unlink($tempConverted);
|
||||||
|
return $resp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function watermarkCenterAndStream(string $pdfPath, string $stampFile)
|
||||||
|
{
|
||||||
|
$pdf = new Fpdi();
|
||||||
|
$pageCount = $pdf->setSourceFile($pdfPath);
|
||||||
|
|
||||||
|
for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
|
||||||
|
$tplId = $pdf->importPage($pageNo);
|
||||||
|
$size = $pdf->getTemplateSize($tplId);
|
||||||
|
|
||||||
|
$pdf->AddPage($size['orientation'], [$size['width'], $size['height']]);
|
||||||
|
$pdf->useTemplate($tplId);
|
||||||
|
|
||||||
|
// watermark tengah (skala adaptif)
|
||||||
|
$stampW = $size['width'] * 0.60;
|
||||||
|
$stampH = $stampW * 0.75; // sesuaikan rasio gambar kalau perlu
|
||||||
|
|
||||||
|
$x = ($size['width'] - $stampW) / 2;
|
||||||
|
$y = ($size['height'] - $stampH) / 2;
|
||||||
|
|
||||||
|
$pdf->Image($stampFile, $x, $y, $stampW, $stampH);
|
||||||
|
}
|
||||||
|
|
||||||
|
$output = $pdf->Output('S');
|
||||||
|
|
||||||
|
return response($output, 200, [
|
||||||
|
'Content-Type' => 'application/pdf',
|
||||||
|
'Content-Disposition' => 'inline; filename="preview.pdf"',
|
||||||
|
'Cache-Control' => 'no-store, no-cache, must-revalidate, max-age=0',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function convertWithGhostscript(string $inputPdf, string $outputPdf): void
|
||||||
|
{
|
||||||
|
$gs = config('services.ghostscript.path');
|
||||||
|
|
||||||
|
if (!$gs || !file_exists($gs)) {
|
||||||
|
throw new \RuntimeException('Ghostscript tidak ditemukan. Cek GHOSTSCRIPT_PATH di .env');
|
||||||
|
}
|
||||||
|
|
||||||
|
$cmd = "\"{$gs}\" -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress "
|
||||||
|
. "-dNOPAUSE -dBATCH -dQUIET -sOutputFile=\"{$outputPdf}\" \"{$inputPdf}\"";
|
||||||
|
|
||||||
|
exec($cmd, $out, $code);
|
||||||
|
|
||||||
|
if ($code !== 0 || !file_exists($outputPdf)) {
|
||||||
|
throw new \RuntimeException('Convert Ghostscript gagal (code=' . $code . ')');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,10 +12,4 @@ class FileDirectory extends Model
|
|||||||
protected $primaryKey = 'file_directory_id';
|
protected $primaryKey = 'file_directory_id';
|
||||||
protected $guarded = ['file_directory_id'];
|
protected $guarded = ['file_directory_id'];
|
||||||
|
|
||||||
// protected $with = ['klasifikasi'];
|
|
||||||
|
|
||||||
// // public function klasifikasi(){
|
|
||||||
// // return $this->belongsTo(MasterKlasifikasi::class, 'master_klasifikasi_directory_id', 'master_klasifikasi_directory_id');
|
|
||||||
// // }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
14
app/Models/LogActivity.php
Normal file
14
app/Models/LogActivity.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class LogActivity extends Model
|
||||||
|
{
|
||||||
|
protected $connection = 'dbDirectory';
|
||||||
|
protected $table = 'logging.log_activity_file_directory';
|
||||||
|
public $timestamps = false;
|
||||||
|
protected $primaryKey = 'id';
|
||||||
|
protected $guarded = ['id'];
|
||||||
|
}
|
||||||
@ -8,7 +8,9 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2",
|
"php": "^8.2",
|
||||||
"laravel/framework": "^12.0",
|
"laravel/framework": "^12.0",
|
||||||
"laravel/tinker": "^2.10.1"
|
"laravel/tinker": "^2.10.1",
|
||||||
|
"setasign/fpdf": "^1.8",
|
||||||
|
"setasign/fpdi": "^2.6"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"fakerphp/faker": "^1.23",
|
"fakerphp/faker": "^1.23",
|
||||||
|
|||||||
120
composer.lock
generated
120
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "c514d8f7b9fc5970bdd94287905ef584",
|
"content-hash": "26cb6fff423ee0edff5bec050b76b10f",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "brick/math",
|
"name": "brick/math",
|
||||||
@ -3274,6 +3274,124 @@
|
|||||||
},
|
},
|
||||||
"time": "2025-06-25T14:20:11+00:00"
|
"time": "2025-06-25T14:20:11+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "setasign/fpdf",
|
||||||
|
"version": "1.8.6",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Setasign/FPDF.git",
|
||||||
|
"reference": "0838e0ee4925716fcbbc50ad9e1799b5edfae0a0"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Setasign/FPDF/zipball/0838e0ee4925716fcbbc50ad9e1799b5edfae0a0",
|
||||||
|
"reference": "0838e0ee4925716fcbbc50ad9e1799b5edfae0a0",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-gd": "*",
|
||||||
|
"ext-zlib": "*"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"classmap": [
|
||||||
|
"fpdf.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Olivier Plathey",
|
||||||
|
"email": "oliver@fpdf.org",
|
||||||
|
"homepage": "http://fpdf.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "FPDF is a PHP class which allows to generate PDF files with pure PHP. F from FPDF stands for Free: you may use it for any kind of usage and modify it to suit your needs.",
|
||||||
|
"homepage": "http://www.fpdf.org",
|
||||||
|
"keywords": [
|
||||||
|
"fpdf",
|
||||||
|
"pdf"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/Setasign/FPDF/tree/1.8.6"
|
||||||
|
},
|
||||||
|
"time": "2023-06-26T14:44:25+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "setasign/fpdi",
|
||||||
|
"version": "v2.6.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Setasign/FPDI.git",
|
||||||
|
"reference": "4b53852fde2734ec6a07e458a085db627c60eada"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Setasign/FPDI/zipball/4b53852fde2734ec6a07e458a085db627c60eada",
|
||||||
|
"reference": "4b53852fde2734ec6a07e458a085db627c60eada",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-zlib": "*",
|
||||||
|
"php": "^7.1 || ^8.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"setasign/tfpdf": "<1.31"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^7",
|
||||||
|
"setasign/fpdf": "~1.8.6",
|
||||||
|
"setasign/tfpdf": "~1.33",
|
||||||
|
"squizlabs/php_codesniffer": "^3.5",
|
||||||
|
"tecnickcom/tcpdf": "^6.8"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"setasign/fpdf": "FPDI will extend this class but as it is also possible to use TCPDF or tFPDF as an alternative. There's no fixed dependency configured."
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"setasign\\Fpdi\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jan Slabon",
|
||||||
|
"email": "jan.slabon@setasign.com",
|
||||||
|
"homepage": "https://www.setasign.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Maximilian Kresse",
|
||||||
|
"email": "maximilian.kresse@setasign.com",
|
||||||
|
"homepage": "https://www.setasign.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF documents and use them as templates in FPDF. Because it is also possible to use FPDI with TCPDF, there are no fixed dependencies defined. Please see suggestions for packages which evaluates the dependencies automatically.",
|
||||||
|
"homepage": "https://www.setasign.com/fpdi",
|
||||||
|
"keywords": [
|
||||||
|
"fpdf",
|
||||||
|
"fpdi",
|
||||||
|
"pdf"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/Setasign/FPDI/issues",
|
||||||
|
"source": "https://github.com/Setasign/FPDI/tree/v2.6.4"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/setasign/fpdi",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-08-05T09:57:14+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/clock",
|
"name": "symfony/clock",
|
||||||
"version": "v7.3.0",
|
"version": "v7.3.0",
|
||||||
|
|||||||
@ -34,5 +34,8 @@ return [
|
|||||||
'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'),
|
'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
'ghostscript' => [
|
||||||
|
'path' => env('GHOSTSCRIPT_PATH'),
|
||||||
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|||||||
BIN
public/assets/copy.png
Normal file
BIN
public/assets/copy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 224 KiB |
@ -40,33 +40,20 @@ function renderTree(units, katDok, keyword) {
|
|||||||
<ul class="file-tree-ul ms-2">
|
<ul class="file-tree-ul ms-2">
|
||||||
${files.map(file => {
|
${files.map(file => {
|
||||||
let fileName = file.file.split('/').pop();
|
let fileName = file.file.split('/').pop();
|
||||||
let uploadedBy = file.pegawai_nama_entry || "Unknown";
|
console.log(file);
|
||||||
let uploadedAt = new Date(file.entry_at).toLocaleString("id-ID", {
|
|
||||||
day: "2-digit",
|
|
||||||
month: "short",
|
|
||||||
year: "numeric",
|
|
||||||
hour: "2-digit",
|
|
||||||
minute: "2-digit"
|
|
||||||
});
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<li class="file-tree-li">
|
<li class="file-tree-li">
|
||||||
<div class="">
|
<div class="">
|
||||||
📄 <a href="#"
|
📄
|
||||||
class="file-link"
|
<a href="#" class="file-link"
|
||||||
data-file="${file?.file}"
|
data-file="${file?.file}"
|
||||||
data-name_file="${fileName}"
|
data-fileName="${fileName || '-'}"
|
||||||
data-upload="${uploadedBy}"
|
data-id="${file.file_directory_id}"
|
||||||
data-time="${uploadedAt}"
|
data-no_dokumen="${file.no_dokumen || '-'}"
|
||||||
data-klasifikasi="${file?.klasifikasi?.nama_klasifikasi_directory}"
|
data-tanggal_terbit="${file.tanggal_terbit || '-'}" data-permission_file="${file.permission_file || '-'}">${fileName}</a>
|
||||||
data-id="${file?.file_directory_id}"
|
|
||||||
title="Diupload oleh: ${uploadedBy} pada ${uploadedAt}">
|
|
||||||
${fileName}
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
<small class="text-muted fst-italic">
|
|
||||||
Upload by ${uploadedBy} · ${uploadedAt}
|
|
||||||
</small>
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
`;
|
`;
|
||||||
|
|||||||
@ -153,6 +153,7 @@
|
|||||||
let upload = e.target.getAttribute('data-upload');
|
let upload = e.target.getAttribute('data-upload');
|
||||||
let time = e.target.getAttribute('data-time');
|
let time = e.target.getAttribute('data-time');
|
||||||
let klasifikasiView = e.target.getAttribute('data-klasifikasi');
|
let klasifikasiView = e.target.getAttribute('data-klasifikasi');
|
||||||
|
console.log(fileUrl);
|
||||||
|
|
||||||
$("#confirm-upload-dokumen").html(upload);
|
$("#confirm-upload-dokumen").html(upload);
|
||||||
$("#confirm-time-dokumen").html(time);
|
$("#confirm-time-dokumen").html(time);
|
||||||
@ -164,17 +165,8 @@
|
|||||||
|
|
||||||
let ext = fileUrl.split('.').pop().toLowerCase();
|
let ext = fileUrl.split('.').pop().toLowerCase();
|
||||||
let previewBox = document.getElementById('file-preview');
|
let previewBox = document.getElementById('file-preview');
|
||||||
|
previewBox.innerHTML = `<iframe src="/file-preview/${idDirectory}" width="100%" height="500px" style="border:none;"></iframe>`;
|
||||||
if (['jpg','jpeg','png','gif','webp'].includes(ext)) {
|
$("#previewModal").modal('show')
|
||||||
previewBox.innerHTML = `<img src="/file/${fileUrl}" class="img-fluid rounded shadow-sm" width="100%" alt="preview">`;
|
|
||||||
} else if (ext === 'pdf') {
|
|
||||||
previewBox.innerHTML = `<iframe src="/file/${fileUrl}" width="100%" height="500px" style="border:none;"></iframe>`;
|
|
||||||
} else {
|
|
||||||
previewBox.innerHTML = `
|
|
||||||
<p class="text-muted">Tidak bisa preview file ini. Silakan download:</p>
|
|
||||||
<a href="/file/${fileUrl}" target="_blank" class="btn btn-sm btn-primary">⬇️ Download</a>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 🔥 Tampilkan modal
|
// 🔥 Tampilkan modal
|
||||||
$("#previewModal").modal("show");
|
$("#previewModal").modal("show");
|
||||||
@ -261,21 +253,21 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#download-file").off('click').on('click', function(){
|
// $("#download-file").off('click').on('click', function(){
|
||||||
if(currentFile){
|
// if(currentFile){
|
||||||
let link = document.createElement('a');
|
// let link = document.createElement('a');
|
||||||
link.href = 'file/' + currentFile; // alamat file
|
// link.href = 'file/' + currentFile; // alamat file
|
||||||
link.download = currentFile.split('/').pop(); // nama file otomatis
|
// link.download = currentFile.split('/').pop(); // nama file otomatis
|
||||||
document.body.appendChild(link);
|
// document.body.appendChild(link);
|
||||||
link.click();
|
// link.click();
|
||||||
document.body.removeChild(link);
|
// document.body.removeChild(link);
|
||||||
}else{
|
// }else{
|
||||||
console.error('error');
|
// console.error('error');
|
||||||
|
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,6 @@
|
|||||||
<div class="modal-body p-2" style="min-height:250px; max-height:70vh; overflow:auto;">
|
<div class="modal-body p-2" style="min-height:250px; max-height:70vh; overflow:auto;">
|
||||||
<div class="d-flex justify-content-end align-items-center sticky-top bg-white z-10">
|
<div class="d-flex justify-content-end align-items-center sticky-top bg-white z-10">
|
||||||
<button type="button" class="btn btn-sm btn-outline-danger mb-2 me-2" id="delete-file">🗑 Hapus</button>
|
<button type="button" class="btn btn-sm btn-outline-danger mb-2 me-2" id="delete-file">🗑 Hapus</button>
|
||||||
<button type="button" class="btn btn-sm btn-outline-primary mb-2" id="download-file">⬇ Download</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="file-preview"
|
<div id="file-preview"
|
||||||
class="text-center text-muted d-flex justify-content-center align-items-center"
|
class="text-center text-muted d-flex justify-content-center align-items-center"
|
||||||
@ -24,17 +23,38 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Footer -->
|
<!-- Footer -->
|
||||||
<div class="modal-footer d-flex justify-content-between">
|
<div class="modal-footer d-flex justify-content-between align-items-center">
|
||||||
<div>
|
|
||||||
<div class="text-black">Klasifikasi Dokumen <strong id="confirm-upload-klasifikasi"></strong></div>
|
<div class="small text-muted">
|
||||||
<div class="mt-2 text-muted fst-italic small text-black">
|
<span class="me-3">
|
||||||
Ditambahkan oleh <strong id="confirm-upload-dokumen"></strong> pada <span id="confirm-time-dokumen"></span>
|
Nomor Dokumen:
|
||||||
</div>
|
<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>
|
||||||
|
|
||||||
<button type="button" class="btn btn-sm btn-secondary" data-bs-dismiss="modal">Tutup</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,13 +3,14 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header d-flex align-items-center justify-content-between">
|
||||||
<h4 class="mb-0">Data Terakhir</h4>
|
<h4 class="mb-0">Data Terakhir</h4>
|
||||||
|
<button type="button" class="btn btn-success" data-bs-target="#modalCreateFile" data-bs-toggle="modal">Tambah File</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body p-2">
|
<div class="card-body p-2">
|
||||||
<div class="d-flex mb-3">
|
<div class="d-flex align-items-center gap-2 mb-3">
|
||||||
<input type="text" onchange="searchData(this)" class="form-control form-control-sm" placeholder="Search">
|
<input type="text" onchange="searchData(this)" class="form-control" placeholder="Search">
|
||||||
<button type="button" class="btn btn-primary ms-2">Cari</button>
|
<button type="button" class="btn btn-primary">Cari</button>
|
||||||
</div>
|
</div>
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered">
|
||||||
<thead>
|
<thead>
|
||||||
@ -28,8 +29,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@include('dashboardV2.modal.create')
|
||||||
|
@include('dashboardV2.modal.view')
|
||||||
<script>
|
<script>
|
||||||
|
const katDok = @json($katDok);
|
||||||
|
const authUnitKerja = @json(auth()->user()->dataUser?->mappingUnitKerjaPegawai[0]?->unitKerja);
|
||||||
|
const authSubUnitKerja = @json(auth()->user()->dataUser?->mappingUnitKerjaPegawai[0]->sub_unit_kerja);
|
||||||
|
const mappingUnitKerjaPegawai = @json(auth()->user()->dataUser?->mappingUnitKerjaPegawai[0]);
|
||||||
|
|
||||||
function fetchData(){
|
function fetchData(){
|
||||||
fetch(`/last-document`)
|
fetch(`/last-document`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
@ -49,6 +56,7 @@
|
|||||||
}
|
}
|
||||||
tbody.innerHTML = resData.map(item => {
|
tbody.innerHTML = resData.map(item => {
|
||||||
const fullPath = item.file;
|
const fullPath = item.file;
|
||||||
|
console.log(item);
|
||||||
|
|
||||||
const parts = fullPath.split('/');
|
const parts = fullPath.split('/');
|
||||||
|
|
||||||
@ -57,7 +65,12 @@
|
|||||||
|
|
||||||
return `
|
return `
|
||||||
<tr>
|
<tr>
|
||||||
<td>${fileName}</td>
|
<td>📄<a href="#" class="file-link"
|
||||||
|
data-file="${item.file}"
|
||||||
|
data-fileName="${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 || '-'}">${fileName}</a></td>
|
||||||
<td>${folderPath}</td>
|
<td>${folderPath}</td>
|
||||||
<td>${formatTanggal(item.entry_at)}</td>
|
<td>${formatTanggal(item.entry_at)}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -81,5 +94,365 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
fetchData()
|
fetchData()
|
||||||
|
|
||||||
|
let colCount = 1;
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('.unit_kerja').select2({
|
||||||
|
placeholder: '--- Pilih Unit Kerja ---',
|
||||||
|
allowClear: true,
|
||||||
|
width: '100%',
|
||||||
|
ajax: {
|
||||||
|
url : '/select-unit-kerja',
|
||||||
|
dataType: 'json',
|
||||||
|
delay: 250,
|
||||||
|
data: function(params){
|
||||||
|
let q = '';
|
||||||
|
if(allAkses){
|
||||||
|
q = params.term;
|
||||||
|
}else{
|
||||||
|
q = authUnitKerja?.name ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return { q };
|
||||||
|
},
|
||||||
|
processResults: function(data){
|
||||||
|
let results = data?.data.map(item => ({
|
||||||
|
id: item.id,
|
||||||
|
text: item.name
|
||||||
|
}));
|
||||||
|
return { results };
|
||||||
|
},
|
||||||
|
cache: true,
|
||||||
|
},
|
||||||
|
minimumInputLength: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.sub_unit_kerja').select2({
|
||||||
|
placeholder: '-- Pilih Sub Unit Kerja --',
|
||||||
|
allowClear: true,
|
||||||
|
width: '100%',
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- 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){
|
||||||
|
loadSubUnitKerja(initialUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
// jalankan setiap kali unit_kerja berubah
|
||||||
|
$('.unit_kerja').on('change', function(){
|
||||||
|
let idUnit = $(this).val();
|
||||||
|
if(idUnit){
|
||||||
|
loadSubUnitKerja(idUnit);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
selectOptionUnitKerjaV1(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
function loadSubUnitKerja(unitId){
|
||||||
|
$('.sub_unit_kerja').empty().append('<option value="" disabled>-- Pilih Sub Unit Kerja --</option>');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: `/select-sub-unit-kerja/${unitId}`,
|
||||||
|
method: 'GET',
|
||||||
|
success: function(response) {
|
||||||
|
if (response?.data) {
|
||||||
|
response.data.forEach(unit => {
|
||||||
|
let selected = (authSubUnitKerja && unit.id === authSubUnitKerja.objectsubunitkerjapegawaifk);
|
||||||
|
const option = new Option(unit.name, unit.id, false, selected);
|
||||||
|
$('.sub_unit_kerja').append(option);
|
||||||
|
});
|
||||||
|
$('.sub_unit_kerja').trigger('change');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function addFormV2(){
|
||||||
|
let col = $("#col_add_fileV2");
|
||||||
|
let html = '';
|
||||||
|
|
||||||
|
html += `
|
||||||
|
<div class="row g-3 align-items-start" id="col-${colCount}">
|
||||||
|
<hr class="my-3" />
|
||||||
|
<div class="col-12 d-flex justify-content-end">
|
||||||
|
<button type="button"
|
||||||
|
class="btn btn-sm btn-danger"
|
||||||
|
onclick="removeCol(${colCount})">
|
||||||
|
<i class="fa-solid fa-trash"></i> Hapus
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label fw-semibold">Unit <span class="text-danger">*</span></label>
|
||||||
|
<select class="form-select"
|
||||||
|
name="data[${colCount}][id_unit_kerja]"
|
||||||
|
id="select_id_unit_kerja_${colCount}"
|
||||||
|
required>
|
||||||
|
<option value="" disabled selected>Pilih Unit</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label fw-semibold">Sub Unit <span class="text-danger">*</span></label>
|
||||||
|
<select class="form-select"
|
||||||
|
name="data[${colCount}][id_sub_unit_kerja]"
|
||||||
|
id="select_id_sub_unit_kerja_${colCount}"
|
||||||
|
required>
|
||||||
|
<option value="" disabled selected>Pilih Sub Unit</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label fw-semibold">Kategori Dokumen <span class="text-danger">*</span></label>
|
||||||
|
<select class="form-select"
|
||||||
|
name="data[${colCount}][master_kategori_directory_id]"
|
||||||
|
id="select_kategori_${colCount}"
|
||||||
|
required>
|
||||||
|
<option value="" disabled selected>Pilih Kategori</option>
|
||||||
|
@foreach ($katDok as $kat)
|
||||||
|
<option value="{{ $kat->master_kategori_directory_id }}/{{ $kat->nama_kategori_directory }}">
|
||||||
|
{{ $kat->nama_kategori_directory }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-semibold">Nomor Dokumen</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-text">#</span>
|
||||||
|
<input type="text"
|
||||||
|
class="form-control"
|
||||||
|
name="data[${colCount}][no_dokumen]"
|
||||||
|
placeholder="Contoh: 001/RS/IT/I/2026">
|
||||||
|
</div>
|
||||||
|
<div class="form-text text-muted">Opsional, isi jika ada nomor resmi dokumen.</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label fw-semibold">Tanggal Terbit</label>
|
||||||
|
<input class="form-control"
|
||||||
|
type="date"
|
||||||
|
name="data[${colCount}][date_active]"
|
||||||
|
required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label fw-semibold">Boleh dilihat unit lain? <span class="text-danger">*</span></label>
|
||||||
|
|
||||||
|
<div class="border rounded-3 p-2 bg-light">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input"
|
||||||
|
type="radio"
|
||||||
|
name="data[${colCount}][is_permission]"
|
||||||
|
id="perm_yes_${colCount}"
|
||||||
|
value="1"
|
||||||
|
required>
|
||||||
|
<label class="form-check-label" for="perm_yes_${colCount}">Iya</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-check mt-1">
|
||||||
|
<input class="form-check-input"
|
||||||
|
type="radio"
|
||||||
|
name="data[${colCount}][is_permission]"
|
||||||
|
id="perm_no_${colCount}"
|
||||||
|
value="2"
|
||||||
|
required>
|
||||||
|
<label class="form-check-label" for="perm_no_${colCount}">Tidak</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-12">
|
||||||
|
<label for="fileUpload_${colCount}" class="form-label fw-semibold">📂 Upload Dokumen (PDF)</label>
|
||||||
|
|
||||||
|
<div class="border rounded-3 p-3 bg-white shadow-sm">
|
||||||
|
<input class="form-control"
|
||||||
|
type="file"
|
||||||
|
id="fileUpload_${colCount}"
|
||||||
|
accept=".pdf"
|
||||||
|
name="data[${colCount}][file]">
|
||||||
|
<div class="mt-2 text-success fw-semibold d-none file-name" id="fileName_${colCount}"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-text text-muted">
|
||||||
|
Format yang didukung: <b>PDF</b>.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
col.append(html)
|
||||||
|
selectOptionUnitKerjaV1(colCount)
|
||||||
|
colCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeCol(count){
|
||||||
|
$(`#col-${count}`).remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectOptionUnitKerjaV1(colCount) {
|
||||||
|
let selectUnit = $(`#select_id_unit_kerja_${colCount}`);
|
||||||
|
let selectSubUnit = $(`#select_id_sub_unit_kerja_${colCount}`);
|
||||||
|
|
||||||
|
// inisialisasi select2 untuk Unit Kerja
|
||||||
|
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+'/'+item.name,
|
||||||
|
text: item.name,
|
||||||
|
sub_units: item.sub_unit_kerja // kirim ke front
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cache: true,
|
||||||
|
},
|
||||||
|
minimumInputLength: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
selectSubUnit.select2({
|
||||||
|
placeholder: '-- Pilih Sub Unit Kerja --',
|
||||||
|
allowClear: true,
|
||||||
|
width: '100%',
|
||||||
|
dropdownParent: selectSubUnit.parent()
|
||||||
|
});
|
||||||
|
|
||||||
|
// event ketika unit kerja dipilih
|
||||||
|
selectUnit.on('select2:select', function (e) {
|
||||||
|
let data = e.params.data; // data unit kerja terpilih
|
||||||
|
selectSubUnit.empty().append('<option value="" disabled selected>-- Pilih Sub Unit Kerja --</option>');
|
||||||
|
|
||||||
|
if (data.sub_units && data.sub_units.length > 0) {
|
||||||
|
data.sub_units.forEach(sub => {
|
||||||
|
selectSubUnit.append(`<option value="${sub.id}/${sub.name}">${sub.name}</option>`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// aktifkan select2 untuk sub unit
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let currentFile = null;
|
||||||
|
let idDirectory = null;
|
||||||
|
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) {
|
||||||
|
// contoh label permission biar enak dibaca
|
||||||
|
const isPublic = (permissionFile === 'true' || permissionFile.toLowerCase() === 'iya');
|
||||||
|
permEl.textContent = isPublic ? 'Bisa dilihat unit lain' : 'Hanya unit ini';
|
||||||
|
permEl.className = 'badge ' + (isPublic ? '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.id === 'delete-file'){
|
||||||
|
if(!currentFile){
|
||||||
|
Swal.fire({
|
||||||
|
text: "Tidak ada file yang dipilih!",
|
||||||
|
icon: "warning",
|
||||||
|
confirmButtonText: "OK"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Swal.fire({
|
||||||
|
title: 'Yakin ingin menghapus file ini?',
|
||||||
|
text: "File akan dihapus",
|
||||||
|
icon: 'warning',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: '#d33',
|
||||||
|
cancelButtonColor: '#6c757d',
|
||||||
|
confirmButtonText: 'Ya, hapus',
|
||||||
|
cancelButtonText: 'Batal'
|
||||||
|
}).then((result) => {
|
||||||
|
if(result.isConfirmed){
|
||||||
|
fetch(`/delete-file/${idDirectory}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
'Content-Type' : 'application/json',
|
||||||
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ file: currentFile })
|
||||||
|
})
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(data => {
|
||||||
|
if(data.success){
|
||||||
|
Swal.fire({
|
||||||
|
text: 'File berhasil dihapus',
|
||||||
|
icon: 'success',
|
||||||
|
timer: 2000,
|
||||||
|
showConfirmButton: false
|
||||||
|
});
|
||||||
|
$("#previewModal").modal("hide");
|
||||||
|
fetchData()
|
||||||
|
currentFile = null;
|
||||||
|
idDirectory = null;
|
||||||
|
}else{
|
||||||
|
Swal.fire({
|
||||||
|
text: 'Gagal menghapus file',
|
||||||
|
icon: 'error'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
Swal.fire({
|
||||||
|
text: 'Terjadi error saat menghapus file ',
|
||||||
|
icon: 'error'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if(e.target.matches('#btn-view-full')){
|
||||||
|
window.open(`/file-preview/${idDirectory}`, '_blank');
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
96
resources/views/dashboardV2/modal/create.blade.php
Normal file
96
resources/views/dashboardV2/modal/create.blade.php
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<div class="modal fade" id="modalCreateFile" tabindex="-1" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-xl modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
|
||||||
|
<!-- Modal Header -->
|
||||||
|
<div class="modal-header">
|
||||||
|
<h1 class="modal-title fs-5">Aksi </h1>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal Form -->
|
||||||
|
<form id="formFile" action="/uploadv2" enctype="multipart/form-data" method="POST">
|
||||||
|
@csrf
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="container" style="max-height: 70vh; overflow-y:auto;">
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label fw-semibold">Unit <span class="text-danger">*</span></label>
|
||||||
|
<select class="form-control unit_kerja" name="data[0][id_unit_kerja]" id="select_id_unit_kerja_0" required>
|
||||||
|
<option value="" disable>Select Choose</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label fw-semibold">Sub Unit <span class="text-danger">*</span></label>
|
||||||
|
<select class="form-control" name="data[0][id_sub_unit_kerja]" id="select_id_sub_unit_kerja_0" required>
|
||||||
|
<option value="" disable selected>Select Choose</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label fw-semibold">Kategori Dokumen <span class="text-danger">*</span></label>
|
||||||
|
<select class="form-control" name="data[0][master_kategori_directory_id]" id="select_kategori_0" required>
|
||||||
|
<option value="" disable>Select Choose</option>
|
||||||
|
@foreach ($katDok as $kat)
|
||||||
|
<option value="{{ $kat->master_kategori_directory_id }}/{{ $kat->nama_kategori_directory }}">{{ $kat->nama_kategori_directory }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-semibold">Nomor Dokumen</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-text">#</span>
|
||||||
|
<input type="text" class="form-control" name="data[0][no_dokumen]" placeholder="Contoh: 001/RS/IT/I/2026">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label fw-semibold">Tanggal Terbit</label>
|
||||||
|
<input class="form-control" type="date" name="data[0][date_active]" required>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label fw-semibold">Boleh dilihat unit lain? <span class="text-danger">*</span></label>
|
||||||
|
|
||||||
|
<div class="border rounded-3 p-2 bg-light">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio" name="data[0][is_permission]" id="perm_yes" value="1" required>
|
||||||
|
<label class="form-check-label" for="perm_yes">
|
||||||
|
Iya
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-check mt-1">
|
||||||
|
<input class="form-check-input" type="radio" name="data[0][is_permission]" id="perm_no" value="2" required>
|
||||||
|
<label class="form-check-label" for="perm_no">
|
||||||
|
Tidak
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-12 mb-2">
|
||||||
|
<label for="fileUpload0" class="form-label fw-semibold">📂 Upload Dokumen (PDF)</label>
|
||||||
|
<div class="border rounded-3 p-3 bg-white shadow-sm">
|
||||||
|
<input class="form-control" type="file" id="fileUpload0" accept=".pdf" name="data[0][file]">
|
||||||
|
<div class="mt-2 text-success fw-semibold d-none file-name"></div>
|
||||||
|
</div>
|
||||||
|
<div class="form-text text-muted">
|
||||||
|
Bisa upload lebih dari 1 file. Format yang didukung: <b>PDF</b>.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="col_add_fileV2" class="col-12"></div>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn btn-outline-primary btn-sm mt-3" onclick="addFormV2()">
|
||||||
|
+ Tambah Form
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal Footer -->
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Tutup</button>
|
||||||
|
<button type="submit" class="btn btn-primary">Simpan</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
61
resources/views/dashboardV2/modal/view.blade.php
Normal file
61
resources/views/dashboardV2/modal/view.blade.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<!-- 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 class="d-flex justify-content-end align-items-center sticky-top bg-white z-10">
|
||||||
|
<button type="button" class="btn btn-sm btn-outline-danger mb-2 me-2" id="delete-file">🗑 Hapus</button>
|
||||||
|
</div>
|
||||||
|
<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>
|
||||||
@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="sidebar-item">
|
{{-- <li class="sidebar-item">
|
||||||
<a class="sidebar-link justify-content-between"
|
<a class="sidebar-link justify-content-between"
|
||||||
href="/master-klasifikasi" aria-expanded="false">
|
href="/master-klasifikasi" aria-expanded="false">
|
||||||
<div class="d-flex align-items-center gap-3">
|
<div class="d-flex align-items-center gap-3">
|
||||||
@ -53,7 +53,7 @@
|
|||||||
<span class="hide-menu">Master Klasifikasi</span>
|
<span class="hide-menu">Master Klasifikasi</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li> --}}
|
||||||
<li class="sidebar-item">
|
<li class="sidebar-item">
|
||||||
<a class="sidebar-link justify-content-between"
|
<a class="sidebar-link justify-content-between"
|
||||||
href="/akses" aria-expanded="false">
|
href="/akses" aria-expanded="false">
|
||||||
|
|||||||
@ -12,6 +12,8 @@ Route::middleware(['auth'])->group(function(){
|
|||||||
Route::get('/', [DashboardController::class, 'index']);
|
Route::get('/', [DashboardController::class, 'index']);
|
||||||
Route::get('/new', [DashboardController::class, 'dashboardVersion2']);
|
Route::get('/new', [DashboardController::class, 'dashboardVersion2']);
|
||||||
Route::get('/last-document', [DashboardController::class, 'dataDocumentLast']);
|
Route::get('/last-document', [DashboardController::class, 'dataDocumentLast']);
|
||||||
|
Route::post('/uploadv2', [DashboardController::class, 'storeVersion2']);
|
||||||
|
Route::get('/file-preview/{id}', [DashboardController::class, 'dataPdf']);
|
||||||
Route::post('/upload', [DashboardController::class, 'store']);
|
Route::post('/upload', [DashboardController::class, 'store']);
|
||||||
Route::get('/data-unit-kerja', [DashboardController::class, 'dataUnitKerja']);
|
Route::get('/data-unit-kerja', [DashboardController::class, 'dataUnitKerja']);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user