Files
2025-12-01 01:51:04 +07:00

199 lines
5.4 KiB
Vue

<script setup lang="ts">
import Header from '~/components/pub/my-ui/nav-header/prep.vue'
import { usePaginatedList } from '~/composables/usePaginatedList'
import { toast } from '~/components/pub/ui/toast'
import RecordConfirmation from '~/components/pub/my-ui/confirmation/record-confirmation.vue'
import { ActionEvents, type HeaderPrep } from '~/components/pub/my-ui/data/types'
// Handlers
import type { ToastFn } from '~/handlers/_handler'
// Apps
import {
recId,
recAction,
recItem,
isReadonly,
isFormEntryDialogOpen,
isRecordConfirmationOpen,
handleActionSave,
handleActionRemove,
} from '~/handlers/mcu-order.handler'
import { getList, getDetail, submit } from '~/services/mcu-order.service'
import type { McuOrder } from '~/models/mcu-order'
// import List from '~/components/app/mcu-order/micro-list.vue'
import ConfirmationInfo from '~/components/app/mcu-order/confirmation-info.vue'
// Props
const props = defineProps<{
scopeCode: string
}>()
// Common preparations
const route = useRoute()
const { crudQueryParams } = useQueryCRUD()
const title = ref('')
const plainEid = route.params.id
const encounter_id = (plainEid && typeof plainEid == 'string') ? parseInt(plainEid) : 0 // here the
const isSubmitConfirmationOpen = ref(false)
// Data
const {
data,
isLoading,
paginationMeta,
searchInput,
fetchData: getMyList,
} = usePaginatedList<McuOrder>({
fetchFn: async ({ page, search }) => {
const result = await getList({
search,
page,
'scope-code': props.scopeCode,
'encounter-id': encounter_id,
includes: 'doctor,doctor-employee,doctor-employee-person,items,items-mcuSrc',
})
return { success: result.success || false, body: result.body || {} }
},
entityName: 'mcu-order'
})
// Header
const headerPrep: HeaderPrep = {
title: 'Order Lab Mikro',
icon: 'i-lucide-box',
refSearchNav: {
placeholder: 'Cari (min. 3 karakter)...',
minLength: 3,
debounceMs: 500,
showValidationFeedback: true,
onInput: (value: string) => {
searchInput.value = value
},
onClick: () => {},
onClear: () => {},
},
addNav: {
label: 'Tambah',
icon: 'i-lucide-plus',
onClick: async () => {
const saveResp = await handleActionSave({ encounter_id, scope_code: props.scopeCode }, () => {}, () =>{}, toast)
if (saveResp.success) {
crudQueryParams.value = { mode: 'entry', recordId: saveResp.body?.data?.id.toString() }
}
},
},
}
// List component
let List: Component
if(props.scopeCode == 'radiology') {
List = defineAsyncComponent(() => import('~/components/content/encounter/status.vue'))
} else if(props.scopeCode == 'cp-lab') {
List = defineAsyncComponent(() => import('~/components/content/encounter/status.vue'))
} else if (props.scopeCode == 'micro-lab') {
List = defineAsyncComponent(() => import('~/components/app/mcu-order/micro-list.vue'))
} else {
List = defineAsyncComponent(() => import('~/components/content/encounter/status.vue'))
}
// Reactivities
provide('rec_id', recId)
provide('rec_action', recAction)
provide('rec_item', recItem)
provide('table_data_loader', isLoading)
watch([recId, recAction], () => {
switch (recAction.value) {
case ActionEvents.showDetail:
getMyDetail(recId.value)
title.value = 'Detail Order Lab PK'
isReadonly.value = true
break
case ActionEvents.showEdit:
getMyDetail(recId.value)
title.value = 'Edit Order Lab PK'
isReadonly.value = false
break
case ActionEvents.showConfirmDelete:
isRecordConfirmationOpen.value = true
break
}
})
///// Functions
async function getMyDetail (id: number | string) {
const result = await getDetail(id)
if (result.success) {
const currentValue = result.body?.data || {}
recItem.value = currentValue
isFormEntryDialogOpen.value = true
}
}
function cancel(data: McuOrder) {
recId.value = data.id
recItem.value = data
isRecordConfirmationOpen.value = true
}
function edit(data: McuOrder) {
crudQueryParams.value = { mode: 'entry', recordId: data.id.toString() }
}
function confirmSubmit(data: McuOrder) {
recId.value = data.id
recItem.value = data
isSubmitConfirmationOpen.value = true
}
async function handleActionSubmit(id: number, refresh: () => void, toast: ToastFn) {
const result = await submit(id)
if (result.success) {
toast({ title: 'Berhasil', description: 'Resep telah di ajukan', variant: 'default' })
setTimeout(refresh, 300)
} else {
toast({ title: 'Gagal', description: 'Gagal menjalankan perintah', variant: 'destructive' })
}
}
</script>
<template>
<Header :prep="{ ...headerPrep }" />
<List
v-if="!isLoading.dataListLoading"
:data="data"
:pagination-meta="paginationMeta"
@cancel="cancel"
@edit="edit"
@submit="confirmSubmit"
/>
<RecordConfirmation
v-model:open="isRecordConfirmationOpen"
action="delete"
:record="recItem"
@confirm="() => handleActionRemove(recId, getMyList, toast)"
@cancel=""
>
<ConfirmationInfo :rec-item="recItem" />
</RecordConfirmation>
<RecordConfirmation
v-model:open="isSubmitConfirmationOpen"
action="delete"
customTitle="Ajukan Resep"
customMessage="Proses akan mengajukan resep ini untuk diproses lebih lanjut. Lanjutkan?"
customConfirmText="Ajukan"
:record="recItem"
@confirm="() => handleActionSubmit(recId, getMyList, toast)"
@cancel=""
>
<ConfirmationInfo :rec-item="recItem" />
</RecordConfirmation>
</template>