From 06caccf3cdfbd08c698526aa09599c5cf966db7d Mon Sep 17 00:00:00 2001 From: Khafid Prayoga Date: Mon, 15 Sep 2025 13:51:43 +0700 Subject: [PATCH] feat(subspecialist): add subspecialist management components and pages - Implement list view with pagination and search functionality - Create form for adding subspecialist entries - Add configuration for subspecialist data validation and dropdown options --- .../app/subspecialist/entry-form.vue | 213 ++++++++++++++++ app/components/app/subspecialist/list-cfg.ts | 56 ++++ app/components/app/subspecialist/list.vue | 31 +++ app/components/content/specialist/entry.ts | 2 +- app/components/content/specialist/list.vue | 4 +- app/components/content/subspecialist/entry.ts | 98 +++++++ app/components/content/subspecialist/list.vue | 241 ++++++++++++++++++ .../org-src/subspecialist/index.vue | 41 +++ 8 files changed, 683 insertions(+), 3 deletions(-) create mode 100644 app/components/app/subspecialist/entry-form.vue create mode 100644 app/components/app/subspecialist/list-cfg.ts create mode 100644 app/components/app/subspecialist/list.vue create mode 100644 app/components/content/subspecialist/entry.ts create mode 100644 app/components/content/subspecialist/list.vue create mode 100644 app/pages/(features)/org-src/subspecialist/index.vue diff --git a/app/components/app/subspecialist/entry-form.vue b/app/components/app/subspecialist/entry-form.vue new file mode 100644 index 00000000..9d31fd3f --- /dev/null +++ b/app/components/app/subspecialist/entry-form.vue @@ -0,0 +1,213 @@ + + + diff --git a/app/components/app/subspecialist/list-cfg.ts b/app/components/app/subspecialist/list-cfg.ts new file mode 100644 index 00000000..eb25f5d0 --- /dev/null +++ b/app/components/app/subspecialist/list-cfg.ts @@ -0,0 +1,56 @@ +import type { + Col, + KeyLabel, + RecComponent, + RecStrFuncComponent, + RecStrFuncUnknown, + Th, +} from '~/components/pub/custom-ui/data/types' +import { defineAsyncComponent } from 'vue' + +type SmallDetailDto = any + +const action = defineAsyncComponent(() => import('~/components/pub/custom-ui/data/dropdown-action-ud.vue')) + +export const cols: Col[] = [{ width: 100 }, {}, {}, {}, { width: 50 }] + +export const header: Th[][] = [ + [{ label: 'Id' }, { label: 'Nama' }, { label: 'Kode' }, { label: 'Specialist' }, { label: '' }], +] +export const keys = ['id', 'name', 'cellphone', 'religion_code', 'action'] + +export const delKeyNames: KeyLabel[] = [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, +] + +export const funcParsed: RecStrFuncUnknown = { + name: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return `${recX.firstName} ${recX.lastName || ''}`.trim() + }, + unit: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.unit?.name || '-' + }, + specialist: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.specialist?.name || '-' + }, +} + +export const funcComponent: RecStrFuncComponent = { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + props: { + size: 'sm', + }, + } + return res + }, +} + +export const funcHtml: RecStrFuncUnknown = {} diff --git a/app/components/app/subspecialist/list.vue b/app/components/app/subspecialist/list.vue new file mode 100644 index 00000000..e9489ef1 --- /dev/null +++ b/app/components/app/subspecialist/list.vue @@ -0,0 +1,31 @@ + + + diff --git a/app/components/content/specialist/entry.ts b/app/components/content/specialist/entry.ts index 9dc0a54f..c89302c2 100644 --- a/app/components/content/specialist/entry.ts +++ b/app/components/content/specialist/entry.ts @@ -1,6 +1,6 @@ import * as z from 'zod' -export const specialistConf = z.object({ +export const schemaConf = z.object({ name: z .string({ required_error: 'Nama spesialisasi harus diisi', diff --git a/app/components/content/specialist/list.vue b/app/components/content/specialist/list.vue index 98874546..b384bfc1 100644 --- a/app/components/content/specialist/list.vue +++ b/app/components/content/specialist/list.vue @@ -6,7 +6,7 @@ import RecordConfirmation from '~/components/pub/custom-ui/confirmation/record-c import { ActionEvents } from '~/components/pub/custom-ui/data/types' import Header from '~/components/pub/custom-ui/nav-header/header.vue' import { usePaginatedList } from '~/composables/usePaginatedList' -import { createFilteredUnitConf, installationConf, specialistConf, unitConf } from './entry' +import { createFilteredUnitConf, installationConf, schemaConf, unitConf } from './entry' // #region State & Computed // Dialog state @@ -210,7 +210,7 @@ watch(recId, () => { = { + '1': ['1', '3'], + '2': ['2', '3'], + '3': ['1', '2', '3'], +} + +export const unitConf = { + msg: { + placeholder: '---pilih unit', + search: 'kode, nama unit', + empty: 'unit tidak ditemukan', + }, + items: [ + { value: '1', label: 'Instalasi Medis', code: 'MED' }, + { value: '2', label: 'Instalasi Keperawatan', code: 'NUR' }, + { value: '3', label: 'Instalasi Administrasi', code: 'ADM' }, + ], +} + +export const specialistConf = { + msg: { + placeholder: '---pilih specialist', + search: 'kode, nama specialist', + empty: 'specialist tidak ditemukan', + }, + items: [ + { value: '1', label: 'Spesialis Jantung', code: 'CARD' }, + { value: '2', label: 'Spesialis Mata', code: 'OPHT' }, + { value: '3', label: 'Spesialis Bedah', code: 'SURG' }, + { value: '4', label: 'Spesialis Anak', code: 'PEDI' }, + { value: '5', label: 'Spesialis Kandungan', code: 'OBGY' }, + ], +} + +export const installationConf = { + msg: { + placeholder: '---pilih instalasi', + search: 'kode, nama instalasi', + empty: 'instalasi tidak ditemukan', + }, + items: [ + { value: '1', label: 'Ambulatory', code: 'AMB' }, + { value: '2', label: 'Inpatient', code: 'IMP' }, + { value: '3', label: 'Emergency', code: 'EMER' }, + ], +} + +// Helper function untuk filter unit berdasarkan installation +export function getFilteredUnits(installationId: string) { + if (!installationId || !installationUnitMapping[installationId]) { + return [] + } + + const allowedUnitIds = installationUnitMapping[installationId] + return unitConf.items.filter((unit) => allowedUnitIds.includes(unit.value)) +} + +// Helper function untuk membuat unit config yang ter-filter +export function createFilteredUnitConf(installationId: string) { + return { + ...unitConf, + items: getFilteredUnits(installationId), + } +} diff --git a/app/components/content/subspecialist/list.vue b/app/components/content/subspecialist/list.vue new file mode 100644 index 00000000..bfb4e4b9 --- /dev/null +++ b/app/components/content/subspecialist/list.vue @@ -0,0 +1,241 @@ + + + diff --git a/app/pages/(features)/org-src/subspecialist/index.vue b/app/pages/(features)/org-src/subspecialist/index.vue new file mode 100644 index 00000000..a7a489d2 --- /dev/null +++ b/app/pages/(features)/org-src/subspecialist/index.vue @@ -0,0 +1,41 @@ + + +