From 6026ed1c5d9b41097b54735640b5f008a29bab3d Mon Sep 17 00:00:00 2001 From: Ahmad Afandi Date: Wed, 2 Sep 2026 14:36:16 +0700 Subject: [PATCH 1/2] Perbaikan pagination unduhan --- .../views/pages/unduhan/form-dokumen.blade.php | 13 +++++++++---- .../views/pages/unduhan/prosedur.blade.php | 13 +++++++++---- .../views/pages/unduhan/regulasi.blade.php | 13 +++++++++---- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/themes/opendk/default/resources/views/pages/unduhan/form-dokumen.blade.php b/themes/opendk/default/resources/views/pages/unduhan/form-dokumen.blade.php index 07b1e21d8..50efbcad0 100644 --- a/themes/opendk/default/resources/views/pages/unduhan/form-dokumen.blade.php +++ b/themes/opendk/default/resources/views/pages/unduhan/form-dokumen.blade.php @@ -30,15 +30,18 @@ $(document).ready(function() { var table = $('#dokumen-table').DataTable({ processing: true, - serverSide: false, + serverSide: true, ajax: { url: '{!! $urlApi !!}/form-dokumen', cache: false, - dataSrc: 'data', + dataSrc: function(json) { + json.recordsTotal = json.meta?.pagination?.total ?? 0; + json.recordsFiltered = json.meta?.pagination?.total ?? 0; + return json.data; + }, data: function(d) { - // Convert DataTables parameters to API format (use safe defaults to avoid NaN) var start = (typeof d.start !== 'undefined' && d.start !== null) ? d.start : 0; - var length = (typeof d.length !== 'undefined' && d.length) ? d.length : (typeof d.pageLength !== 'undefined' ? d.pageLength : 10); + var length = (typeof d.length !== 'undefined' && d.length) ? d.length : 10; var pageNumber = 1; if (length && !isNaN(length)) { pageNumber = Math.floor(start / length) + 1; @@ -52,6 +55,8 @@ }; } }, + pageLength: 10, + lengthMenu: [5, 10, 25, 50, 100], columns: [{ data: null, name: 'aksi', diff --git a/themes/opendk/default/resources/views/pages/unduhan/prosedur.blade.php b/themes/opendk/default/resources/views/pages/unduhan/prosedur.blade.php index b25a3f871..bfcc3d177 100644 --- a/themes/opendk/default/resources/views/pages/unduhan/prosedur.blade.php +++ b/themes/opendk/default/resources/views/pages/unduhan/prosedur.blade.php @@ -30,15 +30,18 @@ $(document).ready(function() { var table = $('#prosedur-table').DataTable({ processing: true, - serverSide: false, + serverSide: true, ajax: { url: '{!! $urlApi !!}/prosedur', cache: false, - dataSrc: 'data', + dataSrc: function(json) { + json.recordsTotal = json.meta?.pagination?.total ?? 0; + json.recordsFiltered = json.meta?.pagination?.total ?? 0; + return json.data; + }, data: function(d) { - // Convert DataTables parameters to API format (use safe defaults to avoid NaN) var start = (typeof d.start !== 'undefined' && d.start !== null) ? d.start : 0; - var length = (typeof d.length !== 'undefined' && d.length) ? d.length : (typeof d.pageLength !== 'undefined' ? d.pageLength : 10); + var length = (typeof d.length !== 'undefined' && d.length) ? d.length : 10; var pageNumber = 1; if (length && !isNaN(length)) { pageNumber = Math.floor(start / length) + 1; @@ -50,6 +53,8 @@ }; } }, + pageLength: 10, + lengthMenu: [5, 10, 25, 50, 100], columns: [{ data: 'attributes.judul_prosedur', name: 'judul_prosedur', diff --git a/themes/opendk/default/resources/views/pages/unduhan/regulasi.blade.php b/themes/opendk/default/resources/views/pages/unduhan/regulasi.blade.php index 567698960..0b2b90993 100644 --- a/themes/opendk/default/resources/views/pages/unduhan/regulasi.blade.php +++ b/themes/opendk/default/resources/views/pages/unduhan/regulasi.blade.php @@ -30,15 +30,18 @@ $(document).ready(function() { var table = $('#regulasi-table').DataTable({ processing: true, - serverSide: false, + serverSide: true, ajax: { url: '{!! $urlApi !!}/regulasi', cache: false, - dataSrc: 'data', + dataSrc: function(json) { + json.recordsTotal = json.meta?.pagination?.total ?? 0; + json.recordsFiltered = json.meta?.pagination?.total ?? 0; + return json.data; + }, data: function(d) { - // Convert DataTables parameters to API format (use safe defaults to avoid NaN) var start = (typeof d.start !== 'undefined' && d.start !== null) ? d.start : 0; - var length = (typeof d.length !== 'undefined' && d.length) ? d.length : (typeof d.pageLength !== 'undefined' ? d.pageLength : 10); + var length = (typeof d.length !== 'undefined' && d.length) ? d.length : 10; var pageNumber = 1; if (length && !isNaN(length)) { pageNumber = Math.floor(start / length) + 1; @@ -50,6 +53,8 @@ }; } }, + pageLength: 10, + lengthMenu: [5, 10, 25, 50, 100], columns: [{ data: 'attributes.judul', name: 'judul', From 831d05d7a89f7d32ca2eebd64891bdc080a349bc Mon Sep 17 00:00:00 2001 From: Ahmad Afandi Date: Fri, 4 Sep 2026 16:38:43 +0700 Subject: [PATCH 2/2] perbaikan prosedur --- app/Events/ProsedurChanged.php | 55 ++++++++++++++++++ app/Listeners/ClearProsedurCacheListener.php | 57 +++++++++++++++++++ app/Models/Prosedur.php | 11 ++++ .../ClearProsedurCacheListenerTest.php | 55 ++++++++++++++++++ 4 files changed, 178 insertions(+) create mode 100644 app/Events/ProsedurChanged.php create mode 100644 app/Listeners/ClearProsedurCacheListener.php create mode 100644 tests/Unit/Listeners/ClearProsedurCacheListenerTest.php diff --git a/app/Events/ProsedurChanged.php b/app/Events/ProsedurChanged.php new file mode 100644 index 000000000..3d17be438 --- /dev/null +++ b/app/Events/ProsedurChanged.php @@ -0,0 +1,55 @@ +prosedur = $prosedur; + } +} diff --git a/app/Listeners/ClearProsedurCacheListener.php b/app/Listeners/ClearProsedurCacheListener.php new file mode 100644 index 000000000..9ec17c2df --- /dev/null +++ b/app/Listeners/ClearProsedurCacheListener.php @@ -0,0 +1,57 @@ +removeCachePrefix($prefix); + } catch (\Exception $e) { + Log::error('Exception occurred while clearing prosedur cache', [ + 'message' => $e->getMessage(), + ]); + } + } +} diff --git a/app/Models/Prosedur.php b/app/Models/Prosedur.php index d1a618d31..7d96b7588 100644 --- a/app/Models/Prosedur.php +++ b/app/Models/Prosedur.php @@ -31,6 +31,7 @@ namespace App\Models; +use App\Events\ProsedurChanged; use App\Traits\HandlesResourceDeletion; use Illuminate\Database\Eloquent\Model; use Cviebrock\EloquentSluggable\Sluggable; @@ -44,6 +45,16 @@ class Prosedur extends Model protected $table = 'das_prosedur'; + /** + * Register model lifecycle hooks. + */ + protected static function booted(): void + { + static::created(fn (Prosedur $prosedur) => ProsedurChanged::dispatch($prosedur)); + static::updated(fn (Prosedur $prosedur) => ProsedurChanged::dispatch($prosedur)); + static::deleted(fn (Prosedur $prosedur) => ProsedurChanged::dispatch($prosedur)); + } + protected $fillable = [ 'judul_prosedur', 'file_prosedur', diff --git a/tests/Unit/Listeners/ClearProsedurCacheListenerTest.php b/tests/Unit/Listeners/ClearProsedurCacheListenerTest.php new file mode 100644 index 000000000..a3a6e5d69 --- /dev/null +++ b/tests/Unit/Listeners/ClearProsedurCacheListenerTest.php @@ -0,0 +1,55 @@ +shouldReceive('removeCachePrefix') + ->once() + ->with('prosedur:api') + ->andReturnTrue(); + + $this->app->instance(CacheService::class, $cacheService); + + $listener = new ClearProsedurCacheListener(); + $event = new ProsedurChanged(new Prosedur()); + + $listener->handle($event); +}); + +it('reads correct cache prefix from config', function () { + config(['theme-api.prosedur.cache_prefix' => 'custom:prosedur']); + + $cacheService = Mockery::mock(CacheService::class); + $cacheService->shouldReceive('removeCachePrefix') + ->once() + ->with('custom:prosedur') + ->andReturnTrue(); + + $this->app->instance(CacheService::class, $cacheService); + + $listener = new ClearProsedurCacheListener(); + $event = new ProsedurChanged(new Prosedur()); + + $listener->handle($event); +}); + +it('handles exception gracefully', function () { + $cacheService = Mockery::mock(CacheService::class); + $cacheService->shouldReceive('removeCachePrefix') + ->once() + ->andThrow(new \Exception('Cache error')); + + $this->app->instance(CacheService::class, $cacheService); + + \Illuminate\Support\Facades\Log::shouldReceive('error')->once(); + + $listener = new ClearProsedurCacheListener(); + $event = new ProsedurChanged(new Prosedur()); + + // Should not throw exception + $listener->handle($event); +});