Feat: Add & integrate add, edit, detail page
This commit is contained in:
@@ -32,25 +32,30 @@ const {
|
||||
|
||||
const doctors = ref<Array<Item>>([])
|
||||
|
||||
async function fetchDpjp() {
|
||||
async function fetchDpjp(specialistId: string, subspecialistId: string) {
|
||||
doctors.value = await getDoctorLabelList({
|
||||
serviceType: 1,
|
||||
serviceDate: new Date().toISOString().substring(0, 10),
|
||||
specialistCode: 0,
|
||||
includes: 'employee-person',
|
||||
// "unit-id": parseInt(unitId),
|
||||
"specialist-id": parseInt(specialistId),
|
||||
"subspecialist-id": parseInt(subspecialistId),
|
||||
})
|
||||
}
|
||||
|
||||
const selectedDpjpId = inject<Ref<string | null>>("selectedDpjpId")!
|
||||
function handleDpjpChange(selected: string) {
|
||||
console.log(`change dphp`)
|
||||
selectedDpjpId.value = selected ?? null
|
||||
const dpjp = doctors.value.find(s => s.value === selectedDpjpId.value)
|
||||
console.log(dpjp)
|
||||
}
|
||||
// const selectedUnitId = inject<Ref<string | null>>("selectedUnitId")!
|
||||
const selectedSpecialistId = inject<Ref<string | null>>("selectedSpecialistId")!
|
||||
const selectedSubSpecialistId = inject<Ref<string | null>>("selectedSubSpecialistId")!
|
||||
|
||||
onMounted(() => {
|
||||
fetchDpjp()
|
||||
// function handleDpjpChange(selected: string) {
|
||||
// selectedDpjpId.value = selected ?? null
|
||||
// }
|
||||
|
||||
watch([ selectedSpecialistId, selectedSubSpecialistId], () => {
|
||||
if ( selectedSpecialistId.value && selectedSubSpecialistId.value) {
|
||||
fetchDpjp( selectedSpecialistId.value, selectedSubSpecialistId.value)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -82,7 +87,7 @@ onMounted(() => {
|
||||
:placeholder="placeholder"
|
||||
search-placeholder="Cari..."
|
||||
empty-message="Data tidak ditemukan"
|
||||
@update:model-value="handleDpjpChange"
|
||||
:is-disabled="selectedSubSpecialistId === null"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
|
||||
+17
-53
@@ -10,8 +10,7 @@ import { getValueLabelList as getSubspecialistLabelList } from '~/services/subsp
|
||||
import * as DE from '~/components/pub/my-ui/doc-entry'
|
||||
|
||||
const props = defineProps<{
|
||||
specialistFieldName?: string
|
||||
subSpecialistFieldName?: string
|
||||
fieldName?: string
|
||||
label?: string
|
||||
placeholder?: string
|
||||
errors?: FormErrors
|
||||
@@ -23,8 +22,7 @@ const props = defineProps<{
|
||||
}>()
|
||||
|
||||
const {
|
||||
specialistFieldName = 'job',
|
||||
subSpecialistFieldName = 'job',
|
||||
fieldName = 'job',
|
||||
label = 'Pekerjaan',
|
||||
placeholder = 'Pilih pekerjaan',
|
||||
errors,
|
||||
@@ -34,96 +32,62 @@ const {
|
||||
} = props
|
||||
|
||||
const specialists = ref<Array<Item>>([])
|
||||
const subspecialists = ref<Array<Item>>([])
|
||||
|
||||
async function fetchSpecialists() {
|
||||
async function fetchSpecialists(unitId: string) {
|
||||
specialists.value = await getSpecialistLabelList({
|
||||
serviceType: 1,
|
||||
serviceDate: new Date().toISOString().substring(0, 10),
|
||||
specialistCode: 0,
|
||||
})
|
||||
subspecialists.value = await getSubspecialistLabelList({
|
||||
serviceType: 1,
|
||||
serviceDate: new Date().toISOString().substring(0, 10),
|
||||
specialistCode: 0,
|
||||
"unit-id": parseInt(unitId),
|
||||
})
|
||||
}
|
||||
|
||||
const selectedUnitId = inject<Ref<string | null>>("selectedUnitId")!
|
||||
const selectedSpecialistId = inject<Ref<string | null>>("selectedSpecialistId")!
|
||||
|
||||
function handleSpecialistChange(selected: string) {
|
||||
selectedSpecialistId.value = selected ?? null
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchSpecialists()
|
||||
watch([selectedUnitId], () => {
|
||||
if (selectedUnitId.value) {
|
||||
fetchSpecialists(selectedUnitId.value)
|
||||
}
|
||||
})
|
||||
console.log(selectedUnitId.value)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DE.Block :col-count="2" :class="cn('select-field-group', fieldGroupClass, containerClass)">
|
||||
<DE.Block :class="cn('select-field-group', fieldGroupClass, containerClass)">
|
||||
<div>
|
||||
<DE.Label
|
||||
:label-for="specialistFieldName"
|
||||
:label-for="fieldName"
|
||||
:class="cn('select-field-label', labelClass)"
|
||||
:is-required="isRequired"
|
||||
>
|
||||
Spesialis
|
||||
</DE.Label>
|
||||
<DE.Field
|
||||
:id="specialistFieldName"
|
||||
:id="fieldName"
|
||||
:errors="errors"
|
||||
:class="cn('select-field-wrapper')"
|
||||
>
|
||||
<FormField
|
||||
v-slot="{ componentField }"
|
||||
:name="specialistFieldName"
|
||||
:name="fieldName"
|
||||
>
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Combobox
|
||||
class="focus:ring-0 focus:ring-offset-0"
|
||||
:id="specialistFieldName"
|
||||
:id="fieldName"
|
||||
v-bind="componentField"
|
||||
:items="specialists"
|
||||
:placeholder="placeholder"
|
||||
search-placeholder="Cari..."
|
||||
empty-message="Data tidak ditemukan"
|
||||
@update:model-value="handleSpecialistChange"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</DE.Field>
|
||||
</div>
|
||||
<div>
|
||||
<DE.Label
|
||||
:label-for="subSpecialistFieldName"
|
||||
:class="cn('select-field-label', labelClass)"
|
||||
:is-required="isRequired"
|
||||
>
|
||||
Sub Spesialis
|
||||
</DE.Label>
|
||||
<DE.Field
|
||||
:id="subSpecialistFieldName"
|
||||
:errors="errors"
|
||||
:class="cn('select-field-wrapper')"
|
||||
>
|
||||
<FormField
|
||||
v-slot="{ componentField }"
|
||||
:name="subSpecialistFieldName"
|
||||
>
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Combobox
|
||||
class="focus:ring-0 focus:ring-offset-0"
|
||||
:id="subSpecialistFieldName"
|
||||
v-bind="componentField"
|
||||
:items="subspecialists"
|
||||
:placeholder="placeholder"
|
||||
search-placeholder="Cari..."
|
||||
empty-message="Data tidak ditemukan"
|
||||
:is-disabled="!selectedSpecialistId"
|
||||
:is-disabled="selectedUnitId === null"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
@@ -0,0 +1,97 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormErrors } from '~/types/error'
|
||||
import Combobox from '~/components/pub/my-ui/combobox/combobox.vue'
|
||||
import { cn, mapToComboboxOptList } from '~/lib/utils'
|
||||
import { occupationCodes } from '~/lib/constants'
|
||||
import type { Item } from '~/components/pub/my-ui/combobox'
|
||||
import { getValueLabelList as getSubspecialistLabelList } from '~/services/subspecialist.service'
|
||||
|
||||
import * as DE from '~/components/pub/my-ui/doc-entry'
|
||||
|
||||
const props = defineProps<{
|
||||
fieldName?: string
|
||||
label?: string
|
||||
placeholder?: string
|
||||
errors?: FormErrors
|
||||
class?: string
|
||||
selectClass?: string
|
||||
fieldGroupClass?: string
|
||||
labelClass?: string
|
||||
isRequired?: boolean
|
||||
}>()
|
||||
|
||||
const {
|
||||
fieldName = 'job',
|
||||
label = 'Pekerjaan',
|
||||
placeholder = 'Pilih pekerjaan',
|
||||
errors,
|
||||
class: containerClass,
|
||||
fieldGroupClass,
|
||||
labelClass,
|
||||
} = props
|
||||
|
||||
const subspecialists = ref<Array<Item>>([])
|
||||
|
||||
async function fetchSubSpecialists(specialistId: string) {
|
||||
subspecialists.value = await getSubspecialistLabelList({
|
||||
serviceType: 1,
|
||||
serviceDate: new Date().toISOString().substring(0, 10),
|
||||
specialistCode: 0,
|
||||
"specialist-id": parseInt(specialistId),
|
||||
})
|
||||
}
|
||||
|
||||
const selectedSpecialistId = inject<Ref<string | null>>("selectedSpecialistId")!
|
||||
const selectedSubSpecialistId = inject<Ref<string | null>>("selectedSubSpecialistId")!
|
||||
|
||||
function handleSubSpecialistChange(selected: string) {
|
||||
selectedSubSpecialistId.value = selected ?? null
|
||||
}
|
||||
|
||||
watch([selectedSpecialistId], () => {
|
||||
if (selectedSpecialistId.value) {
|
||||
fetchSubSpecialists(selectedSpecialistId.value)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DE.Block :class="cn('select-field-group', fieldGroupClass, containerClass)">
|
||||
<div>
|
||||
<DE.Label
|
||||
:label-for="fieldName"
|
||||
:class="cn('select-field-label', labelClass)"
|
||||
:is-required="isRequired"
|
||||
>
|
||||
Sub Spesialis
|
||||
</DE.Label>
|
||||
<DE.Field
|
||||
:id="fieldName"
|
||||
:errors="errors"
|
||||
:class="cn('select-field-wrapper')"
|
||||
>
|
||||
<FormField
|
||||
v-slot="{ componentField }"
|
||||
:name="fieldName"
|
||||
>
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Combobox
|
||||
class="focus:ring-0 focus:ring-offset-0"
|
||||
:id="fieldName"
|
||||
v-bind="componentField"
|
||||
:items="subspecialists"
|
||||
:placeholder="placeholder"
|
||||
search-placeholder="Cari..."
|
||||
empty-message="Data tidak ditemukan"
|
||||
@update:model-value="handleSubSpecialistChange"
|
||||
:is-disabled="selectedSpecialistId === null"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</DE.Field>
|
||||
</div>
|
||||
</DE.Block>
|
||||
</template>
|
||||
@@ -0,0 +1,85 @@
|
||||
<script setup lang="ts">
|
||||
import type { FormErrors } from '~/types/error'
|
||||
import Combobox from '~/components/pub/my-ui/combobox/combobox.vue'
|
||||
import { cn, mapToComboboxOptList } from '~/lib/utils'
|
||||
import { occupationCodes } from '~/lib/constants'
|
||||
import { getValueLabelList as getUnitLabelList } from '~/services/unit.service'
|
||||
|
||||
import * as DE from '~/components/pub/my-ui/doc-entry'
|
||||
import type { Item } from '~/components/pub/my-ui/combobox'
|
||||
|
||||
const props = defineProps<{
|
||||
fieldName?: string
|
||||
label?: string
|
||||
placeholder?: string
|
||||
errors?: FormErrors
|
||||
class?: string
|
||||
selectClass?: string
|
||||
fieldGroupClass?: string
|
||||
labelClass?: string
|
||||
isRequired?: boolean
|
||||
}>()
|
||||
|
||||
const {
|
||||
fieldName = 'job',
|
||||
label = 'Pekerjaan',
|
||||
placeholder = 'Pilih pekerjaan',
|
||||
errors,
|
||||
class: containerClass,
|
||||
fieldGroupClass,
|
||||
labelClass,
|
||||
} = props
|
||||
|
||||
const units = ref<Array<Item>>([])
|
||||
|
||||
async function fetchData() {
|
||||
units.value = await getUnitLabelList()
|
||||
}
|
||||
|
||||
const selectedUnitId = inject<Ref<string | null>>("selectedUnitId")!
|
||||
function handleDataChange(selected: string) {
|
||||
selectedUnitId.value = selected ?? null
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DE.Cell :class="cn('select-field-group', fieldGroupClass, containerClass)">
|
||||
<DE.Label
|
||||
:label-for="fieldName"
|
||||
:class="cn('select-field-label', labelClass)"
|
||||
:is-required="isRequired"
|
||||
>
|
||||
{{ label }}
|
||||
</DE.Label>
|
||||
<DE.Field
|
||||
:id="fieldName"
|
||||
:errors="errors"
|
||||
:class="cn('select-field-wrapper')"
|
||||
>
|
||||
<FormField
|
||||
v-slot="{ componentField }"
|
||||
:name="fieldName"
|
||||
>
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Combobox
|
||||
class="focus:ring-0 focus:ring-offset-0"
|
||||
:id="fieldName"
|
||||
v-bind="componentField"
|
||||
:items="units"
|
||||
:placeholder="placeholder"
|
||||
search-placeholder="Cari..."
|
||||
empty-message="Data tidak ditemukan"
|
||||
@update:model-value="handleDataChange"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</DE.Field>
|
||||
</DE.Cell>
|
||||
</template>
|
||||
@@ -4,15 +4,22 @@ import { toTypedSchema } from '@vee-validate/zod'
|
||||
import { Form } from '~/components/pub/ui/form'
|
||||
import SelectDate from './_common/select-date.vue'
|
||||
import InputBase from '~/components/pub/my-ui/form/input-base.vue'
|
||||
import SelectSpeciality from './_common/select-speciality.vue'
|
||||
import SelectSpeciality from './_common/select-specialist.vue'
|
||||
import SelectDpjp from './_common/select-dpjp.vue'
|
||||
|
||||
import * as DE from '~/components/pub/my-ui/doc-entry'
|
||||
import SelectUnit from './_common/select-unit.vue'
|
||||
import SelectSubspecialist from './_common/select-subspecialist.vue'
|
||||
import SelectSpecialist from './_common/select-specialist.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
schema: any
|
||||
initialValues?: any
|
||||
errors?: FormErrors
|
||||
|
||||
selectedUnitId?: number | null
|
||||
selectedSpecialistId?: number | null
|
||||
selectedSubSpecialistId?: number | null
|
||||
}>()
|
||||
|
||||
const formSchema = toTypedSchema(props.schema)
|
||||
@@ -50,21 +57,38 @@ defineExpose({
|
||||
:errors="errors"
|
||||
is-required
|
||||
/>
|
||||
<SelectSpeciality
|
||||
specialist-field-name="spesialist_id"
|
||||
sub-specialist-field-name="subspesialist_id"
|
||||
label="Spesialis/Sub Spesialis"
|
||||
placeholder="Pilih Spesialis/Sub Spesialis"
|
||||
:errors="errors"
|
||||
is-required
|
||||
/>
|
||||
<SelectDpjp
|
||||
field-name="doctor_id"
|
||||
label="DPJP"
|
||||
placeholder="Pilih DPJP"
|
||||
:errors="errors"
|
||||
is-required
|
||||
/>
|
||||
<DE.Cell :col-span="2">
|
||||
<DE.Block :col-count="4" :cell-flex="false">
|
||||
<SelectUnit
|
||||
field-name="unit_id"
|
||||
label="Unit"
|
||||
placeholder="Pilih Unit"
|
||||
:errors="errors"
|
||||
is-required
|
||||
/>
|
||||
<SelectSpecialist
|
||||
field-name="specialist_id"
|
||||
label="Spesialis/Sub Spesialis"
|
||||
placeholder="Pilih Spesialis/Sub Spesialis"
|
||||
:errors="errors"
|
||||
is-required
|
||||
/>
|
||||
<SelectSubspecialist
|
||||
field-name="subspecialist_id"
|
||||
label="Spesialis/Sub Spesialis"
|
||||
placeholder="Pilih Spesialis/Sub Spesialis"
|
||||
:errors="errors"
|
||||
is-required
|
||||
/>
|
||||
<SelectDpjp
|
||||
field-name="doctor_id"
|
||||
label="DPJP"
|
||||
placeholder="Pilih DPJP"
|
||||
:errors="errors"
|
||||
is-required
|
||||
/>
|
||||
</DE.Block>
|
||||
</DE.Cell>
|
||||
</DE.Block>
|
||||
</Form>
|
||||
</template>
|
||||
|
||||
@@ -1,23 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import type { Patient } from '~/models/patient'
|
||||
import DetailRow from '~/components/pub/my-ui/form/view/detail-row.vue'
|
||||
import DetailSection from '~/components/pub/my-ui/form/view/detail-section.vue'
|
||||
import { formatAddress } from '~/models/person-address'
|
||||
|
||||
import {
|
||||
addressLocationTypeCode,
|
||||
educationCodes,
|
||||
genderCodes,
|
||||
occupationCodes,
|
||||
personContactTypes,
|
||||
relationshipCodes,
|
||||
religionCodes,
|
||||
} from '~/lib/constants'
|
||||
import { cn, mapToComboboxOptList } from '~/lib/utils'
|
||||
import { cn, } from '~/lib/utils'
|
||||
import type { ControlLetter } from '~/models/control-letter'
|
||||
|
||||
// #region Props & Emits
|
||||
const props = defineProps<{
|
||||
patient: Patient
|
||||
instance: ControlLetter | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -27,39 +15,9 @@ const emit = defineEmits<{
|
||||
// #endregion
|
||||
|
||||
// #region State & Computed
|
||||
const genderOptions = mapToComboboxOptList(genderCodes)
|
||||
const religionOptions = mapToComboboxOptList(religionCodes)
|
||||
const educationOptions = mapToComboboxOptList(educationCodes)
|
||||
const occupationOptions = mapToComboboxOptList(occupationCodes)
|
||||
const relationshipOptions = mapToComboboxOptList(relationshipCodes)
|
||||
const personContactTypeOptions = mapToComboboxOptList(personContactTypes)
|
||||
// #endregion
|
||||
|
||||
// Computed addresses from nested data
|
||||
const domicileAddress = computed(() => {
|
||||
const addresses = props.patient.person.addresses
|
||||
const resident = addresses?.find((addr) => addr.locationType_code === 'domicile')
|
||||
return formatAddress(resident)
|
||||
})
|
||||
|
||||
const identityAddress = computed(() => {
|
||||
const addresses = props.patient.person.addresses
|
||||
const primary = addresses?.find((addr) => addr.locationType_code === 'identity')
|
||||
return formatAddress(primary)
|
||||
})
|
||||
|
||||
const patientAge = computed(() => {
|
||||
if (!props.patient.person.birthDate) {
|
||||
return '-'
|
||||
}
|
||||
const birthDate = new Date(props.patient.person.birthDate)
|
||||
const today = new Date()
|
||||
let age = today.getFullYear() - birthDate.getFullYear()
|
||||
const monthDiff = today.getMonth() - birthDate.getMonth()
|
||||
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
|
||||
age--
|
||||
}
|
||||
return age
|
||||
})
|
||||
// #endregion
|
||||
|
||||
// #region Lifecycle Hooks
|
||||
@@ -81,10 +39,12 @@ function onClick(type: string) {
|
||||
|
||||
<template>
|
||||
<div :class="cn('min-h-[50vh] space-y-2',)">
|
||||
<DetailRow label="Tgl Rencana Kontrol">{{ patient.number || '-' }}</DetailRow>
|
||||
<DetailRow label="Spesialis/Sub Spesialis">{{ patient.number || '-' }}</DetailRow>
|
||||
<DetailRow label="DPJP">{{ patient.number || '-' }}</DetailRow>
|
||||
<DetailRow label="Status SEP">{{ patient.number || '-' }}</DetailRow>
|
||||
<DetailRow label="Tgl Rencana Kontrol">{{ props.instance?.date ? new Date(props.instance?.date).toLocaleDateString('id-ID') : '-' }}</DetailRow>
|
||||
<DetailRow label="Unit">{{ props.instance?.unit.name || '-' }}</DetailRow>
|
||||
<DetailRow label="Spesialis">{{ props.instance?.specialist.name || '-' }}</DetailRow>
|
||||
<DetailRow label="Sub Spesialis">{{ props.instance?.subspecialist.name || '-' }}</DetailRow>
|
||||
<DetailRow label="DPJP">{{ props.instance?.doctor.employee.person.name || '-' }}</DetailRow>
|
||||
<DetailRow label="Status SEP">{{ 'SEP INTERNAL' }}</DetailRow>
|
||||
</div>
|
||||
<div class="border-t-1 my-2 flex justify-end border-t-slate-300 py-2">
|
||||
<PubMyUiNavFooterBaEd @click="onClick" />
|
||||
|
||||
Reference in New Issue
Block a user