diff --git a/app/Enums/Modul.php b/app/Enums/Modul.php index 24027cdd..eb1f1a2e 100644 --- a/app/Enums/Modul.php +++ b/app/Enums/Modul.php @@ -19,104 +19,85 @@ final class Modul extends Enum const Menu = [ [ - 'text' => 'Kependudukan', + 'text' => 'Profile Kependudukan', 'icon' => 'fa fa-users', - 'permission' => 'kependudukan', + 'permission' => 'datapokok', 'submenu' => [ [ - 'icon' => 'fas fa-angle-right', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Penduduk', 'url' => 'penduduk', 'permission' => 'penduduk', ], - ], - ], - [ - 'text' => 'Data Pokok', - 'icon' => 'fas fa-chart-pie', - 'permission' => 'datapokok', - 'submenu' => [ [ - 'icon' => 'fas fa-angle-right', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Data Agama & Adat', 'url' => 'data-pokok/agama-adat', 'permission' => 'datapokok-agama-adat', ], [ - 'icon' => 'fas fa-angle-right', - 'text' => 'Data Infrastruktur', - 'url' => 'data-pokok/infrastruktur', - 'permission' => 'datapokok-infrastruktur', - ], - [ - 'icon' => 'fas fa-angle-right', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Kesehatan', 'url' => 'data-pokok/kesehatan', 'permission' => 'datapokok-kesehatan', ], [ - 'icon' => 'fas fa-angle-right', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Pendidikan', 'url' => 'data-pokok/pendidikan', 'permission' => 'datapokok-pendidikan', ], [ - 'icon' => 'fas fa-angle-right', - 'text' => 'Pariwisata', - 'url' => 'data-pokok/pariwisata', - 'permission' => 'datapokok-pariwisata', - ], - [ - 'icon' => 'fas fa-angle-right', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Ketenagakerjaan', 'url' => 'data-pokok/ketenagakerjaan', 'permission' => 'datapokok-ketenagakerjaan', ], [ - 'icon' => 'fas fa-angle-right', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Jaminan Sosial', 'url' => 'data-pokok/jaminan-sosial', 'permission' => 'datapokok-jaminan-sosial', ], [ - 'icon' => 'fas fa-angle-right', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Data Papan', 'url' => 'satu-data/dtks/papan', 'permission' => 'datapokok-papan', ], [ - 'icon' => 'fas fa-angle-right', - 'text' => 'Kepemilihan Lahan & Produksi', - 'url' => 'prodeskel/ddk/pangan', - 'permission' => 'prodeskel-ddk-pangan', + 'text' => 'Penerima Bantuan', + 'icon' => 'far fa-fw fa-circle', + 'url' => 'bantuan', + 'permission' => 'bantuan', ], ], ], [ - 'text' => 'Statistik', + 'text' => 'Statistik Kependudukan', 'icon' => 'fas fa-chart-pie', 'permission' => 'statistik', 'submenu' => [ [ - 'icon' => 'fas fa-angle-right', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Penduduk', 'url' => 'statistik/penduduk', 'permission' => 'statistik-penduduk', ], [ - 'icon' => 'fas fa-angle-right', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Keluarga', 'url' => 'statistik/keluarga', 'permission' => 'statistik-keluarga', ], [ - 'icon' => 'fas fa-angle-right', + 'icon' => 'far fa-fw fa-circle', 'text' => 'RTM', 'url' => 'statistik/rtm', 'permission' => 'statistik-rtm', ], [ - 'icon' => 'fas fa-angle-right', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Bantuan', 'url' => 'statistik/bantuan', 'permission' => 'statistik-bantuan', @@ -125,63 +106,36 @@ final class Modul extends Enum ], ], [ - 'text' => 'Bantuan', - 'icon' => 'fas fa-handshake', - 'url' => 'bantuan', - 'permission' => 'bantuan', - ], - [ - 'text' => 'Data Suplemen', 'icon' => 'fa fa-users', - 'url' => 'suplemen', - 'permission' => 'suplemen', + 'text' => 'Pariwisata', + 'url' => 'data-pokok/pariwisata', + 'permission' => 'datapokok-pariwisata', ], - [ - 'text' => 'Master Data', - 'icon' => 'fa fa-tags', - 'permission' => 'master-data', - 'submenu' => [ - [ - 'icon' => 'fas fa-angle-right', - 'text' => 'Bantuan', - 'url' => 'master/bantuan', - 'permission' => 'master-data-bantuan', - ], - [ - 'icon' => 'fas fa-angle-right', - 'text' => 'Kategori Artikel', - 'url' => 'master/kategori/0', - 'permission' => 'master-data-artikel', - ], - ], - ], - - [ - 'text' => 'Organisasi', + 'text' => 'SOTK', 'icon' => 'fa fa-tags', 'permission' => 'organisasi', 'submenu' => [ [ - 'icon' => 'fa fa-building', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Departemen', 'url' => 'departments', 'permission' => 'organisasi-departemen', ], [ - 'icon' => 'fa fa-star', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Jabatan', 'url' => 'positions', 'permission' => 'organisasi-position', ], [ - 'icon' => 'fa fa-users', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Pejabat Daerah', 'url' => 'employees', 'permission' => 'organisasi-employee', ], [ - 'icon' => 'fa fa-sitemap', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Struktur Bagan', 'url' => 'orgchart', 'permission' => 'organisasi-chart', @@ -189,48 +143,74 @@ final class Modul extends Enum ], ], [ - 'text' => 'Modul Web', + 'text' => 'Pengaturan OpenSID', + 'icon' => 'fa fa-tags', + 'permission' => 'pengaturan-opensid', + 'submenu' => [ + [ + 'icon' => 'far fa-fw fa-circle', + 'text' => 'Program Bantuan', + 'url' => 'master/bantuan', + 'permission' => 'master-data-bantuan', + ], + [ + 'text' => 'Data Suplemen', + 'icon' => 'far fa-fw fa-circle', + 'url' => 'suplemen', + 'permission' => 'suplemen', + ], + + [ + 'icon' => 'far fa-fw fa-circle', + 'text' => 'Kategori Artikel', + 'url' => 'master/kategori/0', + 'permission' => 'master-data-artikel', + ], + ], + ], + [ + 'text' => 'Pengaturan Web', 'icon' => 'fa fa-globe', 'permission' => 'website', 'submenu' => [ [ - 'icon' => 'fas fa-bars', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Menu Website', 'url' => 'cms/menus', 'permission' => 'website-menu', ], [ - 'icon' => 'fas fa-file-text', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Halaman', 'url' => 'cms/pages', 'permission' => 'website-pages', ], [ - 'icon' => 'fas fa-list', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Artikel', 'url' => 'cms/articles', 'permission' => 'website-article', ], [ - 'icon' => 'fas fa-folder', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Kategori Artikel', 'url' => 'cms/categories', 'permission' => 'website-categories', ], [ - 'icon' => 'fas fa-image', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Slider', 'url' => 'cms/slides', 'permission' => 'website-slider', ], [ - 'icon' => 'fas fa-download', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Daftar Unduhan', 'url' => 'cms/downloads', 'permission' => 'website-downloads', ], [ - 'icon' => 'fas fa-chart-line', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Statistik Pengunjung', 'url' => 'cms/statistik', 'permission' => 'website-statistik', @@ -238,42 +218,54 @@ final class Modul extends Enum ], ], [ - 'text' => 'Pengaturan', - 'icon' => 'fa fa-cog', - 'permission' => 'pengaturan', + 'text' => 'Pengaturan Pengguna', + 'icon' => 'fa fa-globe', + 'permission' => 'website', 'submenu' => [ [ - 'icon' => 'fas fa-cogs', - 'text' => 'Identitas', - 'url' => 'pengaturan/identitas', - 'permission' => 'pengaturan-identitas', - ], - [ - 'icon' => 'fas fa-user', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Pengguna', 'url' => 'pengaturan/users', 'permission' => 'pengaturan-users', ], [ - 'icon' => 'fas fa-users', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Grup', 'url' => 'pengaturan/groups', 'permission' => 'pengaturan-group', ], [ - 'icon' => 'fas fa-history', + 'icon' => 'far fa-fw fa-circle', 'text' => 'Riwayat Pengguna', 'url' => 'pengaturan/activities', 'permission' => 'pengaturan-activities', ], + ], + ], + [ + 'text' => 'Pengaturan Aplikasi', + 'icon' => 'fa fa-cog', + 'permission' => 'pengaturan', + 'submenu' => [ [ - 'icon' => 'fas fa-gear', + 'icon' => 'far fa-fw fa-circle', + 'text' => 'Identitas', + 'url' => 'pengaturan/identitas', + 'permission' => 'pengaturan-identitas', + ], + [ + 'icon' => 'far fa-fw fa-circle', 'text' => 'Aplikasi', 'url' => 'pengaturan/settings', 'permission' => 'pengaturan-settings', ], + [ + 'icon' => 'far fa-fw fa-circle', + 'text' => 'OpenDK', + 'url' => 'pengaturan/opendk', + 'permission' => 'pengaturan-opendk', + ], ], ], - ]; } diff --git a/app/Helpers/general.php b/app/Helpers/general.php index 8df81477..3937e89d 100644 --- a/app/Helpers/general.php +++ b/app/Helpers/general.php @@ -27,9 +27,6 @@ 'time' => 'Input Jam', 'textarea' => 'Text Area', 'select-manual' => 'Pilihan (Kustom)', - 'select-otomatis' => 'Pilihan (Referensi)', - 'hari' => 'Input Hari', - 'hari-tanggal' => 'Input Hari dan Tanggal', ])); if (! function_exists('openkab_versi')) { @@ -38,7 +35,7 @@ */ function openkab_versi() { - return 'v2501.0.0'; + return 'v2502.0.0'; } } @@ -318,7 +315,7 @@ function generateMenuPresisi($tree, $parentId = null) $result .= "{$icon}{$item->text}"; } else { $href = $item->href; - if ($href != '/presisi' and $href != '/presisi/kesehatan') { + if ($href != '/presisi' and $href != '/presisi/kesehatan' and $href != '/presisi/geo-spasial') { $href = str_contains($item->href, 'module') ? $item->href : '/'.$item->href; } $result .= "{$icon}{$item->text}"; @@ -897,3 +894,62 @@ function selected($value, $selected) } } } + +if (! function_exists('convertMenu')) { + /** + * Helper untuk menentukan convert menu agar sesuai dengan editor. + * + * @param mixed $value + * @param mixed $checked + * + * @return string + */ + function convertMenu($menu, $parentId = null, &$idCounter = 1) + { + $convertedMenu = [ + 'id' => $idCounter++, + 'parent_id' => $parentId, + 'text' => $menu['text'] ?? 'text', + 'href' => $menu['url'] ?? null, + 'icon' => $menu['icon'], + 'permission' => $menu['permission'], + ]; + + if (isset($menu['submenu']) && is_array($menu['submenu'])) { + $convertedMenu['children'] = []; + foreach ($menu['submenu'] as $submenu) { + $convertedMenu['children'][] = convertMenu($submenu, $convertedMenu['id'], $idCounter); + } + } + + return $convertedMenu; + } +} + +if (! function_exists('convertDatabaseMenu')) { + /** + * Helper untuk menentukan convert menu untuk disimpan di database. + * + * @return array + */ + function convertDatabaseMenu($menu, $parentId = null, &$idCounter = 1) + { + $convertedMenu = [ + 'id' => $idCounter++, + 'parent_id' => $parentId, + 'text' => $menu['text'] ?? 'text', + 'url' => $menu['href'] ?? null, + 'icon' => $menu['icon'] ?? null, + 'permission' => $menu['permission'] ?? null, + ]; + + if (isset($menu['children']) && is_array($menu['children'])) { + $convertedMenu['submenu'] = []; + foreach ($menu['children'] as $submenu) { + $convertedMenu['submenu'][] = convertDatabaseMenu($submenu, $convertedMenu['id'], $idCounter); + } + } + + return $convertedMenu; + } +} diff --git a/app/Http/Controllers/Api/Auth/AuthController.php b/app/Http/Controllers/Api/Auth/AuthController.php index 583d735e..2619e488 100644 --- a/app/Http/Controllers/Api/Auth/AuthController.php +++ b/app/Http/Controllers/Api/Auth/AuthController.php @@ -91,4 +91,12 @@ protected function throttleKey() { return Str::lower(request('credential')).'|'.request()->ip(); } + + public function token() + { + $user = User::whereUsername('synchronize')->first(); + $token = $user->createToken('auth_token', ['synchronize-opendk-create'])->plainTextToken; + + return response()->json(['message' => 'Token Synchronize', 'access_token' => $token, 'token_type' => 'Bearer']); + } } diff --git a/app/Http/Controllers/Api/DesaController.php b/app/Http/Controllers/Api/DesaController.php new file mode 100644 index 00000000..efabd888 --- /dev/null +++ b/app/Http/Controllers/Api/DesaController.php @@ -0,0 +1,18 @@ +fractal($this->desa->list(), new DesaTransformer(), 'daftar desa')->respond(); + } +} diff --git a/app/Http/Controllers/Api/OpendkSynchronizeController.php b/app/Http/Controllers/Api/OpendkSynchronizeController.php new file mode 100644 index 00000000..c3e0641c --- /dev/null +++ b/app/Http/Controllers/Api/OpendkSynchronizeController.php @@ -0,0 +1,34 @@ +fractal($this->opendk->listSinkronisasi(), new OpendkSynchronizeTransformer(), 'daftar sinkronisasi')->respond(); + } + + public function getData(Request $request) + { + $namaKecamatan = $request->get('nama_kecamatan'); + $kodeKecamatan = $request->get('kode_kecamatan'); + OpendkSynchronize::upsert([ + ['nama_kecamatan' => $namaKecamatan, 'kode_kecamatan' => $kodeKecamatan], + ], ['kode_kecamatan']); + + return response()->json([ + 'message' => 'Berhasil mengambil data sinkronisasi', + ], Response::HTTP_OK); + } +} diff --git a/app/Http/Controllers/Api/SettingController.php b/app/Http/Controllers/Api/SettingController.php new file mode 100644 index 00000000..26cdea71 --- /dev/null +++ b/app/Http/Controllers/Api/SettingController.php @@ -0,0 +1,59 @@ +fractal($this->setting->listsetting(), new SettingTransformer(), 'daftar setting')->respond(); + } + + /** + * Update the specified resource in storage. + * + * @return \Illuminate\Http\Response + */ + public function update(Request $request) + { + try { + foreach ($request->all() as $key => $value) { + if ($key == 'opendk_api_key') { + $this->removeTokenSynchronize($value); + } + Setting::where('key', $key)->update(['value' => $value]); + activity('data-log')->event('updated')->withProperties($request)->log('setting Aplikasi'); + } + + return response()->json([ + 'success' => true, + ], Response::HTTP_OK); + } catch (\Exception $e) { + report($e); + + return response()->json([ + 'success' => false, + 'message' => $e->getMessage(), + ], Response::HTTP_INTERNAL_SERVER_ERROR); + } + } + + private function removeTokenSynchronize($token) + { + $user = User::whereUsername('synchronize')->first(); + $excludeToken = PersonalAccessToken::findToken($token); + $user->tokens()->where('id', '!=', $excludeToken->id)->delete(); + } +} diff --git a/app/Http/Controllers/Api/SuplemenController.php b/app/Http/Controllers/Api/SuplemenController.php index 90d244bc..119cc0d6 100644 --- a/app/Http/Controllers/Api/SuplemenController.php +++ b/app/Http/Controllers/Api/SuplemenController.php @@ -7,6 +7,7 @@ use App\Http\Transformers\SuplemenTerdataTransformer; use App\Http\Transformers\SuplemenTransformer; use App\Models\Suplemen; +use App\Models\SuplemenTerdata; use Illuminate\Http\Request; use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Validator; @@ -201,6 +202,26 @@ public function destroy($id) } } + public function delete_multiple(Request $request) + { + try { + // Hapus data yang terpilih + SuplemenTerdata::whereIn('id', $request->ids)->delete(); + + return response()->json([ + 'success' => true, + ], Response::HTTP_OK); + } catch (\Exception $e) { + // report($e); + + return response()->json([ + 'success' => false, + 'message' => '', + // 'message' => $e->getMessage(), + ], Response::HTTP_INTERNAL_SERVER_ERROR); + } + } + public function detail($sasaran, $id) { $suplemenData = $this->suplemen->listSuplemenTerdata($sasaran, $id); diff --git a/app/Http/Controllers/Api/TeamController.php b/app/Http/Controllers/Api/TeamController.php index 17dc9079..9d545230 100644 --- a/app/Http/Controllers/Api/TeamController.php +++ b/app/Http/Controllers/Api/TeamController.php @@ -146,6 +146,66 @@ public function menu() ], Response::HTTP_OK); } + public function updateMenu(Request $request, $id) + { + $team = Team::find($id); + $menuTeam = json_decode($request->menu_order, 1); + $menu = []; + foreach ($menuTeam as $menuItem) { + $menu[] = convertDatabaseMenu($menuItem, null, $idCounter); + } + $team->menu_order = $menu; + $team->save(); + + return response()->json([ + 'success' => true, + ], Response::HTTP_OK); + } + + public function listModul(Request $request) + { + $id = (int) $request->id; + $team = Team::find($id); + $idCounter = 1; // Initialize the ID counter + $menuTeam = $team->menu_order ?? $team->menu; + $menu = []; + foreach ($menuTeam as $menuItem) { + $menu[] = convertMenu($menuItem, null, $idCounter); + } + + $modul = collect($team->menu)->flatMap(function ($item) { + // Initialize an array to hold the results + $results = []; + + // If the item has a non-empty URL, add it to the results + if (! empty($item['url'])) { + $results[] = [ + 'text' => $item['text'].' ('.$item['url'].')', + 'url' => $item['url'], + ]; + } + + // If the item has a submenu, recursively process it + if (! empty($item['submenu'])) { + $results = array_merge($results, collect($item['submenu'])->flatMap(function ($submenuItem) { + return ! empty($submenuItem['url']) ? [ + [ + 'text' => $submenuItem['text'].' ('.$submenuItem['url'].')', + 'url' => $submenuItem['url'], + ], + ] : []; + })->toArray()); + } + + return $results; + })->values()->pluck('text', 'url')->toArray(); + + return response()->json([ + 'success' => true, + 'data' => ['modul' => $modul, 'menu' => $menu], + ], Response::HTTP_OK); + } + private function collectPermissions($data) { $permissions = []; diff --git a/app/Http/Controllers/GroupController.php b/app/Http/Controllers/GroupController.php index 2620d3c0..598e2855 100644 --- a/app/Http/Controllers/GroupController.php +++ b/app/Http/Controllers/GroupController.php @@ -2,6 +2,8 @@ namespace App\Http\Controllers; +use App\Models\Team; + class GroupController extends Controller { private $nama_aplikasi; @@ -24,11 +26,17 @@ public function index() public function create() { - return view('group.form'); + $listPermission = $this->generateListPermission(); + + return view('group.form')->with($listPermission)->with('isAdmin', false); } public function edit($id) { - return view('group.form', ['id' => $id]); + $listPermission = $this->generateListPermission(); + $team = Team::find($id); + $isAdmin = $team->name == 'administrator' ? true : false; + + return view('group.form', ['id' => $id])->with($listPermission)->with('isAdmin', $isAdmin); } } diff --git a/app/Http/Controllers/OpenDKController.php b/app/Http/Controllers/OpenDKController.php new file mode 100644 index 00000000..010d828e --- /dev/null +++ b/app/Http/Controllers/OpenDKController.php @@ -0,0 +1,30 @@ +generateListPermission(); + + return view('opendk.index')->with($listPermission); + } + + protected function getOptionItems($id = null) + { + return []; + } +} diff --git a/app/Http/Controllers/Web/PresisiController.php b/app/Http/Controllers/Web/PresisiController.php index 3423567a..6c66ff10 100644 --- a/app/Http/Controllers/Web/PresisiController.php +++ b/app/Http/Controllers/Web/PresisiController.php @@ -518,4 +518,25 @@ public function bantuan($id = '') return view('presisi.bantuan.index', compact('id', 'categoriesItems', 'statistik')); } + + /** + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ + public function geoSpasial() + { + $totalDesa = 0; + $pendudukSummary = 0; + $configSummary = 0; + $keluargaSummary = 0; + $categoriesItems = [ + ['key' => 'kecamatan', 'text' => 'kecamatan', 'value' => $configSummary, 'icon' => 'web/img/kecamatan.jpg'], + ['key' => 'desa', 'text' => 'desa/kelurahan', 'value' => $totalDesa, 'icon' => 'web/img/kelurahan.jpg'], + ['key' => 'penduduk', 'text' => 'jumlah penduduk', 'value' => $pendudukSummary, 'icon' => 'web/img/penduduk.jpg'], + ['key' => 'keluarga', 'text' => 'jumlah keluarga', 'value' => $keluargaSummary, 'icon' => 'web/img/bantuan.jpg'], + ]; + $listKecamatan = ['' => 'Pilih Kecamatan']; + $listDesa = ['' => 'Pilih Desa']; + + return view('presisi.geo_spasial.index', compact('categoriesItems', 'listKecamatan', 'listDesa')); + } } diff --git a/app/Http/Repository/DesaRepository.php b/app/Http/Repository/DesaRepository.php new file mode 100644 index 00000000..3cffe86a --- /dev/null +++ b/app/Http/Repository/DesaRepository.php @@ -0,0 +1,45 @@ +allowedFilters([ + AllowedFilter::exact('kode_kecamatan'), + AllowedFilter::exact('kode_desa'), + AllowedFilter::exact('id'), + AllowedFilter::callback('search', function ($query, $value) { + $query->where(function ($query) use ($value) { + $query->orWhere('nama_desa', 'like', "%{$value}%"); + $query->orWhere('kode_desa', 'like', "%{$value}%"); + $query->orWhere('website', 'like', "%{$value}%"); + }); + }), + ])->allowedSorts([ + 'kode_kecamatan', + 'kode_desa', + 'nama_desa', + 'website', + ]) + ->allowedFields([ + 'id', + 'kode_kecamatan', + 'nama_kecamatan', + 'kode_pos', + 'kode_desa', + 'nama_desa', + 'website', + 'path', + 'lat', + 'lng', + ]) + ->jsonPaginate(); + } +} diff --git a/app/Http/Repository/OpendkSynchronizeRepository.php b/app/Http/Repository/OpendkSynchronizeRepository.php new file mode 100644 index 00000000..6adcd264 --- /dev/null +++ b/app/Http/Repository/OpendkSynchronizeRepository.php @@ -0,0 +1,40 @@ +fieldSearchable; + } + + public function model(): string + { + return OpendkSynchronize::class; + } + + public function listSinkronisasi() + { + return QueryBuilder::for($this->model()) + ->allowedFields('*') + ->allowedFilters([ + AllowedFilter::callback('search', function ($query, $value) { + $query->where(function ($q) use ($value) { + $q->orWhere('kode_kecamatan', 'LIKE', '%'.$value.'%'); + $q->orWhere('nama_kecamatan', 'LIKE', '%'.$value.'%'); + }); + }), + ])->allowedSorts($this->getFieldsSearchable()) + ->jsonPaginate(); + } +} diff --git a/app/Http/Repository/SettingRepository.php b/app/Http/Repository/SettingRepository.php index ee468a6f..7b828d2c 100644 --- a/app/Http/Repository/SettingRepository.php +++ b/app/Http/Repository/SettingRepository.php @@ -42,6 +42,12 @@ public function listSetting() $q->orWhere('description', 'LIKE', '%'.$value.'%'); }); }), + AllowedFilter::callback('notkey', function ($query, $value) { + $query->whereNotIn('key', $value); + }), + AllowedFilter::callback('key', function ($query, $value) { + $query->whereIn('key', $value); + }), ])->allowedSorts($this->getFieldsSearchable()) ->jsonPaginate(); } diff --git a/app/Http/Transformers/DesaTransformer.php b/app/Http/Transformers/DesaTransformer.php new file mode 100644 index 00000000..c4e10b76 --- /dev/null +++ b/app/Http/Transformers/DesaTransformer.php @@ -0,0 +1,31 @@ +load('sebutanDesa'); + + return [ + 'id' => $config->id, + 'nama_desa' => $config->nama_desa, + 'kode_desa' => $config->kode_desa, + 'kode_pos' => $config->kode_pos, + 'nama_kecamatan' => $config->nama_kecamatan, + 'kode_kecamatan' => $config->kode_kecamatan, + 'website' => $config->website, + 'path' => $config->path, + 'sebutan_desa' => $config->sebutanDesa->value ?? '', + ]; + } +} diff --git a/app/Http/Transformers/OpendkSynchronizeTransformer.php b/app/Http/Transformers/OpendkSynchronizeTransformer.php new file mode 100644 index 00000000..dd5079f2 --- /dev/null +++ b/app/Http/Transformers/OpendkSynchronizeTransformer.php @@ -0,0 +1,19 @@ + $sync->id, + 'nama_kecamatan' => $sync->nama_kecamatan, + 'kode_kecamatan' => $sync->kode_kecamatan, + 'updated_at' => $sync->updated_at->format('d M Y, H:i:s'), + ]; + } +} diff --git a/app/Listeners/MenuListener.php b/app/Listeners/MenuListener.php index 884478d6..0ac8f092 100644 --- a/app/Listeners/MenuListener.php +++ b/app/Listeners/MenuListener.php @@ -107,7 +107,8 @@ public function handle(BuildingMenu $event) // tambahkan menu dari group $user = auth()->user(); if ($user) { - foreach ($user->team->first()?->menu ?? [] as $menu) { + $menuTeam = $user->team->first()?->menu_order ?? $user->team->first()?->menu; + foreach ($menuTeam ?? [] as $menu) { $event->menu->add($menu); } } diff --git a/app/Models/Config.php b/app/Models/Config.php index 36f8c186..b5bb2bd8 100644 --- a/app/Models/Config.php +++ b/app/Models/Config.php @@ -94,4 +94,12 @@ public function scopeOrderByTraffic($query) { return $query->orderByRaw('(SELECT sum(jumlah) FROM sys_traffic WHERE config_id = config.id) DESC'); } + + /** + * Get the sebutanDesa associated with the Config. + */ + public function sebutanDesa(): HasOne + { + return $this->hasOne(SettingAplikasi::class, 'config_id', 'id')->where('key', 'sebutan_desa'); + } } diff --git a/app/Models/OpendkSynchronize.php b/app/Models/OpendkSynchronize.php new file mode 100644 index 00000000..002b8b61 --- /dev/null +++ b/app/Models/OpendkSynchronize.php @@ -0,0 +1,24 @@ + 'json', + 'menu_order' => 'json', ]; public function role(): HasMany diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 0b364f49..0895a693 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -122,6 +122,14 @@ protected function bootConfigAdminLTE($identitasAplikasi, $settingAplikasi) $this->app->config['adminlte.title'] = $identitasAplikasi['nama_aplikasi']; $this->app->config['adminlte.title_postfix'] = "| {$identitasAplikasi['sebutan_kab']}"; $this->app->config['adminlte.logo'] = $identitasAplikasi['nama_aplikasi']; - $this->app->config['adminlte.layout_topnav'] = $settingAplikasi->get('layout_menu') !== 'Vertikal'; + if ($settingAplikasi->get('layout_menu') !== 'Vertikal') { + $this->app->config['adminlte.layout_topnav'] = true; + $this->app->config['adminlte.classes_content'] = 'col-12 p-3'; + $this->app->config['adminlte.classes_sidebar'] = 'sidebar-dark-primary elevation-4'; + $this->app->config['adminlte.classes_topnav'] = 'navbar-white navbar-light p-0'; + $this->app->config['adminlte.classes_topnav_nav'] = 'navbar-expand-lg'; + $this->app->config['adminlte.classes_topnav_container'] = 'container col-lg-12 p-2 pl-4'; + $this->app->config['adminlte.classes_content_header'] = 'container ml-3'; + } } } diff --git a/catatan_rilis.md b/catatan_rilis.md index 656ba6d4..b908500e 100644 --- a/catatan_rilis.md +++ b/catatan_rilis.md @@ -1,4 +1,4 @@ -Di rilis ini, versi 2501.0.0 berisi penambahan filter wilayah pada estunting dan perbaikan lain yang diminta pengguna. +Di rilis ini, versi 2502.0.0 berisi penambahan filter wilayah pada estunting dan perbaikan lain yang diminta pengguna. #### Penambahan Fitur @@ -7,8 +7,19 @@ Di rilis ini, versi 2501.0.0 berisi penambahan filter wilayah pada estunting dan 3. [#381](https://github.com/OpenSID/OpenKab/issues/381) Penambahan statistik penduduk berdasarkan pengaturan menu. 4. [#470](https://github.com/OpenSID/OpenKab/issues/470) Penambahan tombol data selengkapnya pada detail suplemen terdata dan pada export data. 5. [#477](https://github.com/OpenSID/OpenKab/issues/477) Penambahan pengaturan menu yang tampil bisa vertikal & horizontal. +6. [#475](https://github.com/OpenSID/OpenKab/issues/475) Penambahan fungsi multiple hapus pada halaman suplemen terdata. +7. [#489](https://github.com/OpenSID/OpenKab/issues/489) Penambahan fungsi pengaturan menu pada halaman admin. +8. [#491](https://github.com/OpenSID/OpenKab/issues/491) Penambahan halaman geo spasial. +9. [#480](https://github.com/OpenSID/OpenKab/issues/480) Penambahan preview data suplemen. +10. [#501](https://github.com/OpenSID/OpenKab/issues/501) Penambahan pengaturan token api key OpenDK. +11. [#502](https://github.com/OpenSID/OpenKab/issues/502) Penambahan API kebutuhan untuk mengambil identitas desa dengan parameter kode kecamatan dari OpenDK. #### Perbaikan BUG +1. [#485](https://github.com/OpenSID/OpenKab/issues/485) Perbaikan terkait menu pilih aksi pada OpenKab tidak berfungsi. #### Perubahan Teknis + +1. [#482](https://github.com/OpenSID/OpenKab/issues/482) Susun ulang urutan menu pada OpenKab. +2. [#487](https://github.com/OpenSID/OpenKab/issues/487) Rapikan tampilan menu horizontal. +3. [#490](https://github.com/OpenSID/OpenKab/issues/490) Hapus menu yang tidak terpakai.  \ No newline at end of file diff --git a/database/factories/SuplemenTerdataFactory.php b/database/factories/SuplemenTerdataFactory.php new file mode 100644 index 00000000..dff7fb56 --- /dev/null +++ b/database/factories/SuplemenTerdataFactory.php @@ -0,0 +1,24 @@ + \App\Models\Config::factory()->create()->id ?? 1, + 'id_suplemen' => $this->faker->randomNumber(5), + 'id_terdata' => $this->faker->randomNumber(5), + 'keluarga_id' => $this->faker->randomNumber(5), + 'penduduk_id' => $this->faker->randomNumber(5), + 'sasaran' => $this->faker->randomElement([1, 0]), + 'keterangan' => $this->faker->sentence, + ]; + } +} diff --git a/database/migrations/2025_01_07_055323_update_menu_admin.php b/database/migrations/2025_01_07_055323_update_menu_admin.php new file mode 100644 index 00000000..389df806 --- /dev/null +++ b/database/migrations/2025_01_07_055323_update_menu_admin.php @@ -0,0 +1,27 @@ +longText('menu_order')->nullable()->after('menu'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('team', function (Blueprint $table) { + $table->dropColumn('menu_order'); + }); + } +}; diff --git a/database/migrations/2025_01_09_013033_hapus-menu-ekonomi.php b/database/migrations/2025_01_09_013033_hapus-menu-ekonomi.php new file mode 100644 index 00000000..c18174dc --- /dev/null +++ b/database/migrations/2025_01_09_013033_hapus-menu-ekonomi.php @@ -0,0 +1,27 @@ + di kolom name + DB::table('menus')->where('name', 'Ekonomi')->delete(); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + } +}; diff --git a/database/migrations/2025_01_09_015004_update-menu-geospasial.php b/database/migrations/2025_01_09_015004_update-menu-geospasial.php new file mode 100644 index 00000000..f3517ca9 --- /dev/null +++ b/database/migrations/2025_01_09_015004_update-menu-geospasial.php @@ -0,0 +1,27 @@ + di kolom name + DB::table('menus')->where('name', 'Geo Spasial')->update(['url' => '/presisi/geo-spasial']); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + } +}; diff --git a/database/migrations/2025_01_20_063621_create_user_synchronize.php b/database/migrations/2025_01_20_063621_create_user_synchronize.php new file mode 100644 index 00000000..c01bab8c --- /dev/null +++ b/database/migrations/2025_01_20_063621_create_user_synchronize.php @@ -0,0 +1,64 @@ + 'synchronize', + 'name' => 'Admin Sinkronisasi', + 'email' => 'synch@opendesa.id', + 'password' => 'synch@89!OK', + 'active' => StatusEnum::aktif, + ]); + + $team = Team::create([ + 'name' => 'synchronize', + 'menu' => [], + 'menu_order' => null, + ]); + + // joinkan user ke group + UserTeam::create([ + 'id_user' => $user->id, + 'id_team' => $team->id, + ]); + // assign role berdasarkan team + $role = Role::create( + [ + 'name' => $team->name, + 'team_id' => $team->id, + 'guard_name' => 'web', + ] + ); + setPermissionsTeamId($team->id); + $user->assignRole($role); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $team = Team::where('name', 'synchronize')->first(); + UserTeam::where('id_team', $team)->delete(); + $user = User::where('username', 'synchronize')->first(); + $user->delete(); + $team->role()->delete(); + $team->delete(); + } +}; diff --git a/database/migrations/2025_01_20_070417_create_setting_opendk.php b/database/migrations/2025_01_20_070417_create_setting_opendk.php new file mode 100644 index 00000000..17a3ff20 --- /dev/null +++ b/database/migrations/2025_01_20_070417_create_setting_opendk.php @@ -0,0 +1,45 @@ + 'Tidak Aktif', 'value' => 0], + ['text' => 'Aktif', 'value' => 1], + ]; + Setting::create([ + 'key' => 'opendk_synchronize', + 'name' => 'Status', + 'value' => 0, + 'type' => 'dropdown', + 'attribute' => $attribute, + 'description' => 'Pengaturan sinkronisasi dengan OpenDK', + ]); + Setting::create([ + 'key' => 'opendk_api_key', + 'name' => 'API Key', + 'value' => '', + 'type' => 'textarea', + 'description' => 'Pengaturan API Key Untuk Sinkronisasi OpenDK', + ]); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Setting::whereIn('key', ['opendk_synchronize', 'opendk_api_key'])->delete(); + } +}; diff --git a/database/migrations/2025_01_20_071023_update_menu_admin.php b/database/migrations/2025_01_20_071023_update_menu_admin.php new file mode 100644 index 00000000..57872079 --- /dev/null +++ b/database/migrations/2025_01_20_071023_update_menu_admin.php @@ -0,0 +1,74 @@ + 'far fa-fw fa-circle', + 'text' => 'OpenDK', + 'url' => 'pengaturan/opendk', + 'permission' => 'pengaturan-opendk', + ]; + $team = Team::where('name', 'administrator')->first(); + $menuOrder = $team->menu_order ?? []; + if (! $menuOrder) { + return; + } + $menuOrderBaru = collect($menuOrder)->map(function ($item) use ($menuBaru) { + if ($item['text'] == 'Pengaturan') { + if (! isset($item['submenu'])) { + $item['submenu'] = []; + } + $menuBaru['parent_id'] = $item['id']; + $item['submenu'][] = $menuBaru; + } + + return $item; + })->toArray(); + $team->menu_order = $menuOrderBaru; + $team->save(); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $menuBaru = [ + 'icon' => 'far fa-fw fa-circle', + 'text' => 'OpenDK', + 'url' => 'pengaturan/opendk', + 'permission' => 'pengaturan-opendk', + ]; + $team = Team::where('name', 'administrator')->first(); + $menuOrder = $team->menu_order ?? []; + if (! $menuOrder) { + return; + } + $menuOrderBaru = collect($menuOrder)->map(function ($item) use ($menuBaru) { + if ($item['text'] === 'Pengaturan') { + $item['submenu'] = collect($item['submenu'])->filter(function ($submenu) use ($menuBaru) { + return $submenu['url'] !== $menuBaru['url']; + })->toArray(); + } + + return $item; + })->toArray(); + + $team->menu_order = $menuOrderBaru; + $team->save(); + } +}; diff --git a/database/migrations/2025_01_20_135841_create_table_opendk_synchronize.php b/database/migrations/2025_01_20_135841_create_table_opendk_synchronize.php new file mode 100644 index 00000000..55a3b12e --- /dev/null +++ b/database/migrations/2025_01_20_135841_create_table_opendk_synchronize.php @@ -0,0 +1,33 @@ +id(); + $table->string('kode_kecamatan', 8)->unique(); + $table->string('nama_kecamatan', 60); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('opendk_synchronize'); + } +}; diff --git a/resources/views/bantuan/index.blade.php b/resources/views/bantuan/index.blade.php index 5123c70e..320e26e1 100644 --- a/resources/views/bantuan/index.blade.php +++ b/resources/views/bantuan/index.blade.php @@ -148,8 +148,10 @@ className: 'text-nowrap', { data: function(data) { return ` - - ` + + `; + + }, }, { diff --git a/resources/views/group/akses.blade.php b/resources/views/group/akses.blade.php new file mode 100644 index 00000000..cf7ec30a --- /dev/null +++ b/resources/views/group/akses.blade.php @@ -0,0 +1,111 @@ +
+
+
+
+ +
+
+
+ + +
+
+ +
+ + + + + + + + + + + + + + + + +
NoNama ModulHak Akses
BacaTulisUbahHapus
+
+
+ + +
+
+
+
+@if(isset($id)) + @include('group.edit_js', ['id' => $id]) +@else + @include('group.create_js') +@endif \ No newline at end of file diff --git a/resources/views/group/fields.blade.php b/resources/views/group/fields.blade.php new file mode 100644 index 00000000..ff74e794 --- /dev/null +++ b/resources/views/group/fields.blade.php @@ -0,0 +1,56 @@ + +
+
+ {!! Form::text('text', null, ['class' => 'form-control item-menu', 'maxlength' => 255, 'placeholder' => 'Nama Menu']) !!}
+
+
+ + +
+
+ + +
+
+ + +
+
+ {!! Form::select('sourcelist', [], null, ['class' => 'form-control']) !!} + {!! Form::text('href', null, ['class' => 'form-control item-menu', 'maxlength' => 255, 'placeholder' => 'http://contoh.com']) !!} +
+
+ +@push('js') + +@endpush diff --git a/resources/views/group/form.blade.php b/resources/views/group/form.blade.php index 50df6630..0f086cd7 100644 --- a/resources/views/group/form.blade.php +++ b/resources/views/group/form.blade.php @@ -8,100 +8,39 @@ @section('content') @include('partials.breadcrumbs') -
-
-
- -
- -
-
-
- - -
-
- -
- - - - - - - - - - - - - - - - -
- NoNama ModulHak Akses
BacaTulisUbahHapus
-
-
- - -
+ @if(!$isAdmin) +
+ @include('group.akses') +
+ @endif +
+
- @if(isset($id)) - @include('group.edit_js', ['id' => $id]) - @else - @include('group.create_js') - @endif - + @endsection diff --git a/resources/views/group/index.blade.php b/resources/views/group/index.blade.php index 8b99b73f..d023e9ec 100644 --- a/resources/views/group/index.blade.php +++ b/resources/views/group/index.blade.php @@ -38,8 +38,6 @@ - - @@ -74,10 +72,7 @@ data: null, }, { - data: function(data) { - if (data.attributes.name == 'administrator') { - return ``; - } + data: function(data) { let canEdit = `{{ $canedit }}` let canDelete = `{{ $candelete }}` let buttonEdit = canEdit ? ` @@ -88,6 +83,9 @@ let buttonDelete = canDelete ? `` : ``; + if (data.attributes.name == 'administrator') { + buttonDelete = ''; + } return `${buttonEdit} ${buttonDelete}`; }, }, diff --git a/resources/views/group/menu.blade.php b/resources/views/group/menu.blade.php new file mode 100644 index 00000000..74e4ec89 --- /dev/null +++ b/resources/views/group/menu.blade.php @@ -0,0 +1,182 @@ +
+
+
+
+
+ {!! Form::open(['id' => 'frmEdit']) !!} +
+
+
+
Sumber Menu URL
+
+ @include('group.fields') +
+ @if ($canwrite) + + @endif +
+
+
+
+
Struktur Menu
+
+
    +
    + {!! Form::textarea('json_menu', null, ['hidden', 'rows' => 1]) !!} +
    +
    + @if ($canwrite) + + @endif +
    +
    +
    + {!! Form::close() !!} +
    +
    +
    +
    +
    + +@push('js') + + + +@endpush diff --git a/resources/views/layouts/presisi/partials/sidebarmenu.blade.php b/resources/views/layouts/presisi/partials/sidebarmenu.blade.php index 20a7a00b..5f4c9cd7 100644 --- a/resources/views/layouts/presisi/partials/sidebarmenu.blade.php +++ b/resources/views/layouts/presisi/partials/sidebarmenu.blade.php @@ -22,13 +22,6 @@

    -
  • + var pindah = (data.attributes.status_dasar == 1) ? '' : 'disabled'; + let pindahMenu = `
  • Pindah Penduduk -
  • ` : ``; + `; return `
    -
    ` + `; } }, { diff --git a/resources/views/presisi/geo_spasial/index.blade.php b/resources/views/presisi/geo_spasial/index.blade.php new file mode 100644 index 00000000..854de856 --- /dev/null +++ b/resources/views/presisi/geo_spasial/index.blade.php @@ -0,0 +1,189 @@ +@extends('layouts.presisi.index') + +@section('content_header') +@stop +@section('content') + @include('presisi.partials.head') + +
    +
    + +
    + @include('presisi.summary') +
    + @include('presisi.wilayah.filter') + + @include('presisi.wilayah.peta') + +
    +
    +
    + + @include('presisi.wilayah.data-wilayah') + + @include('presisi.wilayah.data-desa') + + + +
    + +@endsection + +@push('styles') + +@endpush +@push('js') + + +@endpush diff --git a/resources/views/presisi/partials/head.blade.php b/resources/views/presisi/partials/head.blade.php index 9fff618d..6ff1c3e8 100644 --- a/resources/views/presisi/partials/head.blade.php +++ b/resources/views/presisi/partials/head.blade.php @@ -66,10 +66,6 @@ - - Ekonomi - - E-Stunting diff --git a/resources/views/settings/index.blade.php b/resources/views/settings/index.blade.php index 97f9d8c2..0e79a174 100644 --- a/resources/views/settings/index.blade.php +++ b/resources/views/settings/index.blade.php @@ -44,6 +44,7 @@ "page[size]": row.length, "page[number]": (row.start / row.length) + 1, "filter[search]": row.search.value, + "filter[notkey]" : ['opendk_synchronize','opendk_api_key'], "sort": (row.order[0]?.dir === "asc" ? "" : "-") + row.columns[row.order[0]?.column] ?.name, }; diff --git a/resources/views/suplemen/detail.blade.php b/resources/views/suplemen/detail.blade.php index 9860d1d5..b683110f 100644 --- a/resources/views/suplemen/detail.blade.php +++ b/resources/views/suplemen/detail.blade.php @@ -12,6 +12,7 @@ @include('partials.breadcrumbs') @include('partials.flash_message') @include('layouts.components.selec2_wilayah_referensi') +
    @@ -25,11 +26,8 @@ @include('layouts.components.tombol_ekspor', [ 'ekspor' => "suplemen/ekspor/{$id}", ]) - Hapus + Hapus Kembali Ke Daftar Data Suplemen -
    @@ -43,8 +41,6 @@ class='fa fa-trash-o'
    @include('suplemen.table_terdata') - - @@ -53,12 +49,14 @@ class='fa fa-trash-o' @endsection @section('js') - @endsection + diff --git a/resources/views/suplemen/edit.blade.php b/resources/views/suplemen/edit.blade.php index 24a6c989..dc6691cb 100644 --- a/resources/views/suplemen/edit.blade.php +++ b/resources/views/suplemen/edit.blade.php @@ -79,6 +79,9 @@ +@include('suplemen.preview') + @endsection @section('js') @include('suplemen.edit_js') +@include('suplemen.preview_js') + @endsection diff --git a/resources/views/suplemen/form.blade.php b/resources/views/suplemen/form.blade.php index 54ae189f..b33b035c 100644 --- a/resources/views/suplemen/form.blade.php +++ b/resources/views/suplemen/form.blade.php @@ -69,13 +69,15 @@
    @include('suplemen.kode_isian') -
    +@include('suplemen.preview') + + @endsection @section('js') @include('suplemen.kode_isian_js') @include('suplemen.form_js') +@include('suplemen.preview_js') @endsection diff --git a/resources/views/suplemen/js/checkbox.blade.php b/resources/views/suplemen/js/checkbox.blade.php new file mode 100644 index 00000000..d65d151f --- /dev/null +++ b/resources/views/suplemen/js/checkbox.blade.php @@ -0,0 +1,22 @@ +// Select or deselect all checkboxes +$('#select-all').on('click', function() { + var checkboxes = $('#suplemen').find('.select-checkbox'); + var isChecked = $(this).prop('checked'); + checkboxes.prop('checked', isChecked); + toggleDeleteButton(); +}); + +// Track selected checkboxes +$('#suplemen').on('change', '.select-checkbox', function() { + toggleDeleteButton(); +}); + +// Toggle delete button visibility +function toggleDeleteButton() { + var selectedCheckboxes = $('#suplemen').find('.select-checkbox:checked'); + if (selectedCheckboxes.length > 0) { + $('#multiple-delete').removeClass('disabled'); + } else { + $('#multiple-delete').addClass('disabled'); + } +} \ No newline at end of file diff --git a/resources/views/suplemen/js/data_suplemen_terdata.blade.php b/resources/views/suplemen/js/data_suplemen_terdata.blade.php index 1e455bfc..61fcfe41 100644 --- a/resources/views/suplemen/js/data_suplemen_terdata.blade.php +++ b/resources/views/suplemen/js/data_suplemen_terdata.blade.php @@ -15,8 +15,7 @@ "page[size]": row.length, "page[number]": (row.start / row.length) + 1, "filter[search]": row.search.value, - "sort": (row.order[0]?.dir === "asc" ? "" : "-") + row.columns[row.order[0]?.column] - ?.name, + "sort": (row.order[0]?.dir === "asc" ? "" : "-") + row.columns[row.order[0]?.column]?.name, "filter[tweb_penduduk.sex]": $("#sex").val(), "filter[tweb_wil_clusterdesa.dusun]": $("#dusun").val(), "filter[tweb_wil_clusterdesa.rw]": $("#rw").val(), @@ -24,26 +23,28 @@ }; }, dataSrc: function(json) { - json.recordsTotal = json.meta.pagination.total - json.recordsFiltered = json.meta.pagination.total - return json.data + json.recordsTotal = json.meta.pagination.total; + json.recordsFiltered = json.meta.pagination.total; + return json.data; }, }, columnDefs: [{ - targets: '_all', - className: 'text-nowrap', - }, + targets: '_all', + className: 'text-nowrap', + }, { + targets: [0, 1, 2, 3, 4, 5], + orderable: false, + searchable: false, + }], + columns: [ { - targets: [0, 1, 2, 3, 4], - orderable: false, - searchable: false, + data: null, }, { - targets: [1], // Kolom "DETAIL" - visible: {!! $suplemen->form_isian ? 'true' : 'false' !!}, // Menyembunyikan atau menampilkan kolom berdasarkan kondisi - }], - columns: [{ data: null, + render: function(data, type, row) { + return ``; + }, }, { data: null, @@ -108,9 +109,9 @@ class: 'padat' }, ], order: [ - [9, 'asc'] + [10, 'asc'] ] -}) +}); suplemen.on('draw.dt', function() { var PageInfo = $('#suplemen').DataTable().page.info(); @@ -122,5 +123,5 @@ class: 'padat' }); $('#sex, #dusun, #rw, #rt').change(function() { - suplemen.draw() -}) + suplemen.draw(); +}); diff --git a/resources/views/suplemen/js/multiple_delete.blade.php b/resources/views/suplemen/js/multiple_delete.blade.php new file mode 100644 index 00000000..238d86ea --- /dev/null +++ b/resources/views/suplemen/js/multiple_delete.blade.php @@ -0,0 +1,62 @@ +// Perform multiple delete with SweetAlert +$('#multiple-delete').on('click', function(e) { + e.preventDefault(); + var selectedIds = []; + $('#suplemen').find('.select-checkbox:checked').each(function() { + selectedIds.push($(this).data('id')); + }); + + if (selectedIds.length > 0) { + // SweetAlert confirmation for delete action + Swal.fire({ + title: 'Konfirmasi Hapus', + text: "Apakah Anda yakin ingin menghapus data yang terpilih?", + icon: 'warning', + showCancelButton: true, + confirmButtonText: 'Hapus', + cancelButtonText: 'Batal' + }).then((result) => { + if (result.isConfirmed) { + // Show loading while performing the deletion + Swal.fire({ + title: 'Menyimpan', + didOpen: () => { + Swal.showLoading(); + }, + }); + + $.ajax({ + url: '{{ url("api/v1/suplemen/terdata/hapus") }}', + method: 'POST', + data: { + _token: '{{ csrf_token() }}', + ids: selectedIds, + }, + success: function(response) { + if (response.success) { + Swal.fire( + 'Hapus!', + 'Data berhasil dihapus', + 'success' + ); + suplemen.ajax.reload(); // Reload the DataTable + } else { + Swal.fire( + 'Gagal!', + 'Gagal menghapus data', + 'error' + ); + } + }, + error: function() { + Swal.fire( + 'Error!', + 'Terjadi kesalahan, coba lagi nanti', + 'error' + ); + } + }); + } + }); + } +}); \ No newline at end of file diff --git a/resources/views/suplemen/kode_isian.blade.php b/resources/views/suplemen/kode_isian.blade.php index 4c7900e5..0b7d3748 100644 --- a/resources/views/suplemen/kode_isian.blade.php +++ b/resources/views/suplemen/kode_isian.blade.php @@ -66,5 +66,4 @@ - - + \ No newline at end of file diff --git a/resources/views/suplemen/kode_isian_js.blade.php b/resources/views/suplemen/kode_isian_js.blade.php index 0cb20ef9..060451f9 100644 --- a/resources/views/suplemen/kode_isian_js.blade.php +++ b/resources/views/suplemen/kode_isian_js.blade.php @@ -192,5 +192,4 @@ $(this).parents('.duplikasi').find('.isian').val(''); }); }); - - \ No newline at end of file + diff --git a/resources/views/suplemen/preview.blade.php b/resources/views/suplemen/preview.blade.php new file mode 100644 index 00000000..4ba5bf84 --- /dev/null +++ b/resources/views/suplemen/preview.blade.php @@ -0,0 +1,41 @@ + \ No newline at end of file diff --git a/resources/views/suplemen/preview_js.blade.php b/resources/views/suplemen/preview_js.blade.php new file mode 100644 index 00000000..a94ed4de --- /dev/null +++ b/resources/views/suplemen/preview_js.blade.php @@ -0,0 +1,190 @@ + \ No newline at end of file diff --git a/resources/views/suplemen/table_terdata.blade.php b/resources/views/suplemen/table_terdata.blade.php index 398b5687..760499ce 100644 --- a/resources/views/suplemen/table_terdata.blade.php +++ b/resources/views/suplemen/table_terdata.blade.php @@ -3,6 +3,9 @@ NO + + + DETAIL {{ $suplemen->sasaran == 1 ? 'NO.' : 'NIK' }} KK {{ $suplemen->sasaran == 1 ? 'NIK PENDUDUK' : 'NO. KK' }} diff --git a/resources/views/vendor/adminlte/partials/navbar/navbar-layout-topnav.blade.php b/resources/views/vendor/adminlte/partials/navbar/navbar-layout-topnav.blade.php new file mode 100644 index 00000000..ae86ed81 --- /dev/null +++ b/resources/views/vendor/adminlte/partials/navbar/navbar-layout-topnav.blade.php @@ -0,0 +1,61 @@ + + +
    diff --git a/routes/apiv1.php b/routes/apiv1.php index ea341798..4b9ddb82 100644 --- a/routes/apiv1.php +++ b/routes/apiv1.php @@ -27,8 +27,12 @@ use Illuminate\Support\Facades\Route; use App\Http\Controllers\Api\PrasaranaSaranaController; use App\Http\Controllers\Api\BantuanKabupatenController; +use App\Http\Controllers\Api\DesaController; use App\Http\Controllers\Api\KelembagaanController; use App\Http\Controllers\Api\InfrastrukturController; +use App\Http\Controllers\Api\OpendkSynchronizeController; +use App\Http\Controllers\Api\SettingController; +use Illuminate\Support\Facades\Auth; /* |-------------------------------------------------------------------------- @@ -75,6 +79,7 @@ }); Route::middleware(['auth:sanctum'])->group(function () { + Route::get('/token', [AuthController::class, 'token']); Route::post('/logout', [AuthController::class, 'logOut']); Route::get('/user', function (Request $request) { return $request->user(); @@ -205,6 +210,13 @@ Route::post('/', 'store'); Route::put('/{id}', 'update'); Route::get('/menu', 'menu'); + Route::get('/listModul/{id}', 'listModul'); + Route::put('/updateMenu/{id}', 'updateMenu'); + }); + Route::controller(SettingController::class) + ->prefix('settings')->group(function () { + Route::get('/', 'index'); + Route::put('/{id}', 'update'); }); }); @@ -224,6 +236,19 @@ Route::prefix('satu-data')->group(function () { Route::get('dtks', DTKSController::class); }); + + // Sinkronisasi OpenDK + Route::prefix('opendk')->group(function () { + Route::get('', [OpendkSynchronizeController::class, 'index'])->name('synchronize.opendk.index'); + Route::middleware(['abilities:synchronize-opendk-create'])->group(function () { + Route::get('data', [OpendkSynchronizeController::class, 'getData']); + }); + }); + + Route::middleware(['abilities:synchronize-opendk-create'])->group(function () { + Route::get('desa', [DesaController::class, 'index']); + }); + }); // Statistik @@ -267,9 +292,10 @@ Route::get('data-summary', SummaryController::class); // Desa teraktif -Route::get('/desa-aktif', [KategoriDesaController::class, 'index']); +Route::get('desa-aktif', [KategoriDesaController::class, 'index']); Route::post('/suplemen', [SuplemenController::class, 'store']); +Route::post('/suplemen/terdata/hapus', [SuplemenController::class, 'delete_multiple'])->name('suplemen-terdata.delete-multiple'); Route::post('/suplemen/update/{id}', [SuplemenController::class, 'update']); Route::get('/suplemen', [SuplemenController::class, 'index']); Route::get('/suplemen/terdata/{sasaran}/{id}', [SuplemenController::class, 'detail']); diff --git a/routes/web.php b/routes/web.php index fd2af4f4..857222de 100644 --- a/routes/web.php +++ b/routes/web.php @@ -64,6 +64,7 @@ }); Route::resource('activities', RiwayatPenggunaController::class)->only(['index', 'show'])->middleware('easyauthorize:pengaturan-activities'); Route::resource('settings', App\Http\Controllers\SettingController::class)->except(['show', 'create', 'delete'])->middleware('easyauthorize:pengaturan-settings'); + Route::resource('opendk', App\Http\Controllers\OpenDKController::class)->except(['show', 'create', 'delete'])->middleware('easyauthorize:pengaturan-opendk'); }); Route::prefix('cms')->group(function () { @@ -223,4 +224,5 @@ Route::get('/kesehatan/{kuartal}/{tahun}/{id}/{kabupaten?}/{kecamatan?}/{desa?}', [PresisiController::class, 'kesehatan']); Route::get('/bantuan', [PresisiController::class, 'bantuan'])->name('presisi.bantuan'); Route::get('/statistik-bantuan', [PresisiController::class, 'bantuan'])->name('presisi.bantuan'); + Route::get('/geo-spasial', [PresisiController::class, 'geoSpasial'])->name('presisi.geo-spasial'); }); \ No newline at end of file diff --git a/tests/Feature/DesaControllerApiTest.php b/tests/Feature/DesaControllerApiTest.php new file mode 100644 index 00000000..707d318b --- /dev/null +++ b/tests/Feature/DesaControllerApiTest.php @@ -0,0 +1,49 @@ +first()->value; + $kecamatan = Config::inRandomOrder()->first()->kode_kecamatan; + $totalDesa = Config::where('kode_kecamatan', $kecamatan)->count(); + if (! $token) { + $this->fail('Token not found'); + } + $url = '/api/v1/desa?'.http_build_query([ + 'filter[kode_kecamatan]' => $kecamatan, + ]); + // Kirim permintaan delete_multiple dengan header Authorization + $response = $this->getJson($url, [ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + 'Authorization' => 'Bearer '.$token, + ]); + // Pastikan responsnya berhasil + $response->assertStatus(Response::HTTP_OK); + $response->assertJsonPath('meta.pagination.total', $totalDesa); + $response->assertJsonStructure([ + 'data' => [ + '*' => [ + 'attributes' => [ + 'kode_desa', + 'nama_desa', + 'sebutan_desa', + ], + ], + ], + ]); + } +} diff --git a/tests/Feature/ExampleTest.php b/tests/Feature/ExampleTest.php index 1eafba61..2a1e37ef 100644 --- a/tests/Feature/ExampleTest.php +++ b/tests/Feature/ExampleTest.php @@ -14,8 +14,10 @@ class ExampleTest extends TestCase */ public function test_the_application_returns_a_successful_response() { - $response = $this->get('/'); + $response = $this->withHeaders([ + 'Authorization' => 'Bearer '.session('api_token') ?? '', // Sesuaikan token jika perlu + ])->get('/'); - $response->assertStatus(200); + $response->assertStatus(302); } } diff --git a/tests/Feature/SuplemenTerdataTest.php b/tests/Feature/SuplemenTerdataTest.php new file mode 100644 index 00000000..48d3eba2 --- /dev/null +++ b/tests/Feature/SuplemenTerdataTest.php @@ -0,0 +1,63 @@ +create(); + $suplemen2 = SuplemenTerdata::factory()->create(); + + // Pastikan data awalnya ada di database + $this->assertDatabaseHas(SuplemenTerdata::class, ['id' => $suplemen1->id]); + $this->assertDatabaseHas(SuplemenTerdata::class, ['id' => $suplemen2->id]); + + // Kirim permintaan delete_multiple dengan header Authorization + $response = $this->postJson('/api/v1/suplemen/terdata/hapus', [ + 'ids' => [$suplemen1->id, $suplemen2->id], // Gunakan ID yang dihasilkan oleh factory + ], [ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + 'Authorization' => 'Bearer '.(session('api_token') ?? ''), + ]); + + // Pastikan responsnya berhasil + $response->assertStatus(Response::HTTP_OK) + ->assertJson(['success' => true]); + + // Pastikan data terhapus dari database + $this->assertDatabaseMissing(SuplemenTerdata::class, ['id' => $suplemen1->id]); + $this->assertDatabaseMissing(SuplemenTerdata::class, ['id' => $suplemen2->id]); + } + + /** + * Test delete_multiple function with invalid IDs. + */ + public function test_delete_multiple_with_invalid_ids() + { + // Kirim permintaan delete_multiple dengan ID yang tidak ada di database + $response = $this->postJson('/api/v1/suplemen/terdata/hapus', [ + 'ids' => [999, 1000], // IDs yang tidak valid + ], [ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + 'Authorization' => 'Bearer '.(session('api_token') ?? ''), + ]); + + // Pastikan responsnya berhasil meskipun tidak ada data yang dihapus + $response->assertStatus(Response::HTTP_OK) + ->assertJson(['success' => true]); + } +}