✨ feat (encounter): implement general consent feature
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
<script setup lang="ts">
|
||||
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'
|
||||
|
||||
// Helpers
|
||||
import type z from 'zod'
|
||||
import { toTypedSchema } from '@vee-validate/zod'
|
||||
import { useForm } from 'vee-validate'
|
||||
import { genBase } from '~/models/_base'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: any
|
||||
schema: z.ZodSchema<any>
|
||||
excludeFields?: string[]
|
||||
isReadonly?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:modelValue', val: any): void
|
||||
(e: 'submit', val: any): void
|
||||
}>()
|
||||
|
||||
// Setup form
|
||||
const {
|
||||
validate: _validate,
|
||||
defineField,
|
||||
handleSubmit,
|
||||
errors,
|
||||
values,
|
||||
} = useForm({
|
||||
validationSchema: toTypedSchema(props.schema),
|
||||
initialValues: props.modelValue,
|
||||
})
|
||||
|
||||
watch(values, (val) => emit('update:modelValue', val), { deep: true })
|
||||
|
||||
const [primaryComplaint, primaryComplaintAttrs] = defineField('prim-compl')
|
||||
const [pastDisease, pastDiseaseAttrs] = defineField('past-disease')
|
||||
const [currentDisease, currentDiseaseAttrs] = defineField('current-disease')
|
||||
const [gcs, gcsAttrs] = defineField('gcs')
|
||||
const [respiratoryRate, respiratoryRateAttrs] = defineField('respiratory-rate')
|
||||
const [respiratoryRateType, respiratoryRateTypeAttrs] = defineField('respiratory-rate-type')
|
||||
const [pulse, pulseAttrs] = defineField('pulse')
|
||||
const [pulseType, pulseTypeAttrs] = defineField('pulse-type')
|
||||
const [rightArmBp, rightArmBpAttrs] = defineField('right-arm-bp')
|
||||
const [leftArmBp, leftArmBpAttrs] = defineField('left-arm-bp')
|
||||
const [axillaryTemp, axillaryTempAttrs] = defineField('axillary-temp')
|
||||
const [rektalTemp, rektalTempAttrs] = defineField('rektal-temp')
|
||||
const [skin, skinAttrs] = defineField('skin')
|
||||
const [head, headAttrs] = defineField('head')
|
||||
const [ear, earAttrs] = defineField('ear')
|
||||
const [nose, noseAttrs] = defineField('nose')
|
||||
const [oralCavity, oralCavityAttrs] = defineField('oral-cavity')
|
||||
const [eye, eyeAttrs] = defineField('eye')
|
||||
const [otherBodyPart, otherBodyPartAttrs] = defineField('other-body-part')
|
||||
const [neck, neckAttrs] = defineField('neck')
|
||||
const [thyroid, thyroidAttrs] = defineField('thyroid')
|
||||
const [thorax, thoraxAttrs] = defineField('thorax')
|
||||
const [heart, heartAttrs] = defineField('heart')
|
||||
const [lung, lungAttrs] = defineField('lung')
|
||||
const [abdomen, abdomenAttrs] = defineField('abdomen')
|
||||
const [heart2, heart2Attrs] = defineField('heart2')
|
||||
const [lien, lienAttrs] = defineField('lien')
|
||||
const [back, backAttrs] = defineField('back')
|
||||
const [extremity, extremityAttrs] = defineField('extremity')
|
||||
const [gender, genderAttrs] = defineField('gender')
|
||||
const [rectum, rectumAttrs] = defineField('rectum')
|
||||
const [systemSyaraf, systemSyarafAttrs] = defineField('system-syaraf')
|
||||
const [nervousSystem, nervousSystemAttrs] = defineField('nervous-system')
|
||||
const [cardioRespiratory, cardioRespiratoryAttrs] = defineField('cardio-respiratory')
|
||||
const [imaging, imagingAttrs] = defineField('imaging')
|
||||
const [laboratory, laboratoryAttrs] = defineField('laboratory')
|
||||
|
||||
const validate = async () => {
|
||||
const result = await _validate()
|
||||
console.log('Component validate() result:', result)
|
||||
|
||||
return {
|
||||
valid: true,
|
||||
data: result.values,
|
||||
errors: result.errors,
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ validate })
|
||||
|
||||
const icdPreview = inject('icdPreview')
|
||||
|
||||
const isExcluded = (key: string) => props.excludeFields?.includes(key)
|
||||
const disorders = ref<string[]>([])
|
||||
const therapies = ref<string[]>([])
|
||||
const summary = ref('')
|
||||
|
||||
const disorderOptions = [
|
||||
'Fungsi Otot',
|
||||
'Fungsi Sendi',
|
||||
'Fungsi Jalan',
|
||||
'Fungsi Syaraf',
|
||||
'Fungsi Koordinasi',
|
||||
'Jantung',
|
||||
'Fungsi Respirasi',
|
||||
'Fungsi Menelan',
|
||||
'Fungsi Bladder',
|
||||
'Fungsi Bowel',
|
||||
'Fungsi Luhur',
|
||||
'Fungsi Kontrol Postur',
|
||||
'Fungsi Eksekusi',
|
||||
'Fungsi Ortosa/Protesa',
|
||||
'Gangguan Aktivitas Sehari-hari',
|
||||
'Lainnya',
|
||||
]
|
||||
|
||||
const therapyOptions = ['Terapi Latihan', 'Modalitas Fisik', 'Protesa/Ortosa', 'Medikamentosa', 'Lain-lain: Konsultasi']
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<form id="entry-form">
|
||||
<div class="mb-5 border-b border-b-slate-300 pb-3 text-lg xl:text-xl">
|
||||
<Block>
|
||||
<Cell>
|
||||
<Label dynamic>Tanggal</Label>
|
||||
<Field :errMessage="errors['prim-compl']">
|
||||
<Textarea
|
||||
v-model="primaryComplaint"
|
||||
v-bind="primaryComplaintAttrs"
|
||||
/>
|
||||
</Field>
|
||||
</Cell>
|
||||
</Block>
|
||||
<Separator class="mt-8" />
|
||||
|
||||
<div class="my-2">
|
||||
<h1 class="font-semibold">Anggota Keluarga dan Penanggung Jawab</h1>
|
||||
</div>
|
||||
|
||||
<div class="my-2 rounded-md border border-slate-300 p-4">
|
||||
<Block :colCount="2">
|
||||
<Cell>
|
||||
<Label dynamic>Pernapasan</Label>
|
||||
<Field>
|
||||
<Input
|
||||
v-model="respiratoryRate"
|
||||
v-bind="respiratoryRateAttrs"
|
||||
/>
|
||||
</Field>
|
||||
</Cell>
|
||||
|
||||
<Cell>
|
||||
<Label dynamic>Jenis</Label>
|
||||
<Field>
|
||||
<Input
|
||||
v-model="respiratoryRateType"
|
||||
v-bind="respiratoryRateTypeAttrs"
|
||||
/>
|
||||
</Field>
|
||||
</Cell>
|
||||
</Block>
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<h1 class="font-semibold">Penanggung Jawab</h1>
|
||||
</div>
|
||||
|
||||
<div class="my-2 rounded-md border border-slate-300 p-4">
|
||||
<Block :colCount="2">
|
||||
<Cell>
|
||||
<Label dynamic>Pernapasan</Label>
|
||||
<Field>
|
||||
<Input
|
||||
v-model="respiratoryRate"
|
||||
v-bind="respiratoryRateAttrs"
|
||||
/>
|
||||
</Field>
|
||||
</Cell>
|
||||
|
||||
<Cell>
|
||||
<Label dynamic>Jenis</Label>
|
||||
<Field>
|
||||
<Input
|
||||
v-model="respiratoryRateType"
|
||||
v-bind="respiratoryRateTypeAttrs"
|
||||
/>
|
||||
</Field>
|
||||
</Cell>
|
||||
</Block>
|
||||
</div>
|
||||
|
||||
<Separator class="mt-8" />
|
||||
|
||||
<div class="my-2">
|
||||
<h1 class="font-semibold">Pemberi Informasi</h1>
|
||||
</div>
|
||||
|
||||
<div class="my-2 rounded-md border border-slate-300 p-4">
|
||||
<Block>
|
||||
<Cell>
|
||||
<Label dynamic>Jenis</Label>
|
||||
<Field>
|
||||
<Input
|
||||
v-model="respiratoryRateType"
|
||||
v-bind="respiratoryRateTypeAttrs"
|
||||
/>
|
||||
</Field>
|
||||
</Cell>
|
||||
</Block>
|
||||
</div>
|
||||
|
||||
<Separator class="mt-8" />
|
||||
|
||||
<div class="my-2">
|
||||
<h1 class="font-semibold">Saksi</h1>
|
||||
</div>
|
||||
|
||||
<div class="my-2 rounded-md border border-slate-300 p-4">
|
||||
<Block :colCount="2">
|
||||
<Cell>
|
||||
<Label dynamic>Pernapasan</Label>
|
||||
<Field>
|
||||
<Input
|
||||
v-model="respiratoryRate"
|
||||
v-bind="respiratoryRateAttrs"
|
||||
/>
|
||||
</Field>
|
||||
</Cell>
|
||||
|
||||
<Cell>
|
||||
<Label dynamic>Jenis</Label>
|
||||
<Field>
|
||||
<Input
|
||||
v-model="respiratoryRateType"
|
||||
v-bind="respiratoryRateTypeAttrs"
|
||||
/>
|
||||
</Field>
|
||||
</Cell>
|
||||
</Block>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
@@ -0,0 +1,57 @@
|
||||
import type { Config, RecComponent, RecStrFuncComponent, RecStrFuncUnknown } from '~/components/pub/my-ui/data-table'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
import type { GeneralConsent } from '~/models/general-consent'
|
||||
|
||||
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: 'Anggota Keluarga' },
|
||||
{ label: 'Penanggung Jawab' },
|
||||
{ label: 'Pemberi Informasi' },
|
||||
{ label: 'Saksi 1' },
|
||||
{ label: 'Saksi 2' },
|
||||
{ label: '' },
|
||||
],
|
||||
],
|
||||
keys: ['date', 'dstUnit.name', 'dstDoctor.name', 'responsible', '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 GeneralConsent
|
||||
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,
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<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 { config } from './list.cfg'
|
||||
|
||||
interface Props {
|
||||
data: any[]
|
||||
paginationMeta: PaginationMeta
|
||||
}
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
pageChange: [page: number]
|
||||
}>()
|
||||
|
||||
function handlePageChange(page: number) {
|
||||
emit('pageChange', page)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="space-y-4">
|
||||
<PubMyUiDataTable
|
||||
v-bind="config"
|
||||
:rows="data"
|
||||
:skeleton-size="paginationMeta?.pageSize"
|
||||
/>
|
||||
<!-- FIXME: pindahkan ke content/division/list.vue -->
|
||||
<PaginationView
|
||||
:pagination-meta="paginationMeta"
|
||||
@page-change="handlePageChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user