diff --git a/app/components/app/division/entry-form-prev.vue b/app/components/app/division/entry-form-prev.vue deleted file mode 100644 index 0684fc55..00000000 --- a/app/components/app/division/entry-form-prev.vue +++ /dev/null @@ -1,145 +0,0 @@ - - - diff --git a/app/components/app/division/entry-form.vue b/app/components/app/division/entry-form.vue index a928c1bd..c58d83ac 100644 --- a/app/components/app/division/entry-form.vue +++ b/app/components/app/division/entry-form.vue @@ -4,6 +4,7 @@ import Block from '~/components/pub/my-ui/doc-entry/block.vue' import Cell from '~/components/pub/my-ui/doc-entry/cell.vue' import Field from '~/components/pub/my-ui/doc-entry/field.vue' import Label from '~/components/pub/my-ui/doc-entry/label.vue' +import TreeSelect from '~/components/pub/my-ui/select-tree/tree-select.vue' // Types import type { DivisionFormData } from '~/schemas/division.schema.ts' @@ -15,6 +16,7 @@ import { useForm } from 'vee-validate' interface Props { schema: z.ZodSchema + divisions: any[] values: any isLoading?: boolean isReadonly?: boolean @@ -33,33 +35,38 @@ const { defineField, errors, meta } = useForm({ initialValues: { code: '', name: '', - division_id: '', + parent_id: null, + division_id: null, } as Partial, }) const [code, codeAttrs] = defineField('code') const [name, nameAttrs] = defineField('name') -const [division, divisionAttrs] = defineField('division_id') +const [parent, parentAttrs] = defineField('parent_id') +const [division] = defineField('division_id') // Fill fields from props.values if provided if (props.values) { if (props.values.code !== undefined) code.value = props.values.code if (props.values.name !== undefined) name.value = props.values.name - if (props.values.division_id !== undefined) division.value = props.values.division_id + if (props.values.parent_id !== undefined) parent.value = String(props.values.parent_id) + if (props.values.division_id !== undefined) division.value = String(props.values.division_id) } const resetForm = () => { code.value = '' name.value = '' - division.value = '' + parent.value = null + division.value = null } // Form submission handler -function onSubmitForm(values: any) { +function onSubmitForm() { const formData: DivisionFormData = { name: name.value || '', code: code.value || '', - division_id: division.value || '', + parent_id: parent.value || null, + division_id: division.value || null, } emit('submit', formData, resetForm) } @@ -85,6 +92,22 @@ function onCancelForm() { + + + + + +
diff --git a/app/components/app/division/list-cfg.ts b/app/components/app/division/list-cfg.ts index 079faf52..d5479579 100644 --- a/app/components/app/division/list-cfg.ts +++ b/app/components/app/division/list-cfg.ts @@ -12,11 +12,11 @@ type SmallDetailDto = any const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue')) -export const cols: Col[] = [{ width: 100 }, {}, {}, { width: 50 }] +export const cols: Col[] = [{}, {}, {}, { width: 50 }] export const header: Th[][] = [[{ label: 'Kode' }, { label: 'Nama' }, { label: 'Divisi Induk' }, { label: '' }]] -export const keys = ['code', 'name', 'ancestor', 'action'] +export const keys = ['code', 'name', 'parent', 'action'] export const delKeyNames: KeyLabel[] = [ { key: 'code', label: 'Kode' }, @@ -24,13 +24,9 @@ export const delKeyNames: KeyLabel[] = [ ] export const funcParsed: RecStrFuncUnknown = { - ancestor: (rec: unknown): unknown => { + parent: (rec: unknown): unknown => { const recX = rec as SmallDetailDto - if (recX.meta === null) { - return '-' - } - - return recX.meta.name + return recX.parent?.name || '-' }, } diff --git a/app/components/app/division/tree.vue b/app/components/app/division/tree.vue deleted file mode 100644 index a6f66eff..00000000 --- a/app/components/app/division/tree.vue +++ /dev/null @@ -1,165 +0,0 @@ - - - diff --git a/app/components/app/installation/entry-form.vue b/app/components/app/installation/entry-form.vue index 4257b712..9d57b434 100644 --- a/app/components/app/installation/entry-form.vue +++ b/app/components/app/installation/entry-form.vue @@ -1,125 +1,119 @@ diff --git a/app/components/app/installation/list-cfg.ts b/app/components/app/installation/list-cfg.ts index 81de0024..e6fc5d47 100644 --- a/app/components/app/installation/list-cfg.ts +++ b/app/components/app/installation/list-cfg.ts @@ -12,13 +12,11 @@ type SmallDetailDto = any const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue')) -export const cols: Col[] = [{ width: 100 }, {}, {}, {}, { width: 50 }] +export const cols: Col[] = [{}, {}, {}, { width: 50 }] -export const header: Th[][] = [ - [{ label: 'Id' }, { label: 'Nama' }, { label: 'Kode' }, { label: 'Encounter Class' }, { label: '' }], -] +export const header: Th[][] = [[{ label: 'Kode' }, { label: 'Nama' }, { label: 'Encounter Class' }, { label: '' }]] -export const keys = ['id', 'name', 'cellphone', 'religion_code', 'action'] +export const keys = ['code', 'name', 'encounterClass_code', 'action'] export const delKeyNames: KeyLabel[] = [ { key: 'code', label: 'Kode' }, @@ -28,22 +26,7 @@ export const delKeyNames: KeyLabel[] = [ export const funcParsed: RecStrFuncUnknown = { name: (rec: unknown): unknown => { const recX = rec as SmallDetailDto - return `${recX.firstName} ${recX.lastName || ''}`.trim() - }, - identity_number: (rec: unknown): unknown => { - const recX = rec as SmallDetailDto - if (recX.identity_number?.substring(0, 5) === 'BLANK') { - return '(TANPA NIK)' - } - return recX.identity_number - }, - inPatient_itemPrice: (rec: unknown): unknown => { - const recX = rec as SmallDetailDto - return Number(recX.inPatient_itemPrice.price).toLocaleString('id-ID') - }, - outPatient_itemPrice: (rec: unknown): unknown => { - const recX = rec as SmallDetailDto - return Number(recX.outPatient_itemPrice.price).toLocaleString('id-ID') + return `${recX.name}`.trim() }, } @@ -65,4 +48,4 @@ export const funcHtml: RecStrFuncUnknown = { patient_address(_rec) { return '-' }, -} +} \ No newline at end of file diff --git a/app/components/app/installation/list.vue b/app/components/app/installation/list.vue index 72973ca3..af63d76e 100644 --- a/app/components/app/installation/list.vue +++ b/app/components/app/installation/list.vue @@ -21,11 +21,16 @@ function handlePageChange(page: number) { diff --git a/app/components/app/medicine/list-cfg.ts b/app/components/app/medicine/list-cfg.ts index bde85bc9..77993d55 100644 --- a/app/components/app/medicine/list-cfg.ts +++ b/app/components/app/medicine/list-cfg.ts @@ -35,13 +35,13 @@ export const delKeyNames: KeyLabel[] = [ export const funcParsed: RecStrFuncUnknown = { group: (rec: unknown): unknown => { - return (rec as SmallDetailDto).medicineGroup_code || '-' + return (rec as SmallDetailDto).medicineGroup?.name || '-' }, method: (rec: unknown): unknown => { - return (rec as SmallDetailDto).medicineMethod_code || '-' + return (rec as SmallDetailDto).medicineMethod?.name || '-' }, unit: (rec: unknown): unknown => { - return (rec as SmallDetailDto).uom_code || '-' + return (rec as SmallDetailDto).uom?.name || '-' }, } diff --git a/app/components/app/specialist/entry-form.vue b/app/components/app/specialist/entry-form.vue index 749765d9..0d055a1d 100644 --- a/app/components/app/specialist/entry-form.vue +++ b/app/components/app/specialist/entry-form.vue @@ -4,7 +4,7 @@ import Block from '~/components/pub/my-ui/doc-entry/block.vue' import Cell from '~/components/pub/my-ui/doc-entry/cell.vue' import Field from '~/components/pub/my-ui/doc-entry/field.vue' import Label from '~/components/pub/my-ui/doc-entry/label.vue' -// import Combobox from '~/components/pub/my-ui/form/combobox.vue' +import Combobox from '~/components/pub/my-ui/form/combobox.vue' // Types import type { SpecialistFormData } from '~/schemas/specialist.schema.ts' @@ -90,24 +90,15 @@ function onCancelForm() { - - diff --git a/app/components/app/unit/entry-form.vue b/app/components/app/unit/entry-form.vue index 0a9d04f0..205513d5 100644 --- a/app/components/app/unit/entry-form.vue +++ b/app/components/app/unit/entry-form.vue @@ -4,6 +4,7 @@ import Block from '~/components/pub/my-ui/doc-entry/block.vue' import Cell from '~/components/pub/my-ui/doc-entry/cell.vue' import Field from '~/components/pub/my-ui/doc-entry/field.vue' import Label from '~/components/pub/my-ui/doc-entry/label.vue' +import Combobox from '~/components/pub/my-ui/form/combobox.vue' // Types import type { UnitFormData } from '~/schemas/unit.schema.ts' @@ -15,6 +16,7 @@ import { useForm } from 'vee-validate' interface Props { schema: z.ZodSchema + installations: any[] values: any isLoading?: boolean isReadonly?: boolean @@ -33,13 +35,13 @@ const { defineField, errors, meta } = useForm({ initialValues: { code: '', name: '', - installation: '', + installation_id: 0, } as Partial, }) const [code, codeAttrs] = defineField('code') const [name, nameAttrs] = defineField('name') -const [installation, installationAttrs] = defineField('installation') +const [installation, installationAttrs] = defineField('installation_id') // Fill fields from props.values if provided if (props.values) { @@ -59,7 +61,7 @@ function onSubmitForm(values: any) { const formData: UnitFormData = { name: name.value || '', code: code.value || '', - installation: installation.value || '', + installation_id: installation.value || '', } emit('submit', formData, resetForm) } @@ -85,6 +87,21 @@ function onCancelForm() { + + + + + +
diff --git a/app/components/app/unit/list-cfg.ts b/app/components/app/unit/list-cfg.ts index 13bbc16f..04975ddc 100644 --- a/app/components/app/unit/list-cfg.ts +++ b/app/components/app/unit/list-cfg.ts @@ -28,8 +28,9 @@ export const funcParsed: RecStrFuncUnknown = { const recX = rec as SmallDetailDto return `${recX.name}`.trim() }, - installation: (_rec: unknown): unknown => { - return '-' + installation: (rec: unknown): unknown => { + const recX = rec as SmallDetailDto + return recX.installation?.name || recX.Installation?.name || '-' }, } diff --git a/app/components/content/division/entry.ts b/app/components/content/division/entry.ts deleted file mode 100644 index 9f3cb9f4..00000000 --- a/app/components/content/division/entry.ts +++ /dev/null @@ -1,145 +0,0 @@ -import type { TreeItem } from '~/components/pub/my-ui/select-tree/type' -import * as z from 'zod' - -export const divisionConf = { - msg: { - placeholder: '---pilih divisi utama', - search: 'kode, nama divisi', - empty: 'divisi tidak ditemukan', - }, - items: [ - { value: '1', label: 'Medical' }, - { value: '2', label: 'Nursing' }, - { value: '3', label: 'Admin' }, - { value: '4', label: 'Support' }, - { value: '5', label: 'Education' }, - { value: '6', label: 'Pharmacy' }, - { value: '7', label: 'Radiology' }, - { value: '8', label: 'Laboratory' }, - { value: '9', label: 'Finance' }, - { value: '10', label: 'Human Resources' }, - { value: '11', label: 'IT Services' }, - { value: '12', label: 'Maintenance' }, - { value: '13', label: 'Catering' }, - { value: '14', label: 'Security' }, - { value: '15', label: 'Emergency' }, - { value: '16', label: 'Surgery' }, - { value: '17', label: 'Outpatient' }, - { value: '18', label: 'Inpatient' }, - { value: '19', label: 'Rehabilitation' }, - { value: '20', label: 'Research' }, - ], -} - -export const schema = z.object({ - name: z - .string({ - required_error: 'Nama wajib diisi', - }) - .min(1, 'Nama divisi wajib diisi'), - - code: z - .string({ - required_error: 'Kode wajib diisi', - }) - .min(1, 'Kode divisi wajib diisi'), - - parentId: z.string().optional(), -}) - -// State untuk tree data divisi - dimulai dengan data level atas -const divisionTreeData = ref([ - { value: '1', label: 'Medical', hasChildren: true }, - { value: '2', label: 'Nursing', hasChildren: true }, - { value: '3', label: 'Admin', hasChildren: false }, - { value: '4', label: 'Support', hasChildren: true }, - { value: '5', label: 'Education', hasChildren: false }, - { value: '6', label: 'Pharmacy', hasChildren: true }, - { value: '7', label: 'Radiology', hasChildren: false }, - { value: '8', label: 'Laboratory', hasChildren: true }, -]) - -// Helper function untuk mencari dan menyisipkan data anak ke dalam tree -function findAndInsertChildren(nodes: TreeItem[], parentId: string, newChildren: TreeItem[]): boolean { - for (const node of nodes) { - if (node.value === parentId) { - node.children = newChildren - return true - } - if (node.children && findAndInsertChildren(node.children as TreeItem[], parentId, newChildren)) { - return true - } - } - return false -} - -// Fungsi untuk fetch data anak divisi (lazy loading) -async function handleFetchDivisionChildren(parentId: string): Promise { - console.log(`Mengambil data sub-divisi untuk parent: ${parentId}`) - - // Simulasi delay API call - await new Promise((resolve) => setTimeout(resolve, 800)) - - let childrenData: TreeItem[] = [] - - // Sample data berdasarkan parent ID - switch (parentId) { - case '1': // Medical - childrenData = [ - { value: '1-1', label: 'Cardiology', hasChildren: true }, - { value: '1-2', label: 'Neurology', hasChildren: false }, - { value: '1-3', label: 'Oncology', hasChildren: false }, - ] - break - case '2': // Nursing - childrenData = [ - { value: '2-1', label: 'ICU Nursing', hasChildren: false }, - { value: '2-2', label: 'ER Nursing', hasChildren: false }, - { value: '2-3', label: 'Ward Nursing', hasChildren: true }, - ] - break - case '4': // Support - childrenData = [ - { value: '4-1', label: 'IT Support', hasChildren: false }, - { value: '4-2', label: 'Maintenance', hasChildren: false }, - ] - break - case '6': // Pharmacy - childrenData = [ - { value: '6-1', label: 'Inpatient Pharmacy', hasChildren: false }, - { value: '6-2', label: 'Outpatient Pharmacy', hasChildren: false }, - ] - break - case '8': // Laboratory - childrenData = [ - { value: '8-1', label: 'Clinical Lab', hasChildren: false }, - { value: '8-2', label: 'Pathology Lab', hasChildren: false }, - ] - break - case '1-1': // Cardiology sub-divisions - childrenData = [ - { value: '1-1-1', label: 'Cardiac Surgery', hasChildren: false }, - { value: '1-1-2', label: 'Cardiac Cathlab', hasChildren: false }, - ] - break - case '2-3': // Ward Nursing sub-divisions - childrenData = [ - { value: '2-3-1', label: 'Pediatric Ward', hasChildren: false }, - { value: '2-3-2', label: 'Surgical Ward', hasChildren: false }, - ] - break - } - - // Insert data ke dalam tree state - findAndInsertChildren(divisionTreeData.value, parentId, childrenData) -} - -export const divisionTreeConfig = computed(() => ({ - msg: { - placeholder: '--- Pilih divisi induk', - search: 'Cari divisi...', - empty: 'Divisi tidak ditemukan', - }, - data: divisionTreeData.value, - onFetchChildren: handleFetchDivisionChildren, -})) diff --git a/app/components/content/division/list-prev.vue b/app/components/content/division/list-prev.vue deleted file mode 100644 index d072ac9a..00000000 --- a/app/components/content/division/list-prev.vue +++ /dev/null @@ -1,208 +0,0 @@ - - - - - diff --git a/app/components/content/division/list.vue b/app/components/content/division/list.vue index 8bb4e390..05a9d8df 100644 --- a/app/components/content/division/list.vue +++ b/app/components/content/division/list.vue @@ -13,6 +13,7 @@ import { toast } from '~/components/pub/ui/toast' // Types import { ActionEvents, type HeaderPrep } from '~/components/pub/my-ui/data/types' import { DivisionSchema, type DivisionFormData } from '~/schemas/division.schema' +import type { TreeItem } from '~/models/_model' // Handlers import { @@ -30,8 +31,9 @@ import { } from '~/handlers/division.handler' // Services -import { getDivisions, getDivisionDetail } from '~/services/division.service' +import { getList, getDetail, getValueTreeItems } from '~/services/division.service' +const divisionsTrees = ref([]) const title = ref('') const { @@ -43,8 +45,13 @@ const { handleSearch, fetchData: getDivisionList, } = usePaginatedList({ - fetchFn: async ({ page, search }) => { - const result = await getDivisions({ search, page }) + fetchFn: async (params: any) => { + const result = await getList({ + search: params.search, + 'page-number': params['page-number'] || 0, + 'page-size': params['page-size'] || 10, + includes: 'parent,childrens', + }) return { success: result.success || false, body: result.body || {} } }, entityName: 'division', @@ -82,7 +89,7 @@ provide('rec_item', recItem) provide('table_data_loader', isLoading) const getCurrentDivisionDetail = async (id: number | string) => { - const result = await getDivisionDetail(id) + const result = await getDetail(id) if (result.success) { const currentValue = result.body?.data || {} recItem.value = currentValue @@ -109,6 +116,22 @@ watch([recId, recAction], () => { } }) +watch( + () => data.value, + async () => { + if (!data.value) return + const result = await getList({ + 'page-size': 100, + 'only-have-children': false, + includes: 'parent,childrens', + }) + if (result.success) { + const currentData = result.body.data || [] + divisionsTrees.value = getValueTreeItems(currentData || []) + } + }, +) + onMounted(async () => { await getDivisionList() }) @@ -123,15 +146,17 @@ onMounted(async () => { class="mb-4 xl:mb-5" /> - + -import type { HeaderPrep } from '~/components/pub/my-ui/data/types' -import AppInstallationEntryForm from '~/components/app/installation/entry-form.vue' +// Components import Dialog from '~/components/pub/my-ui/modal/dialog.vue' +import Header from '~/components/pub/my-ui/nav-header/prep.vue' import RecordConfirmation from '~/components/pub/my-ui/confirmation/record-confirmation.vue' -import { ActionEvents } from '~/components/pub/my-ui/data/types' -import Header from '~/components/pub/my-ui/nav-header/header.vue' -import { transform, usePaginatedList } from '~/composables/usePaginatedList' -import { installationConf, schemaConf } from './entry' +import AppInstallationList from '~/components/app/installation/list.vue' +import AppInstallationEntryForm from '~/components/app/installation/entry-form.vue' -// #region State & Computed -// Dialog state -const isFormEntryDialogOpen = ref(false) -const isRecordConfirmationOpen = ref(false) +// Helpers +import { usePaginatedList } from '~/composables/usePaginatedList' +import { toast } from '~/components/pub/ui/toast' -// Table action rowId provider -const recId = ref(0) -const recAction = ref('') -const recItem = ref(null) +// Types +import { ActionEvents, type HeaderPrep } from '~/components/pub/my-ui/data/types' +import { InstallationSchema, type InstallationFormData } from '~/schemas/installation.schema' -// Fungsi untuk fetch data installation -async function fetchInstallationData(params: any) { - // Prepare query parameters for pagination and search - const endpoint = transform('/api/v1/patient', params) - return await xfetch(endpoint) -} +// Handlers +import { + recId, + recAction, + recItem, + isReadonly, + isProcessing, + isFormEntryDialogOpen, + isRecordConfirmationOpen, + handleActionSave, + handleActionEdit, + handleActionRemove, + handleCancelForm, +} from '~/handlers/installation.handler' + +// Services +import { getList, getDetail } from '~/services/installation.service' +import { getValueLabelListConstants as getEncounterList } from '~/services/encounter.service' + +const encounterClasses = ref<{ value: string; label: string }[]>([]) +const title = ref('') -// Menggunakan composable untuk pagination const { data, isLoading, @@ -35,7 +45,14 @@ const { handleSearch, fetchData: getInstallationList, } = usePaginatedList({ - fetchFn: fetchInstallationData, + fetchFn: async (params: any) => { + const result = await getList({ + search: params.search, + 'page-number': params['page-number'] || 0, + 'page-size': params['page-size'] || 10, + }) + return { success: result.success || false, body: result.body || {} } + }, entityName: 'installation', }) @@ -47,21 +64,20 @@ const headerPrep: HeaderPrep = { minLength: 3, debounceMs: 500, showValidationFeedback: true, - onInput: (_val: string) => { - // Handle search input - this will be triggered by the header component - }, - onClick: () => { - // Handle search button click if needed - }, - onClear: () => { - // Handle search clear + onInput: (value: string) => { + searchInput.value = value }, + onClick: () => {}, + onClear: () => {}, }, addNav: { - label: 'Tambah Instalasi', - icon: 'i-lucide-send', + label: 'Tambah', + icon: 'i-lucide-plus', onClick: () => { + recItem.value = null + recId.value = 0 isFormEntryDialogOpen.value = true + isReadonly.value = false }, }, } @@ -70,137 +86,90 @@ provide('rec_id', recId) provide('rec_action', recAction) provide('rec_item', recItem) provide('table_data_loader', isLoading) -// #endregion -// #region Functions - -async function handleDeleteRow(record: any) { - try { - // TODO : hit backend request untuk delete - console.log('Deleting record:', record) - - // Simulate API call - // const response = await xfetch(`/api/v1/Installation/${record.id}`, { - // method: 'DELETE' - // }) - - // Refresh data setelah berhasil delete - await getInstallationList() - - // TODO: Show success message - console.log('Record deleted successfully') - } catch (error) { - console.error('Error deleting record:', error) - // TODO: Show error message - } finally { - // Reset record state - recId.value = 0 - recAction.value = '' - recItem.value = null +const getCurrentInstallationDetail = async (id: number | string) => { + const result = await getDetail(id) + if (result.success) { + const currentValue = result.body?.data || {} + recItem.value = currentValue + isFormEntryDialogOpen.value = true } } -// #endregion region - -// #region Form event handlers - -function onCancelForm(resetForm: () => void) { - isFormEntryDialogOpen.value = false - setTimeout(() => { - resetForm() - }, 500) -} - -async function onSubmitForm(values: any, resetForm: () => void) { - let isSuccess = false - try { - // TODO: Implement form submission logic - console.log('Form submitted:', values) - - // Simulate API call - // const response = await xfetch('/api/v1/Installation', { - // method: 'POST', - // body: JSON.stringify(values) - // }) - - // If successful, mark as success and close dialog - isFormEntryDialogOpen.value = false - isSuccess = true - - // Refresh data after successful submission - await getInstallationList() - - // TODO: Show success message - console.log('Installation created successfully') - } catch (error: unknown) { - console.warn('Error submitting form:', error) - isSuccess = false - // Don't close dialog or reset form on error - // TODO: Show error message to user - } finally { - if (isSuccess) { - setTimeout(() => { - resetForm() - }, 500) - } - } -} -// #endregion - -// #region Watchers - -// Watch for row actions -watch(recId, () => { +// Watch for row actions when recId or recAction changes +watch([recId, recAction], () => { switch (recAction.value) { + case ActionEvents.showDetail: + getCurrentInstallationDetail(recId.value) + title.value = 'Detail Instalasi' + isReadonly.value = true + break case ActionEvents.showEdit: - // TODO: Handle edit action - // isFormEntryDialogOpen.value = true + getCurrentInstallationDetail(recId.value) + title.value = 'Edit Instalasi' + isReadonly.value = false break case ActionEvents.showConfirmDelete: - // Trigger confirmation modal open isRecordConfirmationOpen.value = true break } }) -// Handle confirmation result -function handleConfirmDelete(record: any, action: string) { - console.log('Confirmed action:', action, 'for record:', record) - handleDeleteRow(record) -} - -function handleCancelConfirmation() { - // Reset record state when cancelled - recId.value = 0 - recAction.value = '' - recItem.value = null -} -// #endregion +onMounted(async () => { + encounterClasses.value = getEncounterList() + await getInstallationList() +}) - - diff --git a/app/components/content/medicine-group/list.vue b/app/components/content/medicine-group/list.vue index 3ff9e241..8d45843f 100644 --- a/app/components/content/medicine-group/list.vue +++ b/app/components/content/medicine-group/list.vue @@ -30,7 +30,7 @@ import { } from '~/handlers/medicine-group.handler' // Services -import { getMedicineGroups, getMedicineGroupDetail } from '~/services/medicine-group.service' +import { getList, getDetail } from '~/services/medicine-group.service' const title = ref('') @@ -43,8 +43,12 @@ const { handleSearch, fetchData: getMedicineGroupList, } = usePaginatedList({ - fetchFn: async ({ page, search }) => { - const result = await getMedicineGroups({ search, page }) + fetchFn: async (params: any) => { + const result = await getList({ + search: params.search, + 'page-number': params['page-number'] || 0, + 'page-size': params['page-size'] || 10, + }) return { success: result.success || false, body: result.body || {} } }, entityName: 'medicine-group', @@ -82,7 +86,7 @@ provide('rec_item', recItem) provide('table_data_loader', isLoading) const getCurrentMedicineGroupDetail = async (id: number | string) => { - const result = await getMedicineGroupDetail(id) + const result = await getDetail(id) if (result.success) { const currentValue = result.body?.data || {} recItem.value = currentValue diff --git a/app/components/content/medicine-method/list.vue b/app/components/content/medicine-method/list.vue index 36f93087..f6ddf86b 100644 --- a/app/components/content/medicine-method/list.vue +++ b/app/components/content/medicine-method/list.vue @@ -30,7 +30,7 @@ import { } from '~/handlers/medicine-method.handler' // Services -import { getMedicineMethods, getMedicineMethodDetail } from '~/services/medicine-method.service' +import { getList, getDetail } from '~/services/medicine-method.service' const title = ref('') @@ -43,8 +43,12 @@ const { handleSearch, fetchData: getMedicineMethodList, } = usePaginatedList({ - fetchFn: async ({ page, search }) => { - const result = await getMedicineMethods({ search, page }) + fetchFn: async (params: any) => { + const result = await getList({ + search: params.search, + 'page-number': params['page-number'] || 0, + 'page-size': params['page-size'] || 10, + }) return { success: result.success || false, body: result.body || {} } }, entityName: 'medicine-method', @@ -82,7 +86,7 @@ provide('rec_item', recItem) provide('table_data_loader', isLoading) const getCurrentMedicineMethodDetail = async (id: number | string) => { - const result = await getMedicineMethodDetail(id) + const result = await getDetail(id) if (result.success) { const currentValue = result.body?.data || {} recItem.value = currentValue diff --git a/app/components/content/medicine/list.vue b/app/components/content/medicine/list.vue index 1aa3a492..d52c0ea4 100644 --- a/app/components/content/medicine/list.vue +++ b/app/components/content/medicine/list.vue @@ -33,10 +33,10 @@ import { } from '~/handlers/medicine.handler' // Services -import { getMedicines, getMedicineDetail } from '~/services/medicine.service' -import { getMedicineGroups } from '~/services/medicine-group.service' -import { getMedicineMethods } from '~/services/medicine-method.service' -import { getUoms } from '~/services/uom.service' +import { getList, getDetail } from '~/services/medicine.service' +import { getValueLabelList as getMedicineGroupList } from '~/services/medicine-group.service' +import { getValueLabelList as getMedicineMethodList } from '~/services/medicine-method.service' +import { getValueLabelList as getUomList } from '~/services/uom.service' const medicineGroups = ref<{ value: string; label: string }[]>([]) const medicineMethods = ref<{ value: string; label: string }[]>([]) @@ -52,8 +52,13 @@ const { handleSearch, fetchData: getMedicineList, } = usePaginatedList({ - fetchFn: async ({ page, search }) => { - const result = await getMedicines({ search, page }) + fetchFn: async (params: any) => { + const result = await getList({ + search: params.search, + 'page-number': params['page-number'] || 0, + 'page-size': params['page-size'] || 10, + includes: 'medicineGroup,medicineMethod,uom', + }) return { success: result.success || false, body: result.body || {} } }, entityName: 'medicine', @@ -91,7 +96,7 @@ provide('rec_item', recItem) provide('table_data_loader', isLoading) const getCurrentMedicineDetail = async (id: number | string) => { - const result = await getMedicineDetail(id) + const result = await getDetail(id) if (result.success) { const currentValue = result.body?.data || {} recItem.value = currentValue @@ -99,36 +104,6 @@ const getCurrentMedicineDetail = async (id: number | string) => { } } -const getMedicineGroupList = async () => { - const result = await getMedicineGroups() - if (result.success) { - const currentMedicineGroups = result.body?.data || [] - medicineGroups.value = currentMedicineGroups.map((medicineGroup: MedicineGroup) => ({ - value: medicineGroup.code, - label: medicineGroup.name, - })) - } -} - -const getMedicineMethodList = async () => { - const result = await getMedicineMethods() - if (result.success) { - const currentMedicineMethods = result.body?.data || [] - medicineMethods.value = currentMedicineMethods.map((medicineMethod: MedicineMethod) => ({ - value: medicineMethod.code, - label: medicineMethod.name, - })) - } -} - -const getUomList = async () => { - const result = await getUoms() - if (result.success) { - const currentUoms = result.body?.data || [] - uoms.value = currentUoms.map((uom: Uom) => ({ value: uom.code || uom.erp_id, label: uom.name })) - } -} - watch([recId, recAction], () => { switch (recAction.value) { case ActionEvents.showDetail: @@ -148,9 +123,9 @@ watch([recId, recAction], () => { }) onMounted(async () => { - await getMedicineGroupList() - await getMedicineMethodList() - await getUomList() + medicineGroups.value = await getMedicineGroupList() + medicineMethods.value = await getMedicineMethodList() + uoms.value = await getUomList() await getMedicineList() }) diff --git a/app/components/content/specialist/entry.ts b/app/components/content/specialist/entry.ts deleted file mode 100644 index c89302c2..00000000 --- a/app/components/content/specialist/entry.ts +++ /dev/null @@ -1,95 +0,0 @@ -import * as z from 'zod' - -export const schemaConf = z.object({ - name: z - .string({ - required_error: 'Nama spesialisasi harus diisi', - }) - .min(3, 'Nama spesialisasi minimal 3 karakter'), - - code: z - .string({ - required_error: 'Kode spesialisasi harus diisi', - }) - .min(3, 'Kode spesialisasi minimal 3 karakter'), - - installationId: z - .string({ - required_error: 'Instalasi harus dipilih', - }) - .min(1, 'Instalasi harus dipilih'), - - unitId: z - .string({ - required_error: 'Unit harus dipilih', - }) - .min(1, 'Unit harus dipilih'), -}) - -// Unit mapping berdasarkan installation -export const installationUnitMapping: Record = { - '1': ['1', '3', '5'], - '2': ['2', '4', '6'], - '3': ['7', '8', '9', '10', '11'], -} - -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' }, - { value: '4', label: 'Instalasi Penunjang Non-Medis', code: 'SUP' }, - { value: '5', label: 'Instalasi Pendidikan & Pelatihan', code: 'EDU' }, - { value: '6', label: 'Instalasi Farmasi', code: 'PHA' }, - { value: '7', label: 'Instalasi Radiologi', code: 'RAD' }, - { value: '8', label: 'Instalasi Laboratorium', code: 'LAB' }, - { value: '9', label: 'Instalasi Keuangan', code: 'FIN' }, - { value: '10', label: 'Instalasi SDM', code: 'HR' }, - { value: '11', label: 'Instalasi Teknologi Informasi', code: 'ITS' }, - { value: '12', label: 'Instalasi Pemeliharaan & Sarana', code: 'MNT' }, - { value: '13', label: 'Instalasi Gizi / Catering', code: 'CAT' }, - { value: '14', label: 'Instalasi Keamanan', code: 'SEC' }, - { value: '15', label: 'Instalasi Gawat Darurat', code: 'EMR' }, - { value: '16', label: 'Instalasi Bedah Sentral', code: 'SUR' }, - { value: '17', label: 'Instalasi Rawat Jalan', code: 'OUT' }, - { value: '18', label: 'Instalasi Rawat Inap', code: 'INP' }, - { value: '19', label: 'Instalasi Rehabilitasi Medik', code: 'REB' }, - { value: '20', label: 'Instalasi Penelitian & Pengembangan', code: 'RSH' }, - ], -} - -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/specialist/list-prev.vue b/app/components/content/specialist/list-prev.vue deleted file mode 100644 index 9ed71016..00000000 --- a/app/components/content/specialist/list-prev.vue +++ /dev/null @@ -1,240 +0,0 @@ - - - - - diff --git a/app/components/content/specialist/list.vue b/app/components/content/specialist/list.vue index ab3d13bb..71d573b4 100644 --- a/app/components/content/specialist/list.vue +++ b/app/components/content/specialist/list.vue @@ -13,7 +13,6 @@ import { toast } from '~/components/pub/ui/toast' // Types import { ActionEvents, type HeaderPrep } from '~/components/pub/my-ui/data/types' import { SpecialistSchema, type SpecialistFormData } from '~/schemas/specialist.schema' -import type { Unit } from '~/models/unit' // Handlers import { @@ -31,10 +30,10 @@ import { } from '~/handlers/specialist.handler' // Services -import { getSpecialists, getSpecialistDetail } from '~/services/specialist.service' -import { getUnits } from '~/services/unit.service' +import { getList, getDetail } from '~/services/specialist.service' +import { getValueLabelList as getUnitList } from '~/services/unit.service' -const units = ref<{ value: string; label: string }[]>([]) +const units = ref<{ value: string | number; label: string }[]>([]) const title = ref('') const { @@ -46,8 +45,13 @@ const { handleSearch, fetchData: getSpecialistList, } = usePaginatedList({ - fetchFn: async ({ page, search }) => { - const result = await getSpecialists({ search, page }) + fetchFn: async (params: any) => { + const result = await getList({ + search: params.search, + 'page-number': params['page-number'] || 0, + 'page-size': params['page-size'] || 10, + includes: 'unit', + }) return { success: result.success || false, body: result.body || {} } }, entityName: 'specialist', @@ -85,7 +89,7 @@ provide('rec_item', recItem) provide('table_data_loader', isLoading) const getCurrentSpecialistDetail = async (id: number | string) => { - const result = await getSpecialistDetail(id) + const result = await getDetail(id) if (result.success) { const currentValue = result.body?.data || {} recItem.value = currentValue @@ -93,14 +97,6 @@ const getCurrentSpecialistDetail = async (id: number | string) => { } } -const getUnitList = async () => { - const result = await getUnits() - if (result.success) { - const currentUnits = result.body?.data || [] - units.value = currentUnits.map((item: Unit) => ({ value: item.id ? Number(item.id) : item.code, label: item.name })) - } -} - // Watch for row actions when recId or recAction changes watch([recId, recAction], () => { switch (recAction.value) { @@ -121,7 +117,7 @@ watch([recId, recAction], () => { }) onMounted(async () => { - await getUnitList() + units.value = await getUnitList() await getSpecialistList() }) diff --git a/app/components/content/subspecialist/entry.ts b/app/components/content/subspecialist/entry.ts deleted file mode 100644 index 5a93847d..00000000 --- a/app/components/content/subspecialist/entry.ts +++ /dev/null @@ -1,98 +0,0 @@ -import * as z from 'zod' - -export const schemaConf = z.object({ - name: z - .string({ - required_error: 'Nama spesialisasi harus diisi', - }) - .min(3, 'Nama spesialisasi minimal 3 karakter'), - - code: z - .string({ - required_error: 'Kode spesialisasi harus diisi', - }) - .min(3, 'Kode spesialisasi minimal 3 karakter'), - - installationId: z - .string({ - required_error: 'Instalasi harus dipilih', - }) - .min(1, 'Instalasi harus dipilih'), - - unitId: z - .string({ - required_error: 'Unit harus dipilih', - }) - .min(1, 'Unit harus dipilih'), - specialistId: z - .string({ - required_error: 'Specialist harus dipilih', - }) - .min(1, 'Specialist harus dipilih'), -}) - -// Unit mapping berdasarkan installation -export const installationUnitMapping: Record = { - '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-prev.vue b/app/components/content/subspecialist/list-prev.vue deleted file mode 100644 index 81f59399..00000000 --- a/app/components/content/subspecialist/list-prev.vue +++ /dev/null @@ -1,239 +0,0 @@ - - - diff --git a/app/components/content/subspecialist/list.vue b/app/components/content/subspecialist/list.vue index 8da9e24c..bf60598e 100644 --- a/app/components/content/subspecialist/list.vue +++ b/app/components/content/subspecialist/list.vue @@ -13,7 +13,6 @@ import { toast } from '~/components/pub/ui/toast' // Types import { ActionEvents, type HeaderPrep } from '~/components/pub/my-ui/data/types' import { SubspecialistSchema, type SubspecialistFormData } from '~/schemas/subspecialist.schema' -import type { Specialist } from '~/models/specialist' // Handlers import { @@ -31,10 +30,10 @@ import { } from '~/handlers/subspecialist.handler' // Services -import { getSubspecialists, getSubspecialistDetail } from '~/services/subspecialist.service' -import { getSpecialists } from '~/services/specialist.service' +import { getList, getDetail } from '~/services/subspecialist.service' +import { getValueLabelList as getSpecialistsList } from '~/services/specialist.service' -const specialists = ref<{ value: string; label: string }[]>([]) +const specialists = ref<{ value: string | number; label: string }[]>([]) const title = ref('') const { @@ -46,8 +45,13 @@ const { handleSearch, fetchData: getSubSpecialistList, } = usePaginatedList({ - fetchFn: async ({ page, search }) => { - const result = await getSubspecialists({ search, page }) + fetchFn: async (params: any) => { + const result = await getList({ + search: params.search, + 'page-number': params['page-number'] || 0, + 'page-size': params['page-size'] || 10, + includes: 'specialist', + }) return { success: result.success || false, body: result.body || {} } }, entityName: 'subspecialist', @@ -85,7 +89,7 @@ provide('rec_item', recItem) provide('table_data_loader', isLoading) const getCurrentSubSpecialistDetail = async (id: number | string) => { - const result = await getSubspecialistDetail(id) + const result = await getDetail(id) if (result.success) { const currentValue = result.body?.data || {} recItem.value = currentValue @@ -93,17 +97,6 @@ const getCurrentSubSpecialistDetail = async (id: number | string) => { } } -const getSpecialistsList = async () => { - const result = await getSpecialists() - if (result.success) { - const currentSpecialists = result.body?.data || [] - specialists.value = currentSpecialists.map((item: Specialist) => ({ - value: item.id ? Number(item.id) : item.code, - label: item.name, - })) - } -} - // Watch for row actions when recId or recAction changes watch([recId, recAction], () => { switch (recAction.value) { @@ -124,7 +117,7 @@ watch([recId, recAction], () => { }) onMounted(async () => { - await getSpecialistsList() + specialists.value = await getSpecialistsList() await getSubSpecialistList() }) diff --git a/app/components/content/tools/list.vue b/app/components/content/tools/list.vue index c57b65b2..32fbbdea 100644 --- a/app/components/content/tools/list.vue +++ b/app/components/content/tools/list.vue @@ -13,7 +13,6 @@ import { toast } from '~/components/pub/ui/toast' // Types import { ActionEvents, type HeaderPrep } from '~/components/pub/my-ui/data/types' import { DeviceSchema, type DeviceFormData } from '~/schemas/device.schema' -import type { Uom } from '~/models/uom' // Handlers import { @@ -31,8 +30,8 @@ import { } from '~/handlers/device.handler' // Services -import { getDevices, getDeviceDetail } from '~/services/device.service' -import { getUoms } from '~/services/uom.service' +import { getList, getDetail } from '~/services/device.service' +import { getValueLabelList as getUomList } from '~/services/uom.service' const uoms = ref<{ value: string; label: string }[]>([]) const title = ref('') @@ -46,8 +45,8 @@ const { handleSearch, fetchData: getToolsList, } = usePaginatedList({ - fetchFn: async ({ page }) => { - const result = await getDevices({ search: searchInput.value, page }) + fetchFn: async (params: any) => { + const result = await getList({ search: params.search, 'page-number': params['page-number'] || 0 }) return { success: result.success || false, body: result.body || {} } }, entityName: 'device', @@ -89,21 +88,13 @@ provide('rec_item', recItem) provide('table_data_loader', isLoading) const getCurrentToolsDetail = async (id: number | string) => { - const result = await getDeviceDetail(id) + const result = await getDetail(id) if (result.success) { const currentValue = result.body?.data || {} recItem.value = currentValue } } -const getUomList = async () => { - const result = await getUoms() - if (result.success) { - const currentUoms = result.body?.data || [] - uoms.value = currentUoms.map((uom: Uom) => ({ value: uom.code || uom.erp_id, label: uom.name })) - } -} - // Watch for row actions watch([recId, recAction], () => { switch (recAction.value) { @@ -126,7 +117,7 @@ watch([recId, recAction], () => { }) onMounted(async () => { - await getUomList() + uoms.value = await getUomList() await getToolsList() }) diff --git a/app/components/content/unit/entry.ts b/app/components/content/unit/entry.ts deleted file mode 100644 index bf85a0ed..00000000 --- a/app/components/content/unit/entry.ts +++ /dev/null @@ -1,63 +0,0 @@ -import * as z from 'zod' - -export const unitConf = { - msg: { - placeholder: '--- pilih instalasi', - search: 'kode, nama instalasi', - empty: 'instalasi tidak ditemukan', - }, - items: [ - { value: '1', label: 'Instalasi Medis', code: 'MED' }, - { value: '2', label: 'Instalasi Keperawatan', code: 'NUR' }, - { value: '3', label: 'Instalasi Administrasi', code: 'ADM' }, - { value: '4', label: 'Instalasi Penunjang Non-Medis', code: 'SUP' }, - { value: '5', label: 'Instalasi Pendidikan & Pelatihan', code: 'EDU' }, - { value: '6', label: 'Instalasi Farmasi', code: 'PHA' }, - { value: '7', label: 'Instalasi Radiologi', code: 'RAD' }, - { value: '8', label: 'Instalasi Laboratorium', code: 'LAB' }, - { value: '9', label: 'Instalasi Keuangan', code: 'FIN' }, - { value: '10', label: 'Instalasi SDM', code: 'HR' }, - { value: '11', label: 'Instalasi Teknologi Informasi', code: 'ITS' }, - { value: '12', label: 'Instalasi Pemeliharaan & Sarana', code: 'MNT' }, - { value: '13', label: 'Instalasi Gizi / Catering', code: 'CAT' }, - { value: '14', label: 'Instalasi Keamanan', code: 'SEC' }, - { value: '15', label: 'Instalasi Gawat Darurat', code: 'EMR' }, - { value: '16', label: 'Instalasi Bedah Sentral', code: 'SUR' }, - { value: '17', label: 'Instalasi Rawat Jalan', code: 'OUT' }, - { value: '18', label: 'Instalasi Rawat Inap', code: 'INP' }, - { value: '19', label: 'Instalasi Rehabilitasi Medik', code: 'REB' }, - { value: '20', label: 'Instalasi Penelitian & Pengembangan', code: 'RSH' }, - ], -} - -export const schemaConf = z.object({ - name: z - .string({ - required_error: 'Nama unit harus diisi', - }) - .min(1, 'Nama unit harus diisi'), - - code: z - .string({ - required_error: 'Kode unit harus diisi', - }) - .min(1, 'Kode unit harus diisi'), - parentId: z.preprocess( - (input: unknown) => { - if (typeof input === 'string') { - // Handle empty string case - if (input.trim() === '') { - return 0 - } - return Number(input) - } - - return input - }, - z - .number({ - required_error: 'Instalasi induk harus dipilih', - }) - .refine((num) => num > 0, 'Instalasi induk harus dipilih'), - ), -}) diff --git a/app/components/content/unit/list-prev.vue b/app/components/content/unit/list-prev.vue deleted file mode 100644 index e5498f25..00000000 --- a/app/components/content/unit/list-prev.vue +++ /dev/null @@ -1,207 +0,0 @@ - - - - - diff --git a/app/components/content/unit/list.vue b/app/components/content/unit/list.vue index 8105eb79..d8ffafa5 100644 --- a/app/components/content/unit/list.vue +++ b/app/components/content/unit/list.vue @@ -30,8 +30,10 @@ import { } from '~/handlers/unit.handler' // Services -import { getUnits, getUnitDetail } from '~/services/unit.service' +import { getList, getDetail } from '~/services/unit.service' +import { getValueLabelList as getInstallationList } from '~/services/installation.service' +const installations = ref<{ value: string; label: string }[]>([]) const title = ref('') const { @@ -43,8 +45,13 @@ const { handleSearch, fetchData: getUnitList, } = usePaginatedList({ - fetchFn: async ({ page, search }) => { - const result = await getUnits({ search, page }) + fetchFn: async (params: any) => { + const result = await getList({ + search: params.search, + 'page-number': params['page-number'] || 0, + 'page-size': params['page-size'] || 10, + includes: 'installation', + }) return { success: result.success || false, body: result.body || {} } }, entityName: 'unit', @@ -82,7 +89,7 @@ provide('rec_item', recItem) provide('table_data_loader', isLoading) const getCurrentUnitDetail = async (id: number | string) => { - const result = await getUnitDetail(id) + const result = await getDetail(id) if (result.success) { const currentValue = result.body?.data || {} recItem.value = currentValue @@ -110,6 +117,7 @@ watch([recId, recAction], () => { }) onMounted(async () => { + installations.value = await getInstallationList() await getUnitList() }) @@ -127,6 +135,7 @@ onMounted(async () => { { - const result = await getUoms({ search, page }) + fetchFn: async (params: any) => { + const result = await getList({ + search: params.search, + 'page-number': params['page-number'] || 0, + 'page-size': params['page-size'] || 10, + }) return { success: result.success || false, body: result.body || {} } }, entityName: 'uom', @@ -81,7 +85,7 @@ provide('rec_item', recItem) provide('table_data_loader', isLoading) const getCurrentUomDetail = async (id: number | string) => { - const result = await getUomDetail(id) + const result = await getDetail(id) if (result.success) { const currentValue = result.body?.data || {} recItem.value = currentValue diff --git a/app/components/pub/my-ui/select-tree/leaf.vue b/app/components/pub/my-ui/select-tree/leaf.vue index 81dabf2b..d98b8b27 100644 --- a/app/components/pub/my-ui/select-tree/leaf.vue +++ b/app/components/pub/my-ui/select-tree/leaf.vue @@ -24,7 +24,7 @@ function handleSelect(value: string) { :class="{ 'pl-8': shouldAlign }" @select="() => handleSelect(item.value)" > - {{ item.label }} + {{ item.label }} .leaf-node { - @apply w-full; + width: 100%; } diff --git a/app/components/pub/my-ui/select-tree/tree-select.vue b/app/components/pub/my-ui/select-tree/tree-select.vue index d0525336..1994e533 100644 --- a/app/components/pub/my-ui/select-tree/tree-select.vue +++ b/app/components/pub/my-ui/select-tree/tree-select.vue @@ -11,6 +11,7 @@ const props = defineProps<{ const modelValue = defineModel() const open = ref(false) +const searchValue = ref('') function handleSelect(newVal: string) { modelValue.value = newVal @@ -30,6 +31,27 @@ function findLabel(value: string, items: TreeItem[]): string | undefined { const selectedLabel = computed(() => { return modelValue.value ? findLabel(modelValue.value, props.data) : '--- select item' }) + +const filteredData = computed(() => { + if (!searchValue.value) return props.data + // recursive filter + function filterTree(items: TreeItem[]): TreeItem[] { + return items + .map(item => { + const match = item.label.toLowerCase().includes(searchValue.value.toLowerCase()) + let children: TreeItem[] | undefined = undefined + if (item.children) { + children = filterTree(item.children) + } + if (match || (children && children.length > 0)) { + return { ...item, children } + } + return null + }) + .filter(Boolean) as TreeItem[] + } + return filterTree(props.data) +})