feat/consulation-82: done

This commit is contained in:
2025-10-20 09:34:42 +07:00
parent e1358c0d9e
commit f3b45f2cb1
8 changed files with 79 additions and 66 deletions
+10 -10
View File
@@ -10,10 +10,12 @@ import type z from 'zod'
import { toTypedSchema } from '@vee-validate/zod'
import { useForm } from 'vee-validate'
import Textarea from '~/components/pub/ui/textarea/Textarea.vue'
import type { CreateDto } from '~/models/consultation'
interface Props {
schema: z.ZodSchema<any>
values: any
values: CreateDto
encounter_id: number
units: { value: string; label: string }[]
isLoading?: boolean
isReadonly?: boolean
@@ -31,11 +33,9 @@ const today = new Date()
const { defineField, errors, meta } = useForm({
validationSchema: toTypedSchema(props.schema),
initialValues: {
id: 0,
encounter_id: 0,
date: props.values.date || today.toISOString().slice(0, 10),
problem: '',
unit_id: 0,
dstUnit_id: 0,
} as Partial<ConsultationFormData>,
})
@@ -45,8 +45,9 @@ const [problem, problemAttrs] = defineField('problem')
// Fill fields from props.values if provided
if (props.values) {
if (props.values.unit_id !== undefined) unit_id.value = props.values.unit_id
if (props.values.code !== undefined) problem.value = props.values.problem
if (props.values.date !== undefined) date.value = props.values.date.substring(0, 10)
if (props.values.dstUnit_id !== undefined) unit_id.value = props.values.dstUnit_id
if (props.values.problem !== undefined) problem.value = props.values.problem
}
const resetForm = () => {
@@ -58,11 +59,10 @@ const resetForm = () => {
// Form submission handler
function onSubmitForm(values: any) {
const formData: ConsultationFormData = {
id: 0,
encounter_id: 0,
date: date.value || '',
encounter_id: props.encounter_id,
date: date.value ? `${date.value}T00:00:00Z` : '',
problem: problem.value || '',
unit_id: unit_id.value || 0,
dstUnit_id: unit_id.value || 0,
}
emit('submit', formData, resetForm)
}
@@ -0,0 +1,54 @@
import type { Config, RecComponent, RecStrFuncComponent, RecStrFuncUnknown } from '~/components/pub/my-ui/data-table'
import { defineAsyncComponent } from 'vue'
import type { Consultation } from '~/models/consultation'
type SmallDetailDto = any
const action = defineAsyncComponent(() => import('~/components/pub/my-ui/data/dropdown-action-ud.vue'))
export const config: Config = {
cols: [{ width: 100 }, {}, {}, {}, { width: 50 }],
headers: [[
{ label: 'Tanggal' },
{ label: 'Tujuan' },
{ label: 'Dokter' },
{ label: 'Pertanyaan' },
{ label: 'Jawaban' },
{ label: '' },
]],
keys: ['date', 'dstUnit.name', 'dstDoctor.name', 'problem', 'solution', 'action'],
delKeyNames: [
{ key: 'data', label: 'Tanggal' },
{ key: 'dstDoctor.name', label: 'Dokter' },
],
parses: {
action(rec, idx) {
const res: RecComponent = {
idx,
rec: rec as object,
component: action,
props: {
size: 'sm',
},
}
return res
},
date(rec) {
const recX = rec as Consultation
return recX.date?.substring(0, 10) || '-'
}
},
components: {
action(rec, idx) {
const res: RecComponent = {
idx,
rec: rec as object,
component: action,
props: {
size: 'sm',
},
}
return res
},
} as RecStrFuncComponent,
htmls: {} as RecStrFuncUnknown,
}
-40
View File
@@ -1,40 +0,0 @@
import type {
Col,
KeyLabel,
RecComponent,
RecStrFuncComponent,
RecStrFuncUnknown,
Th,
} from '~/components/pub/my-ui/data/types'
import { defineAsyncComponent } from 'vue'
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 header: Th[][] = [[{ label: 'Tanggal' }, { label: 'Dokter' }, { label: 'Tujuan' }, { label: 'Pertanyaan' }, { label: 'Jawaban' }, { label: '' }]]
export const keys = ['date', 'dstDoctor.name', 'dstUnit.name', 'case', 'solution', 'action']
export const delKeyNames: KeyLabel[] = [
{ key: 'data', label: 'Tanggal' },
{ key: 'dstDoctor.name', label: 'Dokter' },
]
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 = {}
+4 -9
View File
@@ -1,14 +1,13 @@
<script setup lang="ts">
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
import PaginationView from '~/components/pub/my-ui/pagination/pagination-view.vue'
import { cols, funcComponent, funcHtml, header, keys } from './list'
import { config } from './list.cfg'
interface Props {
data: any[]
paginationMeta: PaginationMeta
}
defineProps<Props>()
const props = defineProps<Props>()
const emit = defineEmits<{
pageChange: [page: number]
@@ -21,13 +20,9 @@ function handlePageChange(page: number) {
<template>
<div class="space-y-4">
<PubBaseDataTable
<PubMyUiDataTable
v-bind="config"
:rows="data"
:cols="cols"
:header="header"
:keys="keys"
:func-html="funcHtml"
:func-component="funcComponent"
:skeleton-size="paginationMeta?.pageSize"
/>
<!-- FIXME: pindahkan ke content/division/list.vue -->
+6 -2
View File
@@ -41,7 +41,6 @@ interface Props {
encounter: Encounter
}
const props = defineProps<Props>()
console.log(props.encounter);
let units = ref<{ value: string; label: string }[]>([])
const title = ref('')
@@ -56,7 +55,10 @@ const {
fetchData: getMyList,
} = usePaginatedList({
fetchFn: async ({ page, search }) => {
const result = await getList({ search, page })
const result = await getList({ 'encounter-id': props.encounter.id, includes: 'encounter,dstUnit', search, page })
if (result.success) {
data.value = result.body.data;
}
return { success: result.success || false, body: result.body || {} }
},
entityName: 'consultation',
@@ -148,6 +150,7 @@ onMounted(async () => {
<Entry
:schema="ConsultationSchema"
:values="recItem"
:encounter_id="props.encounter.id"
:units="units"
:is-loading="isProcessing"
:is-readonly="isReadonly"
@@ -165,6 +168,7 @@ onMounted(async () => {
</Dialog>
<!-- Record Confirmation Modal -->
{{ isRecordConfirmationOpen }}
<RecordConfirmation
v-model:open="isRecordConfirmationOpen"
action="delete"
+1 -1
View File
@@ -56,7 +56,7 @@ const tabs: TabItem[] = [
{ value: 'mcu-lab-pa', label: 'Order Lab PA' },
{ value: 'medical-action', label: 'Order Ruang Tindakan' },
{ value: 'mcu-result', label: 'Hasil Penunjang' },
{ value: 'consultation', label: 'Konsultasi', component: Consultation, props: { encounter } },
{ value: 'consultation', label: 'Konsultasi', component: Consultation, props: { encounter: data } },
{ value: 'resume', label: 'Resume' },
{ value: 'control', label: 'Surat Kontrol' },
{ value: 'screening', label: 'Skrinning MPP' },
+1 -1
View File
@@ -13,7 +13,7 @@ export interface CreateDto {
encounter_id: number
date: string
problem: string
unit_id: number
dstUnit_id: number
}
export interface UpdateDto {
+3 -3
View File
@@ -1,13 +1,13 @@
import { z } from 'zod'
import type { Consultation } from '~/models/consultation'
import type { CreateDto } from '~/models/consultation'
const ConsultationSchema = z.object({
date: z.string({ required_error: 'Tanggal harus diisi' }),
unit_id: z.number({ required_error: 'Unit harus diisi' }),
dstUnit_id: z.number({ required_error: 'Unit harus diisi' }),
problem: z.string({ required_error: 'Uraian harus diisi' }).min(20, 'Uraian minimum 20 karakter'),
})
type ConsultationFormData = z.infer<typeof ConsultationSchema> & (Consultation)
type ConsultationFormData = z.infer<typeof ConsultationSchema> & (CreateDto)
export { ConsultationSchema }
export type { ConsultationFormData }