feat(holidaycalendar): implement full feature set for holiday calendar management
- Mengganti namespace model `HolidayCalendar` dari `Entities` ke `Models`. - Menambahkan validasi izin untuk semua aksi CRUD dan ekspor pada `HolidayCalendarController`. - Mengintegrasikan fitur izin pada tombol aksi (create, update, delete, export) di view `index.blade.php`. - Mengupdate logika form view `create.blade.php` untuk mendukung pengelolaan izin dan action dinamis. - Menambahkan class test `HolidayCalendarControllerTest` dengan pengujian lengkap mencakup: - Hak akses untuk membaca, membuat, memperbarui, menghapus, dan mengekspor data. - Validasi data saat penyimpanan/pembaruan. - Validasi respon HTTP untuk setiap aksi berdasarkan izin. - Memastikan user tanpa izin akan menerima pesan atau pembatasan akses yang relevan (HTTP 403). - Fitur ekspor CSV hanya dapat diakses oleh user dengan izin `basic-data.export`. - Memperbaiki rendering tindakan pada data tabel di `index.blade.php` agar responsif terhadap izin user. Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
This commit is contained in:
@@ -6,71 +6,79 @@
|
||||
|
||||
@section('content')
|
||||
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
|
||||
@if(isset($holiday->id))
|
||||
<form action="{{ route('basicdata.holidaycalendar.update', $holiday->id) }}" method="POST">
|
||||
<form method="POST" action="{{ isset($holiday->id) ? route('basicdata.holidaycalendar.update', $holiday->id) : route('basicdata.holidaycalendar.store') }}">
|
||||
@csrf
|
||||
@if(isset($holiday->id))
|
||||
<input type="hidden" name="id" value="{{ $holiday->id }}">
|
||||
@method('PUT')
|
||||
@else
|
||||
<form method="POST" action="{{ route('basicdata.holidaycalendar.store') }}">
|
||||
@endif
|
||||
@csrf
|
||||
<div class="card pb-2.5">
|
||||
<div class="card-header" id="basic_settings">
|
||||
<h3 class="card-title">
|
||||
{{ isset($holiday->id) ? 'Edit' : 'Tambah' }} Hari Libur
|
||||
</h3>
|
||||
<div class="flex items-center gap-2">
|
||||
<a href="{{ route('basicdata.holidaycalendar.index') }}" class="btn btn-xs btn-info"><i class="ki-filled ki-exit-left"></i> Back</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body grid gap-5">
|
||||
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
||||
<label class="form-label max-w-56">
|
||||
Tanggal
|
||||
</label>
|
||||
<div class="flex flex-wrap items-baseline w-full">
|
||||
<input class="input @error('date') border-danger bg-danger-light @enderror" type="date" name="date" value="{{ old('date', isset($holiday) ? $holiday->date->format('Y-m-d') : '') }}">
|
||||
@error('date')
|
||||
<em class="alert text-danger text-sm">{{ $message }}</em>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
||||
<label class="form-label max-w-56">
|
||||
Deskripsi
|
||||
</label>
|
||||
<div class="flex flex-wrap items-baseline w-full">
|
||||
<input class="input @error('description') border-danger bg-danger-light @enderror"
|
||||
type="text"
|
||||
name="description"
|
||||
value="{{ old('description', $holiday->description ?? '') }}">
|
||||
@error('description')
|
||||
<em class="alert text-danger text-sm">{{ $message }}</em>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
||||
<label class="form-label max-w-56">
|
||||
Tipe
|
||||
</label>
|
||||
<div class="flex flex-wrap items-baseline w-full">
|
||||
<select class="select @error('type') border-danger bg-danger-light @enderror" name="type">
|
||||
<option value="">Pilih Tipe</option>
|
||||
<option value="national_holiday" {{ old('type', $holiday->type ?? '') == 'national_holiday' ? 'selected' : '' }}>Nasional</option>
|
||||
<option value="collective_leave" {{ old('type', $holiday->type ?? '') == 'collective_leave' ? 'selected' : '' }}>Cuti Bersama</option>
|
||||
</select>
|
||||
@error('type')
|
||||
<em class="alert text-danger text-sm">{{ $message }}</em>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
<div class="card pb-2.5">
|
||||
<div class="card-header" id="basic_settings">
|
||||
<h3 class="card-title">
|
||||
{{ isset($holiday->id) ? 'Edit' : 'Tambah' }} Hari Libur
|
||||
</h3>
|
||||
<div class="flex items-center gap-2">
|
||||
<a href="{{ route('basicdata.holidaycalendar.index') }}" class="btn btn-xs btn-info"><i class="ki-filled ki-exit-left"></i> Back</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body grid gap-5">
|
||||
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
||||
<label class="form-label max-w-56">
|
||||
Tanggal
|
||||
</label>
|
||||
<div class="flex flex-wrap items-baseline w-full">
|
||||
<input class="input @error('date') border-danger bg-danger-light @enderror" type="date" name="date" value="{{ old('date', isset($holiday) ? $holiday->date->format('Y-m-d') : '') }}">
|
||||
@error('date')
|
||||
<em class="alert text-danger text-sm">{{ $message }}</em>
|
||||
@enderror
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
||||
<label class="form-label max-w-56">
|
||||
Deskripsi
|
||||
</label>
|
||||
<div class="flex flex-wrap items-baseline w-full">
|
||||
<input class="input @error('description') border-danger bg-danger-light @enderror"
|
||||
type="text"
|
||||
name="description"
|
||||
value="{{ old('description', $holiday->description ?? '') }}">
|
||||
@error('description')
|
||||
<em class="alert text-danger text-sm">{{ $message }}</em>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
|
||||
<label class="form-label max-w-56">
|
||||
Tipe
|
||||
</label>
|
||||
<div class="flex flex-wrap items-baseline w-full">
|
||||
<select class="select @error('type') border-danger bg-danger-light @enderror" name="type">
|
||||
<option value="">Pilih Tipe</option>
|
||||
<option value="national_holiday" {{ old('type', $holiday->type ?? '') == 'national_holiday' ? 'selected' : '' }}>Nasional</option>
|
||||
<option value="collective_leave" {{ old('type', $holiday->type ?? '') == 'collective_leave' ? 'selected' : '' }}>Cuti Bersama</option>
|
||||
</select>
|
||||
@error('type')
|
||||
<em class="alert text-danger text-sm">{{ $message }}</em>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end">
|
||||
@if(isset($holiday->id))
|
||||
@can('basic-data.update')
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Save
|
||||
</button>
|
||||
@endcan
|
||||
@else
|
||||
@can('basic-data.create')
|
||||
<button type="submit" class="btn btn-primary">
|
||||
Save
|
||||
</button>
|
||||
@endcan
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@@ -19,9 +19,15 @@
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2.5">
|
||||
<div class="h-[24px] border border-r-gray-200"></div>
|
||||
@can('basic-data.export')
|
||||
<a class="btn btn-sm btn-light" href="{{ route('basicdata.holidaycalendar.export') }}"> Export to Excel </a>
|
||||
@endcan
|
||||
@can('basic-data.create')
|
||||
<a class="btn btn-sm btn-primary" href="{{ route('basicdata.holidaycalendar.create') }}"> Tambah Hari Libur </a>
|
||||
@endcan
|
||||
@can('basic-data.delete')
|
||||
<button class="btn btn-sm btn-danger hidden" id="deleteSelected" onclick="deleteSelectedRows()">Delete Selected</button>
|
||||
@endcan
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -177,14 +183,22 @@
|
||||
actions: {
|
||||
title: 'Action',
|
||||
render: (item, data) => {
|
||||
return `<div class="flex flex-nowrap justify-center">
|
||||
<a class="btn btn-sm btn-icon btn-clear btn-info" href="basic-data/holidaycalendar/${data.id}/edit">
|
||||
let html = `<div class="flex flex-nowrap justify-center">`;
|
||||
|
||||
@can('basic-data.update')
|
||||
html += `<a class="btn btn-sm btn-icon btn-clear btn-info" href="basic-data/holidaycalendar/${data.id}/edit">
|
||||
<i class="ki-outline ki-notepad-edit"></i>
|
||||
</a>
|
||||
<a onclick="deleteData(${data.id})" class="delete btn btn-sm btn-icon btn-clear btn-danger">
|
||||
</a>`;
|
||||
@endcan
|
||||
|
||||
@can('basic-data.delete')
|
||||
html += `<a onclick="deleteData(${data.id})" class="delete btn btn-sm btn-icon btn-clear btn-danger">
|
||||
<i class="ki-outline ki-trash"></i>
|
||||
</a>
|
||||
</div>`;
|
||||
</a>`;
|
||||
@endcan
|
||||
|
||||
html += `</div>`;
|
||||
return html;
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user