fix: add tree select subspecialist and filter doctor
This commit is contained in:
No files matched your search
@@ -9,10 +9,12 @@ import { Input } from '~/components/pub/ui/input'
|
||||
import Select from '~/components/pub/ui/select/Select.vue'
|
||||
import Combobox from '~/components/pub/my-ui/combobox/combobox.vue'
|
||||
import DatepickerSingle from '~/components/pub/my-ui/datepicker/datepicker-single.vue'
|
||||
import TreeSelect from '~/components/pub/my-ui/select-tree/tree-select.vue'
|
||||
|
||||
// Types
|
||||
import { IntegrationEncounterSchema, type IntegrationEncounterFormData } from '~/schemas/integration-encounter.schema'
|
||||
import type { PatientEntity } from '~/models/patient'
|
||||
import type { TreeItem } from '~/components/pub/my-ui/select-tree/type'
|
||||
|
||||
// Helpers
|
||||
import { toTypedSchema } from '@vee-validate/zod'
|
||||
@@ -23,6 +25,7 @@ const props = defineProps<{
|
||||
isReadonly?: boolean
|
||||
doctor?: any[]
|
||||
subSpecialist?: any[]
|
||||
specialists?: TreeItem[]
|
||||
payments: any[]
|
||||
participantGroups?: any[]
|
||||
seps: any[]
|
||||
@@ -60,18 +63,31 @@ const isReadonly = props.isReadonly !== undefined ? props.isReadonly : false
|
||||
const sepFileInput = ref<HTMLInputElement | null>(null)
|
||||
const sippFileInput = ref<HTMLInputElement | null>(null)
|
||||
|
||||
const doctorOpts = ref([
|
||||
{ label: 'Pilih', value: '' },
|
||||
{ label: 'Dr. A', value: '1' },
|
||||
])
|
||||
|
||||
const subSpecialistOpts = ref([
|
||||
{ label: 'Pilih', value: '' },
|
||||
{ label: 'Subspesialis A', value: '1' },
|
||||
])
|
||||
const doctorOpts = computed(() => {
|
||||
// Add default option
|
||||
const defaultOption = [{ label: 'Pilih', value: '' }]
|
||||
// Add doctors from props
|
||||
const doctors = props.doctor || []
|
||||
return [...defaultOption, ...doctors]
|
||||
})
|
||||
|
||||
const isJKNPayment = computed(() => paymentType.value === 'jkn')
|
||||
|
||||
async function onFetchChildren(parentId: string): Promise<void> {
|
||||
console.log('onFetchChildren', parentId)
|
||||
}
|
||||
|
||||
// Watch specialist/subspecialist selection to fetch doctors
|
||||
watch(subSpecialistId, async (newValue) => {
|
||||
if (newValue) {
|
||||
console.log('SubSpecialist changed:', newValue)
|
||||
// Reset doctor selection
|
||||
doctorId.value = ''
|
||||
// Emit fetch event to parent
|
||||
emit('fetch', { subSpecialistId: newValue })
|
||||
}
|
||||
})
|
||||
|
||||
// Sync props to form fields
|
||||
watch(props, (value) => {
|
||||
const patient = value.patient || ({} as PatientEntity)
|
||||
@@ -233,17 +249,17 @@ const onSubmit = handleSubmit((values) => {
|
||||
:cellFlex="false"
|
||||
>
|
||||
<Cell>
|
||||
<Label height="compact">Spesialis / Subspesialis</Label>
|
||||
<Label height="compact">
|
||||
Spesialis / Subspesialis
|
||||
<span class="text-red-500">*</span>
|
||||
</Label>
|
||||
<Field :errMessage="errors.subSpecialistId">
|
||||
<Combobox
|
||||
<TreeSelect
|
||||
id="subSpecialistId"
|
||||
v-model="subSpecialistId"
|
||||
v-bind="subSpecialistIdAttrs"
|
||||
:items="subSpecialistOpts"
|
||||
:is-disabled="isLoading || isReadonly"
|
||||
placeholder="Pilih Subspesialis"
|
||||
search-placeholder="Cari Subspesialis"
|
||||
empty-message="Subspesialis tidak ditemukan"
|
||||
:data="specialists || []"
|
||||
:on-fetch-children="onFetchChildren"
|
||||
/>
|
||||
</Field>
|
||||
</Cell>
|
||||
@@ -364,7 +380,14 @@ const onSubmit = handleSubmit((values) => {
|
||||
/>
|
||||
</Field>
|
||||
</Cell>
|
||||
</Block>
|
||||
|
||||
<Block
|
||||
labelSize="thin"
|
||||
class="!pt-0"
|
||||
:colCount="3"
|
||||
:cellFlex="false"
|
||||
>
|
||||
<Cell>
|
||||
<Label height="compact">
|
||||
No. SEP
|
||||
@@ -392,14 +415,7 @@ const onSubmit = handleSubmit((values) => {
|
||||
</div>
|
||||
</Field>
|
||||
</Cell>
|
||||
</Block>
|
||||
|
||||
<Block
|
||||
labelSize="thin"
|
||||
class="!pt-0"
|
||||
:colCount="3"
|
||||
:cellFlex="false"
|
||||
>
|
||||
<Cell>
|
||||
<Label height="compact">Dokumen SEP</Label>
|
||||
<Field>
|
||||
|
||||
@@ -5,10 +5,18 @@ import AppViewPatient from '~/components/app/patient/view-patient.vue'
|
||||
|
||||
// Types
|
||||
import type { DataTableLoader } from '~/components/pub/my-ui/data-table/type'
|
||||
import type { TreeItem } from '~/components/pub/my-ui/select-tree/type'
|
||||
|
||||
// Constants
|
||||
import { paymentTypes, sepRefTypeCodes, participantGroups } from '~/lib/constants.vclaim'
|
||||
|
||||
// Services
|
||||
import {
|
||||
getList as getSpecialistList,
|
||||
getValueTreeItems as getSpecialistTreeItems,
|
||||
} from '~/services/specialist.service'
|
||||
import { getValueLabelList as getDoctorValueLabelList } from '~/services/doctor.service'
|
||||
|
||||
// Handlers
|
||||
import {
|
||||
patients,
|
||||
@@ -32,6 +40,8 @@ const isLoading = reactive<DataTableLoader>({
|
||||
const paymentsList = ref<Array<{ value: string; label: string }>>([])
|
||||
const sepsList = ref<Array<{ value: string; label: string }>>([])
|
||||
const participantGroupsList = ref<Array<{ value: string; label: string }>>([])
|
||||
const specialistsTree = ref<TreeItem[]>([])
|
||||
const doctorsList = ref<Array<{ value: string; label: string }>>([])
|
||||
|
||||
function handleSavePatient() {
|
||||
selectedPatientObject.value = null
|
||||
@@ -71,6 +81,74 @@ function handleEvent(menu: string, value?: any) {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleFetchSpecialists() {
|
||||
try {
|
||||
const specialistsResult = await getSpecialistList({ 'page-size': 100, includes: 'subspecialists' })
|
||||
if (specialistsResult.success) {
|
||||
const specialists = specialistsResult.body?.data || []
|
||||
specialistsTree.value = getSpecialistTreeItems(specialists)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching specialist-subspecialist tree:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to check if a value exists in the specialistsTree
|
||||
* Returns true if it's a leaf node (subspecialist), false if parent node (specialist)
|
||||
*/
|
||||
function isSubspecialist(value: string, items: TreeItem[]): boolean {
|
||||
for (const item of items) {
|
||||
if (item.value === value) {
|
||||
// If this item has children, it's not selected, so skip
|
||||
// If this is the selected item, check if it has children in the tree
|
||||
return false // This means it's a specialist, not a subspecialist
|
||||
}
|
||||
if (item.children) {
|
||||
for (const child of item.children) {
|
||||
if (child.value === value) {
|
||||
// This is a subspecialist (leaf node)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
async function handleFetchDoctors(subSpecialistId: string) {
|
||||
try {
|
||||
// Check if the selected value is a subspecialist or specialist
|
||||
const isSub = isSubspecialist(subSpecialistId, specialistsTree.value)
|
||||
|
||||
// Build filter based on selection type
|
||||
const filterParams: any = { 'page-size': 100 }
|
||||
|
||||
if (isSub) {
|
||||
// If selected is subspecialist, filter by subspecialist-id
|
||||
filterParams['subspecialist-id'] = subSpecialistId
|
||||
} else {
|
||||
// If selected is specialist, filter by specialist-id
|
||||
filterParams['specialist-id'] = subSpecialistId
|
||||
}
|
||||
|
||||
console.log('Fetching doctors with filter:', filterParams)
|
||||
|
||||
const doctors = await getDoctorValueLabelList(filterParams)
|
||||
doctorsList.value = doctors
|
||||
console.log('Fetched doctors:', doctors)
|
||||
} catch (error) {
|
||||
console.error('Error fetching doctors:', error)
|
||||
doctorsList.value = []
|
||||
}
|
||||
}
|
||||
|
||||
function handleFetch(value?: any) {
|
||||
if (value?.subSpecialistId) {
|
||||
handleFetchDoctors(value.subSpecialistId)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleInit() {
|
||||
paymentsList.value = Object.keys(paymentTypes).map((item) => ({
|
||||
value: item.toString(),
|
||||
@@ -84,6 +162,8 @@ async function handleInit() {
|
||||
value: item.toString(),
|
||||
label: participantGroups[item],
|
||||
})) as any
|
||||
// Fetch tree data
|
||||
await handleFetchSpecialists()
|
||||
}
|
||||
|
||||
provide('table_data_loader', isLoading)
|
||||
@@ -107,8 +187,11 @@ onMounted(async () => {
|
||||
:payments="paymentsList"
|
||||
:seps="sepsList"
|
||||
:participant-groups="participantGroupsList"
|
||||
:specialists="specialistsTree"
|
||||
:doctor="doctorsList"
|
||||
:patient="selectedPatientObject"
|
||||
@event="handleEvent"
|
||||
@fetch="handleFetch"
|
||||
/>
|
||||
|
||||
<AppViewPatient
|
||||
|
||||
Reference in New Issue
Block a user