chore: add issue count and change show UI in gov agency

This commit is contained in:
myuqinurrohman 2025-03-24 10:50:56 +07:00
parent 01a8b500a4
commit 96643c30de
19 changed files with 213 additions and 93 deletions

View File

@ -356,12 +356,19 @@ public function subLocation(Request $request){
public function governmentAgency(Request $request){
if ($request->ajax()) {
$data = GovernmentAgency::all();
$data = GovernmentAgency::with(['issues'])->get();
return DataTables::of($data)
->addIndexColumn()
->addColumn('issues', function ($data) {
return $data->managementIssues->count();
$issueCount = $data->issues->count();
if($issueCount > 0){
return $issueCount. ' [<a href="'.route('dashboard.issue.managements.index', ['government_agency' => encrypt_id($data->id)]).'">Lihat</a>]';
}else{
return $issueCount;
}
})
->addColumn('action', function ($data) {
$showUrl = route('dashboard.government.agencies.show', ['id' => encrypt_id($data->id)]);
@ -392,7 +399,7 @@ public function governmentAgency(Request $request){
return $dropdown;
})
->rawColumns(['action'])
->rawColumns(['issues', 'action'])
->make(true);
}
@ -1722,6 +1729,7 @@ public function issueManagement(Request $request){
$subClassificationParam = $request->input('sub_classification', null);
$locationParam = $request->input('location', null);
$subLocationParam = $request->input('sub_location', null);
$governmentAgencyParam = $request->input('government_agency', null);
if($classificationParam){
$data = IssueManagement::with(['location', 'subLocation', 'classification', 'subClassification', 'enhancer', 'governmentAgencies'])->where('classification_id', decrypt_id($classificationParam))->get();
@ -1735,6 +1743,12 @@ public function issueManagement(Request $request){
}else if($subLocationParam){
$data = IssueManagement::with(['location', 'subLocation', 'classification', 'subClassification', 'enhancer', 'governmentAgencies'])->where('sub_location_id', decrypt_id($subLocationParam))->get();
}else if($governmentAgencyParam){
$data = IssueManagement::with(['location', 'subLocation', 'classification', 'subClassification', 'enhancer', 'governmentAgencies'])
->whereHas('governmentAgencies', function ($query) use ($governmentAgencyParam) {
$query->where('issue_managements_government_agencies.government_agency_id', decrypt_id($governmentAgencyParam));
})
->get();
}else{
$data = IssueManagement::with(['location', 'subLocation', 'classification', 'subClassification', 'enhancer', 'governmentAgencies'])->get();
}

View File

@ -25,13 +25,12 @@ public function create(){
public function store(GovernmentAgencyRequest $request){
$validatedData = $request->validated();
$validatedData['slug'] = Str::slug($validatedData['name']);
$validatedData['enhancer_id'] = Auth::id();
$createdGovernmentAgency = GovernmentAgency::create($validatedData);
if($createdGovernmentAgency){
return redirect()->back()->with('success-status', 'Berhasil menambahkan OPD.');
return redirect()->route('dashboard.government.agencies.index')->with('success-status', 'Berhasil menambahkan OPD.');
}else{
return redirect()->back()->with('failed-status', 'Gagal menambahkan OPD');
}
@ -48,7 +47,6 @@ public function edit($id){
public function update(GovernmentAgencyRequest $request, $id){
$validatedData = $request->validated();
$validatedData['slug'] = Str::slug($validatedData['name']);
$validatedData['enhancer_id'] = Auth::id();
$governmentAgency = GovernmentAgency::findOrFail(decrypt_id($id));

View File

@ -23,7 +23,7 @@ public function index(Request $request){
'sub_classification' => $request->input('sub_classification', null),
'location' => $request->input('location', null),
'sub_location' => $request->input('sub_location', null),
'agency' => $request->input('agency', null),
'government_agency' => $request->input('government_agency', null),
]);
}

View File

@ -24,17 +24,26 @@ public function authorize(): bool
public function rules(): array
{
return [
'name' => ['required'],
'name' => ['required', 'max:100'],
'status' => ['required', 'in:0,1'],
'description' => ['nullable']
];
}
protected function prepareForValidation()
{
$this->merge([
'description' => filled($this->description) ? $this->description : null,
]);
}
public function messages(): array
{
return [
'name.required' => 'Nama klasifikasi harus diisi.',
'name.max' => 'Nama klasifikasi tidak boleh lebih dari 100 karakter.',
'status.required' => 'Status harus dipilih.',
'status.in' => 'Status harus memiliki nilai aktif atau tidak aktif.',
'description.nullable' => 'Deskripsi boleh kosong jika tidak diperlukan.',

View File

@ -29,4 +29,25 @@ public function rules(): array
'description' => ['nullable'],
];
}
protected function prepareForValidation()
{
$this->merge([
'short_name' => filled($this->short_name) ? $this->short_name : null,
'location' => filled($this->location) ? $this->location : null,
'description' => filled($this->description) ? $this->description : null,
]);
}
public function messages(): array
{
return [
'name.required' => 'Nama OPD harus diisi.',
'name.max' => 'Nama OPD tidak boleh lebih dari 100 karakter.',
'short_name.nullable' => 'Singkatan nama boleh kosong jika tidak diperlukan.',
'short_name.max' => 'Singkatan nama tidak boleh lebih dari 100 karakter.',
'location.nullable' => 'Lokasi boleh kosong jika tidak diperlukan.',
'description.nullable' => 'Deskripsi boleh kosong jika tidak diperlukan.',
];
}
}

View File

@ -23,16 +23,24 @@ public function authorize(): bool
public function rules(): array
{
return [
'name' => ['required'],
'name' => ['required', 'max:100'],
'status' => ['required', 'in:0,1'],
'description' => ['nullable']
];
}
protected function prepareForValidation()
{
$this->merge([
'description' => filled($this->description) ? $this->description : null,
]);
}
public function messages(): array
{
return [
'name.required' => 'Nama lokus harus diisi.',
'name.max' => 'Nama lokus tidak boleh lebih dari 100 karakter.',
'status.required' => 'Status harus dipilih.',
'status.in' => 'Status harus memiliki nilai aktif atau tidak aktif.',
'description.nullable' => 'Deskripsi boleh kosong jika tidak diperlukan.',

View File

@ -23,19 +23,27 @@ public function authorize(): bool
public function rules(): array
{
return [
'name' => ['required'],
'name' => ['required', 'max:100'],
'classification_id' => ['required', 'exists:classifications,id'],
'status' => ['required', 'in:0,1'],
'description' => ['nullable']
];
}
protected function prepareForValidation()
{
$this->merge([
'description' => filled($this->description) ? $this->description : null,
]);
}
public function messages(): array
{
return [
'name.required' => 'Nama klasifikasi harus diisi.',
'classification_id.required' => 'Klasifikasi utama harus dipilih.',
'name.required' => 'Nama sub klasifikasi harus diisi.',
'name.max' => 'Nama sub klasifikasi tidak boleh lebih dari 100 karakter.',
'classification_id.required' => 'Klasifikasi harus dipilih.',
'classification_id.exists' => 'Klasifikasi yang dipilih tidak valid.',
'status.required' => 'Status harus dipilih.',
'status.in' => 'Status harus bernilai aktif atau tidak aktif.',

View File

@ -23,18 +23,26 @@ public function authorize(): bool
public function rules(): array
{
return [
'name' => ['required'],
'name' => ['required', 'max:100'],
'location_id' => ['required', 'exists:locations,id'],
'status' => ['required', 'in:0,1'],
'description' => ['nullable']
];
}
protected function prepareForValidation()
{
$this->merge([
'description' => filled($this->description) ? $this->description : null,
]);
}
public function messages(): array
{
return [
'name.required' => 'Nama lokus harus diisi.',
'location_id.required' => 'Lokus utama harus dipilih.',
'name.required' => 'Nama sub lokus harus diisi.',
'name.max' => 'Nama sub lokus tidak boleh lebih dari 100 karakter.',
'location_id.required' => 'Lokus harus dipilih.',
'location_id.exists' => 'Lokus yang dipilih tidak valid.',
'status.required' => 'Status harus dipilih.',
'status.in' => 'Status harus bernilai aktif atau tidak aktif.',

View File

@ -7,6 +7,7 @@
class GovernmentAgency extends Model
{
use SoftDeletes;
protected $table = 'government_agencies';
@ -18,7 +19,7 @@ class GovernmentAgency extends Model
'enhancer_id',
];
public function managementIssues()
public function issues()
{
return $this->belongsToMany(IssueManagement::class, 'issue_managements_government_agencies', 'government_agency_id', 'issue_management_id')
->using(IssueManagementGovernmentAgency::class)

View File

@ -20,6 +20,7 @@ public function up(): void
$table->unsignedBigInteger('enhancer_id');
$table->foreign('enhancer_id')->references('id')->on('users');
$table->timestamps();
$table->softDeletes();
});
}

View File

@ -28,6 +28,7 @@ public function run(): void
'name' => $normalizedAgencyName, // Simpan dengan format aslinya
'created_at' => $agency->created_at,
'updated_at' => $agency->updated_at,
'deleted_at' => $agency->deleted_at,
'enhancer_id' => $agency->user_id,
]);
}

View File

@ -36,7 +36,7 @@
@elseif ($classification->status == 0)
<span class="profile-ud-value"><span class="badge bg-warning">Nonaktif</span></span>
@elseif ($classification->status == 1)
<span class="profile-ud-value"><span class="badge bg-success">Aktif</span></span>
<span class="profile-ud-value"><span class="badge bg-primary">Aktif</span></span>
@else
<span class="profile-ud-value"><span class="badge bg-secondary">Tidak Diketahui</span></span>
@endif

View File

@ -12,7 +12,7 @@
<div class="card-head">
<h5 class="card-title">{{$title}}</h5>
</div>
<form action="{{route('dashboard.government.agencies.store')}}" method="post">
<form action="{{route('dashboard.government.agencies.store')}}" method="post" id="myForm">
@csrf
<div class="row g-4">
<div class="col-lg-6">
@ -60,7 +60,7 @@
<hr>
<div class="form-group d-flex justify-content-end">
<a href="{{route('dashboard.government.agencies.index')}}" class="btn btn-white btn-dim btn-outline-light mx-2"><span>Kembali</span></a>
<button type="submit" class="btn btn-md btn-primary">Tambahkan</button>
<button type="button" class="btn btn-md btn-primary" id="submitButton">Tambahkan</button>
</div>
</div>
</div>

View File

@ -12,7 +12,7 @@
<div class="card-head">
<h5 class="card-title">{{$title}}</h5>
</div>
<form action="{{route('dashboard.government.agencies.update', ['id' => encrypt_id($governmentAgency->id)])}}" method="post">
<form action="{{route('dashboard.government.agencies.update', ['id' => encrypt_id($governmentAgency->id)])}}" method="post" id="myForm">
@csrf
@method('put')
<div class="row g-4">
@ -60,8 +60,12 @@
<div class="col-12">
<hr>
<div class="form-group d-flex justify-content-end">
@if (request()->query('show'))
<a href="{{route('dashboard.government.agencies.show', ['id' => encrypt_id($governmentAgency->id)])}}" class="btn btn-white btn-dim btn-outline-light mx-2"><span>Kembali</span></a>
@else
<a href="{{route('dashboard.government.agencies.index')}}" class="btn btn-white btn-dim btn-outline-light mx-2"><span>Kembali</span></a>
<button type="submit" class="btn btn-md btn-primary">Simpan</button>
@endif
<button type="button" class="btn btn-md btn-primary" id="submitButton">Simpan</button>
</div>
</div>
</div>

View File

@ -7,57 +7,80 @@
<div class="nk-content-inner">
<div class="nk-content-body">
<div class="nk-block nk-block-lg">
<div class="card card-bordered card-preview">
<div class="card-inner">
<div class="card-head">
<h5 class="card-title">{{$title}}</h5>
</div>
<form action="#" method="post">
@csrf
@method('put')
<div class="row g-4">
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="name">Nama<span class="required-input">*</span></label>
<div class="form-control-wrap">
<input type="text" class="form-control @error('name') border-danger @enderror" id="name" name="name" placeholder="Masukan nama OPD" value="{{$governmentAgency->name}}" readonly>
<div class="card">
<div class="card-aside-wrap">
<div class="card-content">
<ul class="nav nav-tabs nav-tabs-mb-icon nav-tabs-card">
<li class="nav-item">
<a class="nav-link text-primary" href="#"><em class="icon ni ni-info"></em><span>Detail OPD</span></a>
</li>
</ul><!-- .nav-tabs -->
<div class="card-inner">
<div class="nk-block">
{{-- <div class="nk-block-head">
<h5 class="title">Personal Information</h5>
<p>Basic info, like your name and address, that you use on Nio Platform.</p>
</div> --}}
<div class="profile-ud-list">
<div class="profile-ud-item">
<div class="profile-ud wider">
<span class="profile-ud-label">Nama OPD</span>
<span class="profile-ud-value">{{$governmentAgency->name}}</span>
</div>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="short_name">Singkatan Nama</label>
<div class="form-control-wrap">
<input type="text" class="form-control @error('short_name') border-danger @enderror" id="short_name" name="short_name" placeholder="Masukan singkatan nama OPD" value="{{$governmentAgency->short_name}}" readonly>
<div class="profile-ud-item">
<div class="profile-ud wider">
<span class="profile-ud-label">Singkatan Nama</span>
<span class="profile-ud-value">{{$governmentAgency->short_name ?? '-'}}</span>
</div>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="location">Lokasi</label>
<div class="form-control-wrap">
<input type="text" class="form-control @error('location') border-danger @enderror" id="location" name="location" placeholder="Masukan lokasi OPD" value="{{$governmentAgency->location}}" readonly>
<div class="profile-ud-item">
<div class="profile-ud wider">
<span class="profile-ud-label">Lokasi</span>
<span class="profile-ud-value">{{$governmentAgency->location ?? '-'}}</span>
</div>
</div>
</div>
</div>
<div class="col-lg-12">
<div class="form-group">
<label class="form-label" for="phone-no-1">Deskripsi</label>
<div class="form-control-wrap">
<div class="description-content">{!! $governmentAgency->description !!}</div>
<div class="profile-ud-item">
<div class="profile-ud wider">
<span class="profile-ud-label">Isu</span>
<span class="profile-ud-value">
@if ($governmentAgency->issues->count() > 0)
<a href="{{route('dashboard.issue.managements.index', ['government_agency' => encrypt_id($governmentAgency->id)])}}"><u>{{$governmentAgency->issues->count()}}</u></a>
@else
{{$governmentAgency->issues->count()}}
@endif
</span>
</div>
</div>
</div>
</div>
<div class="col-12">
<hr>
<div class="form-group d-flex justify-content-end">
<a href="{{route('dashboard.government.agencies.index')}}" class="btn btn-white btn-dim btn-outline-light mx-2"><span>Kembali</span></a>
<a href="{{route('dashboard.government.agencies.edit', ['id' => encrypt_id($governmentAgency->id)])}}" class="btn btn-warning"><span>Ubah</span></a>
</div>
</div>
</div>
</form>
</div>
<div class="profile-ud-item">
<div class="profile-ud wider">
<span class="profile-ud-label">Dibuat Pada</span>
<span class="profile-ud-value">{{idn_date($governmentAgency->created_at, 'l, d F Y')}}</span>
</div>
</div>
</div><!-- .profile-ud-list -->
</div><!-- .nk-block -->
{{-- <div class="nk-divider divider md"></div> --}}
<div class="nk-block">
<div class="nk-block-head nk-block-head-sm nk-block-between">
<span class="profile-ud-label">Deskripsi</span>
</div><!-- .nk-block-head -->
<div class="bq-note">
<div class="bq-note-item">
<div class="bq-note-text">
{!!$governmentAgency->description ?? '-' !!}
</div>
</div><!-- .bq-note-item -->
</div><!-- .bq-note -->
</div><!-- .nk-block -->
<hr>
<div class="nk-block d-flex justify-content-end">
<a href="{{route('dashboard.government.agencies.index')}}" class="btn btn-white btn-dim btn-outline-light mx-2"><span>Kembali</span></a>
<a href="{{route('dashboard.government.agencies.edit', ['id' => encrypt_id($governmentAgency->id), 'show' => true])}}" class="btn btn-warning"><span>Ubah</span></a>
</div><!-- .nk-block -->
</div><!-- .card-inner -->
</div><!-- .card-content -->
</div><!-- .card-aside-wrap -->
</div>
</div>
</div>
@ -65,4 +88,4 @@
</div>
</div>
<!-- content @e -->
@include('partials.dashboard.footer', ['rich_editor' => true])
@include('partials.dashboard.footer', ['rich_editor' => false])

View File

@ -31,16 +31,15 @@
<div class="profile-ud-item">
<div class="profile-ud wider">
<span class="profile-ud-label">Status</span>
@switch($location->status)
@case(0)
<span class="profile-ud-value"><span class="badge bg-warning">Nonaktif</span></span>
@break
@case(1)
<span class="profile-ud-value"><span class="badge bg-success">Aktif</span></span>
@break
@default
<span class="profile-ud-value"><span class="badge bg-secondary">Tidak Diketahui</span></span>
@endswitch
@if (filled($location->deleted_at))
<span class="profile-ud-value"><span class="badge bg-danger">Dihapus</span></span>
@elseif ($location->status == 0)
<span class="profile-ud-value"><span class="badge bg-warning">Nonaktif</span></span>
@elseif ($location->status == 1)
<span class="profile-ud-value"><span class="badge bg-primary">Aktif</span></span>
@else
<span class="profile-ud-value"><span class="badge bg-secondary">Tidak Diketahui</span></span>
@endif
</div>
</div>
@ -68,6 +67,12 @@
</span>
</div>
</div>
<div class="profile-ud-item">
<div class="profile-ud wider">
<span class="profile-ud-label">Dibuat Pada</span>
<span class="profile-ud-value">{{idn_date($location->created_at, 'l, d F Y')}}</span>
</div>
</div>
</div><!-- .profile-ud-list -->
</div><!-- .nk-block -->
{{-- <div class="nk-divider divider md"></div> --}}

View File

@ -54,7 +54,7 @@
@elseif ($subClassification->status == 0)
<span class="profile-ud-value"><span class="badge bg-warning">Nonaktif</span></span>
@elseif ($subClassification->status == 1)
<span class="profile-ud-value"><span class="badge bg-success">Aktif</span></span>
<span class="profile-ud-value"><span class="badge bg-primary">Aktif</span></span>
@else
<span class="profile-ud-value"><span class="badge bg-secondary">Tidak Diketahui</span></span>
@endif

View File

@ -49,18 +49,22 @@
<div class="profile-ud-item">
<div class="profile-ud wider">
<span class="profile-ud-label">Status</span>
@switch($subLocation->status)
@case(0)
<span class="profile-ud-value"><span class="badge bg-warning">Nonaktif</span></span>
@break
@case(1)
<span class="profile-ud-value"><span class="badge bg-success">Aktif</span></span>
@break
@default
<span class="profile-ud-value"><span class="badge bg-secondary">Tidak Diketahui</span></span>
@endswitch
@if (filled($subLocation->deleted_at))
<span class="profile-ud-value"><span class="badge bg-danger">Dihapus</span></span>
@elseif ($subLocation->status == 0)
<span class="profile-ud-value"><span class="badge bg-warning">Nonaktif</span></span>
@elseif ($subLocation->status == 1)
<span class="profile-ud-value"><span class="badge bg-primary">Aktif</span></span>
@else
<span class="profile-ud-value"><span class="badge bg-secondary">Tidak Diketahui</span></span>
@endif
</div>
</div>
<div class="profile-ud-item">
<div class="profile-ud wider">
<span class="profile-ud-label">Dibuat Pada</span>
<span class="profile-ud-value">{{idn_date($subLocation->created_at, 'l, d F Y')}}</span>
</div>
</div>
</div><!-- .profile-ud-list -->
</div><!-- .nk-block -->

View File

@ -222,9 +222,24 @@
{ data: 'created_at', name: 'created_at', visible: false },
{ data: 'id', name: 'id', orderable: true, searchable: false, visible: false },
],
columnDefs: [
{ targets: 0, width: 'auto' },
{ targets: 2, width: '10%' },
{ targets: 3, width: '7%' },
{
targets: [1],
createdCell: function(td, cellData, rowData, row, col) {
$(td).css({
'word-wrap': 'break-word',
'white-space': 'normal',
'overflow-wrap': 'break-word'
});
}
}
],
language: datatableLanguage,
autoWidth: false,
order: [[3, 'desc']],
order: [[4, 'desc']],
pagingType: "simple",
lengthMenu: [[10, 25, 50, 100, -1], ['Tampilkan 10 data', 'Tampilkan 25 data', 'Tampilkan 50 data', 'Tampilkan 100 data', 'Tampilkan semua']],
scrollX: true
@ -805,7 +820,7 @@
$('#issueManagementsTable').DataTable({
processing: true,
serverSide: true,
ajax: '{{ route('dashboard.issue.managements.data', ["classification" => $classification, "sub_classification" => $sub_classification, "location" => $location, "sub_location" => $sub_location, "agency" => $agency]) }}',
ajax: '{{ route('dashboard.issue.managements.data', ["classification" => $classification, "sub_classification" => $sub_classification, "location" => $location, "sub_location" => $sub_location, "government_agency" => $government_agency]) }}',
columns: [
{ data: 'DT_RowIndex', name: 'DT_RowIndex', orderable: false, searchable: false },
{ data: 'code', name: 'code' },