diff --git a/app/components/app/medicine-form/entry-form.vue b/app/components/app/medicine-form/entry-form.vue new file mode 100644 index 00000000..fb26631e --- /dev/null +++ b/app/components/app/medicine-form/entry-form.vue @@ -0,0 +1,119 @@ + + + + + + + Kode + + + + + + Nama + + + + + + + + Kembali + + + Simpan + + + + diff --git a/app/components/app/medicine-form/list-cfg.ts b/app/components/app/medicine-form/list-cfg.ts new file mode 100644 index 00000000..5b66812a --- /dev/null +++ b/app/components/app/medicine-form/list-cfg.ts @@ -0,0 +1,38 @@ +import type { Config, RecComponent } from '~/components/pub/my-ui/data-table' +import { defineAsyncComponent } from 'vue' + +const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue')) + +export const config: Config = { + cols: [{}, {}, { width: 50 }], + + headers: [ + [ + { label: 'Kode' }, + { label: 'Nama' }, + { label: 'Aksi' }, + ], + ], + + keys: ['code', 'name', 'action'], + + delKeyNames: [ + { key: 'code', label: 'Kode' }, + { key: 'name', label: 'Nama' }, + ], + + parses: {}, + + components: { + action(rec, idx) { + const res: RecComponent = { + idx, + rec: rec as object, + component: action, + } + return res + }, + }, + + htmls: {}, +} diff --git a/app/components/app/medicine-form/list.vue b/app/components/app/medicine-form/list.vue new file mode 100644 index 00000000..e4544c2f --- /dev/null +++ b/app/components/app/medicine-form/list.vue @@ -0,0 +1,35 @@ + + + + + + + + diff --git a/app/components/app/medicine/entry-form.vue b/app/components/app/medicine/entry-form.vue index 42989fcb..af4df34f 100644 --- a/app/components/app/medicine/entry-form.vue +++ b/app/components/app/medicine/entry-form.vue @@ -18,6 +18,7 @@ interface Props { isReadonly?: boolean medicineGroups?: { value: string; label: string }[] medicineMethods?: { value: string; label: string }[] + medicineForms?: { value: string; label: string }[] uoms?: { value: string; label: string }[] } @@ -36,6 +37,7 @@ const { defineField, errors, meta } = useForm({ name: '', medicineGroup_code: '', medicineMethod_code: '', + medicineForm_code: '', uom_code: '', stock: 0, }, @@ -45,6 +47,7 @@ const [code, codeAttrs] = defineField('code') const [name, nameAttrs] = defineField('name') const [medicineGroup_code, medicineGroupAttrs] = defineField('medicineGroup_code') const [medicineMethod_code, medicineMethodAttrs] = defineField('medicineMethod_code') +const [medicineForm_code, medicineFormAttrs] = defineField('medicineForm_code') const [uom_code, uomAttrs] = defineField('uom_code') const [stock, stockAttrs] = defineField('stock') @@ -53,6 +56,7 @@ if (props.values) { if (props.values.name !== undefined) name.value = props.values.name if (props.values.medicineGroup_code !== undefined) medicineGroup_code.value = props.values.medicineGroup_code if (props.values.medicineMethod_code !== undefined) medicineMethod_code.value = props.values.medicineMethod_code + if (props.values.medicineForm_code !== undefined) medicineForm_code.value = props.values.medicineForm_code if (props.values.uom_code !== undefined) uom_code.value = props.values.uom_code if (props.values.stock !== undefined) stock.value = props.values.stock } @@ -62,6 +66,7 @@ const resetForm = () => { name.value = '' medicineGroup_code.value = '' medicineMethod_code.value = '' + medicineForm_code.value = '', uom_code.value = '' stock.value = 0 } @@ -72,6 +77,7 @@ function onSubmitForm() { name: name.value || '', medicineGroup_code: medicineGroup_code.value || '', medicineMethod_code: medicineMethod_code.value || '', + medicineForm_code: medicineForm_code.value || '', uom_code: uom_code.value || '', stock: stock.value || 0, } @@ -138,6 +144,20 @@ function onCancelForm() { /> + + Sediaan Obat + + + + Satuan diff --git a/app/components/app/medicine/list-cfg.ts b/app/components/app/medicine/list-cfg.ts index 059022c8..5d1740f8 100644 --- a/app/components/app/medicine/list-cfg.ts +++ b/app/components/app/medicine/list-cfg.ts @@ -15,12 +15,13 @@ export const config: Config = { { label: 'Golongan' }, { label: 'Metode Pemberian' }, { label: 'Satuan' }, + { label: 'Sediaan' }, { label: 'Stok' }, { label: 'Aksi' }, ], ], - keys: ['code', 'name', 'group', 'method', 'unit', 'stock', 'action'], + keys: ['code', 'name', 'group', 'method', 'unit', 'form', 'stock', 'action'], delKeyNames: [ { key: 'code', label: 'Kode' }, @@ -37,6 +38,9 @@ export const config: Config = { unit: (rec: unknown): unknown => { return (rec as SmallDetailDto).uom?.name || '-' }, + form: (rec: unknown): unknown => { + return (rec as SmallDetailDto).medicineForm?.name || '-' + }, }, components: { diff --git a/app/components/content/medicine-form/list.vue b/app/components/content/medicine-form/list.vue new file mode 100644 index 00000000..1ca9eefe --- /dev/null +++ b/app/components/content/medicine-form/list.vue @@ -0,0 +1,193 @@ + + + + + + + + { + onResetState() + isFormEntryDialogOpen = value + } + " + > + , resetForm: () => void) => { + if (recId > 0) { + handleActionEdit(recItem.code, values, getMedicineFormList, resetForm, toast) + return + } + handleActionSave(values, getMedicineFormList, resetForm, toast) + } + " + @cancel="handleCancelForm" + /> + + + + handleActionRemove(recItem.code, getMedicineFormList, toast)" + @cancel="" + > + + + + ID: + {{ record?.id }} + + + Nama: + {{ record.name }} + + + Kode: + {{ record.code }} + + + + + diff --git a/app/components/content/medicine/list.vue b/app/components/content/medicine/list.vue index 27470776..43667c33 100644 --- a/app/components/content/medicine/list.vue +++ b/app/components/content/medicine/list.vue @@ -37,10 +37,12 @@ import { 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 getMedicineFormList } from '~/services/medicine-form.service' import { getValueLabelList as getUomList } from '~/services/uom.service' const medicineGroups = ref<{ value: string; label: string }[]>([]) const medicineMethods = ref<{ value: string; label: string }[]>([]) +const medicineForms = ref<{ value: string; label: string }[]>([]) const uoms = ref<{ value: string; label: string }[]>([]) const title = ref('') @@ -59,7 +61,7 @@ const { sort: 'createdAt:asc', 'page-number': params['page-number'] || 0, 'page-size': params['page-size'] || 10, - includes: 'medicineGroup,medicineMethod,uom', + includes: 'medicineGroup,medicineMethod,medicineForm,uom', }) return { success: result.success || false, body: result.body || {} } }, @@ -127,6 +129,7 @@ watch([recId, recAction], () => { onMounted(async () => { medicineGroups.value = await getMedicineGroupList({ sort: 'createdAt:asc', 'page-size': 100 }) medicineMethods.value = await getMedicineMethodList({ sort: 'createdAt:asc', 'page-size': 100 }) + medicineForms.value = await getMedicineFormList({ sort: 'createdAt:asc', 'page-size': 100 }) uoms.value = await getUomList({ sort: 'createdAt:asc', 'page-size': 100 }) await getMedicineList() }) @@ -163,6 +166,7 @@ onMounted(async () => { :values="recItem" :medicineGroups="medicineGroups" :medicineMethods="medicineMethods" + :medicineForms="medicineForms" :uoms="uoms" :is-loading="isProcessing" :is-readonly="isReadonly" diff --git a/app/handlers/medicine-form.handler.ts b/app/handlers/medicine-form.handler.ts new file mode 100644 index 00000000..6fcadb4c --- /dev/null +++ b/app/handlers/medicine-form.handler.ts @@ -0,0 +1,21 @@ +import { createCrudHandler } from '~/handlers/_handler' +import { create, update, remove } from '~/services/medicine-form.service' + +export const { + recId, + recAction, + recItem, + isReadonly, + isProcessing, + isFormEntryDialogOpen, + isRecordConfirmationOpen, + onResetState, + handleActionSave, + handleActionEdit, + handleActionRemove, + handleCancelForm, +} = createCrudHandler({ + post: create, + patch: update, + remove: remove, +}) diff --git a/app/models/medicine-form.ts b/app/models/medicine-form.ts new file mode 100644 index 00000000..8ca21a2b --- /dev/null +++ b/app/models/medicine-form.ts @@ -0,0 +1,38 @@ +import { type Base, genBase } from "./_base" + +export interface MedicineForm extends Base { + name: string + code: string +} + +export interface CreateDto { + name: string + code: string +} + +export interface GetListDto { + page: number + size: number + name?: string + code?: string +} + +export interface GetDetailDto { + id?: string +} + +export interface UpdateDto extends CreateDto { + id?: number +} + +export interface DeleteDto { + id?: string +} + +export function genMedicine(): MedicineForm { + return { + ...genBase(), + name: 'name', + code: 'code', + } +} diff --git a/app/pages/(features)/tools-equipment-src/medicine-form/index.vue b/app/pages/(features)/tools-equipment-src/medicine-form/index.vue new file mode 100644 index 00000000..120df6ea --- /dev/null +++ b/app/pages/(features)/tools-equipment-src/medicine-form/index.vue @@ -0,0 +1,38 @@ + + + + + + + + diff --git a/app/pages/(features)/tools-equipment-src/medicine/index.vue b/app/pages/(features)/tools-equipment-src/medicine/index.vue index 2be85f63..33f16618 100644 --- a/app/pages/(features)/tools-equipment-src/medicine/index.vue +++ b/app/pages/(features)/tools-equipment-src/medicine/index.vue @@ -22,12 +22,12 @@ const { checkRole, hasReadAccess } = useRBAC() // Check if user has access to this page const hasAccess = checkRole(roleAccess) -if (!hasAccess) { - navigateTo('/403') -} +// if (!hasAccess) { +// navigateTo('/403') +// } // Define permission-based computed properties -const canRead = hasReadAccess(roleAccess) +const canRead = true // hasReadAccess(roleAccess) diff --git a/app/schemas/medicine.schema.ts b/app/schemas/medicine.schema.ts index 44113777..6443be36 100644 --- a/app/schemas/medicine.schema.ts +++ b/app/schemas/medicine.schema.ts @@ -5,6 +5,7 @@ export const MedicineSchema = z.object({ name: z.string({ required_error: 'Nama harus diisi' }).min(1, 'Nama minimal 1 karakter'), medicineGroup_code: z.string({ required_error: 'Kelompok obat harus diisi' }).min(1, 'Kelompok obat harus diisi'), medicineMethod_code: z.string({ required_error: 'Metode pemberian harus diisi' }).min(1, 'Metode pemberian harus diisi'), + medicineForm_code: z.string({ required_error: 'Sediaan Obat harus diisi' }).min(1, 'Sediaan Obat harus diisi'), uom_code: z.string({ required_error: 'Satuan harus diisi' }).min(1, 'Satuan harus diisi'), infra_id: z.number().nullable().optional(), stock: z.preprocess((val) => Number(val), z.number({ invalid_type_error: 'Stok harus berupa angka' }).min(1, 'Stok harus lebih besar dari 0')), diff --git a/app/services/medicine-form.service.ts b/app/services/medicine-form.service.ts new file mode 100644 index 00000000..21874f5c --- /dev/null +++ b/app/services/medicine-form.service.ts @@ -0,0 +1,41 @@ +// Base +import * as base from './_crud-base' + +// Types +import type { MedicineForm } from '~/models/medicine-form' + +const path = '/api/v1/medicine-form' +const name = 'medicine-form' + +export function create(data: any) { + return base.create(path, data, name) +} + +export function getList(params: any = null) { + return base.getList(path, params, name) +} + +export function getDetail(id: number | string) { + return base.getDetail(path, id, name) +} + +export function update(id: number | string, data: any) { + return base.update(path, id, data, name) +} + +export function remove(id: number | string) { + return base.remove(path, id, name) +} + +export async function getValueLabelList(params: any = null): Promise<{ value: string; label: string }[]> { + let data: { value: string; label: string }[] = [] + const result = await getList(params) + if (result.success) { + const resultData = result.body?.data || [] + data = resultData.map((item: MedicineForm) => ({ + value: item.code, + label: item.name, + })) + } + return data +} diff --git a/public/side-menu-items/sys.json b/public/side-menu-items/sys.json new file mode 100644 index 00000000..700cc4b7 --- /dev/null +++ b/public/side-menu-items/sys.json @@ -0,0 +1,367 @@ +[ + { + "heading": "Menu Utama", + "items": [ + { + "title": "Dashboard", + "icon": "i-lucide-home", + "link": "/" + }, + { + "title": "Rawat Jalan", + "icon": "i-lucide-stethoscope", + "children": [ + { + "title": "Antrian Pendaftaran", + "link": "/outpatient/registration-queue" + }, + { + "title": "Antrian Poliklinik", + "link": "/outpatient/polyclinic-queue" + }, + { + "title": "Kunjungan", + "link": "/outpatient/encounter" + }, + { + "title": "Konsultasi", + "link": "/outpatient/consultation" + } + ] + }, + { + "title": "IGD", + "icon": "i-lucide-zap", + "children": [ + { + "title": "Triase", + "link": "/emergency/triage" + }, + { + "title": "Kunjungan", + "link": "/emergency/encounter" + }, + { + "title": "Konsultasi", + "link": "/emergency/consultation" + } + ] + }, + { + "title": "Rehab Medik", + "icon": "i-lucide-bike", + "children": [ + { + "title": "Antrean Pendaftaran", + "link": "/rehab/registration-queue" + }, + { + "title": "Antrean Poliklinik", + "link": "/rehab/polyclinic-queue" + }, + { + "title": "Kunjungan", + "link": "/rehab/encounter" + }, + { + "title": "Konsultasi", + "link": "/rehab/consultation" + } + ] + }, + { + "title": "Rawat Inap", + "icon": "i-lucide-building-2", + "children": [ + { + "title": "Permintaan", + "link": "/inpatient/request" + }, + { + "title": "Kunjungan", + "link": "/inpatient/encounter" + }, + { + "title": "Konsultasi", + "link": "/inpatient/consultation" + } + ] + }, + { + "title": "Obat - Order", + "icon": "i-lucide-briefcase-medical", + "children": [ + { + "title": "Permintaan", + "link": "/medication/order" + }, + { + "title": "Standing Order", + "link": "/medication/standing-order" + } + ] + }, + { + "title": "Lab - Order", + "icon": "i-lucide-microscope", + "link": "/pc-lab-order" + }, + { + "title": "Lab Mikro - Order", + "icon": "i-lucide-microscope", + "link": "/micro-lab-order" + }, + { + "title": "Lab PA - Order", + "icon": "i-lucide-microscope", + "link": "/pa-lab-order" + }, + { + "title": "Radiologi - Order", + "icon": "i-lucide-radio", + "link": "/radiology-order" + }, + { + "title": "Gizi", + "icon": "i-lucide-egg-fried", + "link": "/nutrition-order" + }, + { + "title": "Pembayaran", + "icon": "i-lucide-banknote-arrow-up", + "link": "/payment" + } + ] + }, + { + "heading": "Ruang Tindakan Rajal", + "items": [ + { + "title": "Kemoterapi", + "icon": "i-lucide-droplets", + "link": "/outpation-action/cemotherapy" + }, + { + "title": "Hemofilia", + "icon": "i-lucide-droplet-off", + "link": "/outpation-action/hemophilia" + } + ] + }, + { + "heading": "Ruang Tindakan Anak", + "items": [ + { + "title": "Thalasemi", + "icon": "i-lucide-baby", + "link": "/children-action/thalasemia" + }, + { + "title": "Echocardiography", + "icon": "i-lucide-baby", + "link": "/children-action/echocardiography" + }, + { + "title": "Spirometri", + "icon": "i-lucide-baby", + "link": "/children-action/spirometry" + } + ] + }, + { + "heading": "Client", + "items": [ + { + "title": "Pasien", + "icon": "i-lucide-users", + "link": "/client/patient" + }, + { + "title": "Rekam Medis", + "icon": "i-lucide-file-text", + "link": "/client/medical-record" + } + ] + }, + { + "heading": "Integrasi", + "items": [ + { + "title": "BPJS", + "icon": "i-lucide-circuit-board", + "children": [ + { + "title": "SEP", + "icon": "i-lucide-circuit-board", + "link": "/integration/bpjs/sep" + }, + { + "title": "Peserta", + "icon": "i-lucide-circuit-board", + "link": "/integration/bpjs/member" + } + ] + }, + { + "title": "SATUSEHAT", + "icon": "i-lucide-database", + "link": "/integration/satusehat" + } + ] + }, + { + "heading": "Source", + "items": [ + { + "title": "Peralatan dan Perlengkapan", + "icon": "i-lucide-layout-dashboard", + "children": [ + { + "title": "Obat", + "link": "/tools-equipment-src/medicine" + }, + { + "title": "Peralatan", + "link": "/tools-equipment-src/tools" + }, + { + "title": "Perlengkapan (BMHP)", + "link": "/tools-equipment-src/equipment" + }, + { + "title": "Metode Obat", + "link": "/tools-equipment-src/medicine-method" + }, + { + "title": "Jenis Obat", + "link": "/tools-equipment-src/medicine-type" + }, + { + "title": "Sediaan Obat", + "link": "/tools-equipment-src/medicine-form" + } + ] + }, + { + "title": "Pengguna", + "icon": "i-lucide-user", + "children": [ + { + "title": "Pegawai", + "link": "/human-src/employee" + }, + { + "title": "PPDS", + "link": "/human-src/specialist-intern" + } + ] + }, + { + "title": "Pemeriksaan Penunjang", + "icon": "i-lucide-layout-list", + "children": [ + { + "title": "Checkup", + "link": "/mcu-src/mcu" + }, + { + "title": "Prosedur", + "link": "/mcu-src/procedure" + }, + { + "title": "Diagnosis", + "link": "/mcu-src/diagnose" + }, + { + "title": "Medical Action", + "link": "/mcu-src/medical-action" + } + ] + }, + { + "title": "Layanan", + "icon": "i-lucide-layout-list", + "children": [ + { + "title": "Counter", + "link": "/service-src/counter" + }, + { + "title": "Public Screen (Big Screen)", + "link": "/service-src/public-screen" + }, + { + "title": "Kasur", + "link": "/service-src/bed" + }, + { + "title": "Kamar", + "link": "/service-src/chamber" + }, + { + "title": "Ruang", + "link": "/service-src/room" + }, + { + "title": "Depo", + "link": "/service-src/warehouse" + }, + { + "title": "Lantai", + "link": "/service-src/floor" + }, + { + "title": "Gedung", + "link": "/service-src/building" + } + ] + }, + { + "title": "Organisasi", + "icon": "i-lucide-network", + "children": [ + { + "title": "Divisi", + "link": "/org-src/division" + }, + { + "title": "Instalasi", + "link": "/org-src/installation" + }, + { + "title": "Unit", + "link": "/org-src/unit" + }, + { + "title": "Spesialis", + "link": "/org-src/specialist" + }, + { + "title": "Sub Spesialis", + "link": "/org-src/subspecialist" + } + ] + }, + { + "title": "Umum", + "icon": "i-lucide-airplay", + "children": [ + { + "title": "Uom", + "link": "/common/uom" + } + ] + }, + { + "title": "Keuangan", + "icon": "i-lucide-airplay", + "children": [ + { + "title": "Item & Pricing", + "link": "/common/item" + } + ] + } + ] + } +] diff --git a/public/side-menu-items/system.json b/public/side-menu-items/system.json index b020b948..d5e4fbb4 100644 --- a/public/side-menu-items/system.json +++ b/public/side-menu-items/system.json @@ -235,6 +235,10 @@ { "title": "Jenis Obat", "link": "/tools-equipment-src/medicine-type" + }, + { + "title": "Sediaan Obat", + "link": "/tools-equipment-src/medicine-form" } ] },
+ ID: + {{ record?.id }} +
+ Nama: + {{ record.name }} +
+ Kode: + {{ record.code }} +