feat(sep): implement debounced search for patient identifiers and enhance entry form functionality

This commit is contained in:
riefive
2025-11-06 14:45:24 +07:00
parent 48b8ee5d2c
commit 7eecdc67ec
2 changed files with 46 additions and 10 deletions

No files matched your search

+24 -3
View File
@@ -17,14 +17,16 @@ import { IntegrationBpjsSchema, type IntegrationBpjsFormData } from '~/schemas/i
import type { PatientEntity } from '~/models/patient' import type { PatientEntity } from '~/models/patient'
// Helpers // Helpers
import { watch } from 'vue'
import { toTypedSchema } from '@vee-validate/zod' import { toTypedSchema } from '@vee-validate/zod'
import { useForm } from 'vee-validate' import { useForm } from 'vee-validate'
import { is } from "date-fns/locale" import { refDebounced } from '@vueuse/core'
const props = defineProps<{ const props = defineProps<{
isLoading?: boolean isLoading?: boolean
isReadonly?: boolean isReadonly?: boolean
isService?: boolean isService?: boolean
isShowPatient?: boolean;
mode?: string mode?: string
doctors: any[] doctors: any[]
diagnoses: any[] diagnoses: any[]
@@ -105,8 +107,13 @@ const mode = props.mode !== undefined ? props.mode : 'add'
const isLoading = props.isLoading !== undefined ? props.isLoading : false const isLoading = props.isLoading !== undefined ? props.isLoading : false
const isReadonly = props.isReadonly !== undefined ? props.isReadonly : false const isReadonly = props.isReadonly !== undefined ? props.isReadonly : false
const isService = ref(props.isService || false) const isService = ref(props.isService || false)
const isShowPatient = ref(props.isShowPatient || false)
const isDateReload = ref(false) const isDateReload = ref(false)
// Debounced search for bpjsNumber and nationalId
const debouncedBpjsNumber = refDebounced(bpjsNumber, 500)
const debouncedNationalId = refDebounced(nationalId, 500)
if (mode === 'add') { if (mode === 'add') {
// Set default sepDate to current date in YYYY-MM-DD format // Set default sepDate to current date in YYYY-MM-DD format
const today = new Date() const today = new Date()
@@ -154,6 +161,19 @@ watch(props, (value) => {
} }
}) })
// Watch debounced search values
watch(debouncedBpjsNumber, (newValue) => {
if (newValue && newValue !== '-' && newValue.length >= 3) {
emit('event', 'search-patient-by-identifier', { text: newValue, type: 'bpjs' })
}
})
watch(debouncedNationalId, (newValue) => {
if (newValue && newValue !== '-' && newValue.length >= 3) {
emit('event', 'search-patient-by-identifier', { text: newValue, type: 'nationalId' })
}
})
onMounted(() => { onMounted(() => {
if (!isService.value) { if (!isService.value) {
serviceType.value = '2' serviceType.value = '2'
@@ -229,6 +249,7 @@ onMounted(() => {
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<h3 class="text-lg font-semibold">Data Pasien</h3> <h3 class="text-lg font-semibold">Data Pasien</h3>
<Button <Button
v-if="isShowPatient"
variant="outline" variant="outline"
type="button" type="button"
class="h-[40px] rounded-md border-orange-400 text-orange-400 hover:bg-green-50" class="h-[40px] rounded-md border-orange-400 text-orange-400 hover:bg-green-50"
@@ -258,7 +279,7 @@ onMounted(() => {
id="bpjsNumber" id="bpjsNumber"
v-model="bpjsNumber" v-model="bpjsNumber"
v-bind="bpjsNumberAttrs" v-bind="bpjsNumberAttrs"
:disabled="true" :disabled="false"
/> />
</Field> </Field>
</Cell> </Cell>
@@ -273,7 +294,7 @@ onMounted(() => {
id="nationalId" id="nationalId"
v-model="nationalId" v-model="nationalId"
v-bind="nationalIdAttrs" v-bind="nationalIdAttrs"
:disabled="true" :disabled="false"
/> />
</Field> </Field>
</Cell> </Cell>
+22 -7
View File
@@ -80,6 +80,7 @@ const isServiceHidden = ref(false)
const isSaveLoading = ref(false) const isSaveLoading = ref(false)
const isLetterReadonly = ref(false) const isLetterReadonly = ref(false)
const resourceType = ref('') const resourceType = ref('')
const resourcePath = ref('')
async function getMonitoringHistoryMappers() { async function getMonitoringHistoryMappers() {
histories.value = [] histories.value = []
@@ -243,6 +244,14 @@ async function handleEvent(menu: string, value: any) {
}) })
return return
} }
if (menu === 'search-patient-by-identifier') {
const text = value.text
const type = value.type
if (type === 'nationalId') {
getPatientByIdentifierSearch(text)
}
return
}
if (menu === 'search-letter') { if (menu === 'search-letter') {
isLetterReadonly.value = false isLetterReadonly.value = false
getLetterMappers(value.admissionType, value.search).then(() => { getLetterMappers(value.admissionType, value.search).then(() => {
@@ -285,7 +294,7 @@ async function handleEvent(menu: string, value: any) {
} }
toast({ title: 'Berhasil', description: 'SEP berhasil dibuat', variant: 'default' }) toast({ title: 'Berhasil', description: 'SEP berhasil dibuat', variant: 'default' })
if (resourceType.value === 'encounter') { if (resourceType.value === 'encounter') {
navigateTo('/rehab/encounter/add') navigateTo(resourcePath.value)
return return
} }
navigateTo('/integration/bpjs/sep') navigateTo('/integration/bpjs/sep')
@@ -387,20 +396,25 @@ async function handleInit() {
const queries = route.query as any const queries = route.query as any
isServiceHidden.value = queries['is-service'] === 'true' isServiceHidden.value = queries['is-service'] === 'true'
selectedObjects.value = {} selectedObjects.value = {}
if (queries['doctor-code']) selectedObjects.value['doctorCode'] = queries['doctor-code']
if (queries['specialist-code']) selectedObjects.value['subSpecialistCode'] = queries['specialist-code']
if (queries['sub-specialist-code']) selectedObjects.value['subSpecialistCode'] = queries['sub-specialist-code']
if (queries['bpjs-number']) selectedObjects.value['bpjsNumber'] = queries['bpjs-number'] if (queries['bpjs-number']) selectedObjects.value['bpjsNumber'] = queries['bpjs-number']
if (queries['register-date']) selectedObjects.value['registerDate'] = queries['register-date'] if (queries['register-date']) selectedObjects.value['registerDate'] = queries['register-date']
if (queries['sep-type']) selectedObjects.value['sepType'] = queries['sep-type'] if (queries['sep-type']) selectedObjects.value['sepType'] = queries['sep-type']
if (queries['sep-number']) selectedObjects.value['sepNumber'] = queries['sep-number'] if (queries['sep-number']) selectedObjects.value['sepNumber'] = queries['sep-number']
if (queries['register-date']) selectedObjects.value['registerDate'] = queries['register-date'] if (queries['register-date']) selectedObjects.value['registerDate'] = queries['register-date']
if (queries['doctor-id']) selectedObjects.value['doctorId'] = queries['doctor-id']
if (queries['patient-name']) selectedObjects.value['patientName'] = queries['patient-name']
if (queries['national-identity']) selectedObjects.value['nationalIdentity'] = queries['national-identity']
if (queries['payment-type']) selectedObjects.value['paymentType'] = queries['payment-type'] if (queries['payment-type']) selectedObjects.value['paymentType'] = queries['payment-type']
if (queries['medical-record-number'])
selectedObjects.value['medicalRecordNumber'] = queries['medical-record-number']
if (queries['resource']) resourceType.value = queries['resource'] if (queries['resource']) resourceType.value = queries['resource']
delete selectedObjects.value['is-service'] if (queries['resource-path']) resourcePath.value = queries['resource-path']
// Load patient data if identifier is provided // Load patient data if identifier is provided
if (queries['patient-id']) {
try {
await getPatientCurrent(queries['patient-id'])
} catch (err) {
console.error('Failed to load patient from query params:', err)
}
}
if (queries['national-identity'] && queries['medical-record-number']) { if (queries['national-identity'] && queries['medical-record-number']) {
try { try {
await getPatientByIdentifierSearch(queries['national-identity']) await getPatientByIdentifierSearch(queries['national-identity'])
@@ -415,6 +429,7 @@ async function handleInit() {
console.error('Failed to load patient from query params:', err) console.error('Failed to load patient from query params:', err)
} }
} }
delete selectedObjects.value['is-service']
} }
} }