init specialist feature
This commit is contained in:
No files matched your search
@@ -6,30 +6,20 @@ import Field from '~/components/pub/custom-ui/form/field.vue'
|
|||||||
import Label from '~/components/pub/custom-ui/form/label.vue'
|
import Label from '~/components/pub/custom-ui/form/label.vue'
|
||||||
import Select from '~/components/pub/custom-ui/form/select.vue'
|
import Select from '~/components/pub/custom-ui/form/select.vue'
|
||||||
|
|
||||||
interface InstallationFormData {
|
interface SpecialistFormData {
|
||||||
name: string
|
name: string
|
||||||
code: string
|
code: string
|
||||||
encounterClassCode: string
|
encounterClassCode: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
installation: {
|
|
||||||
msg: {
|
|
||||||
placeholder: string
|
|
||||||
}
|
|
||||||
items: {
|
|
||||||
value: string
|
|
||||||
label: string
|
|
||||||
code: string
|
|
||||||
}[]
|
|
||||||
}
|
|
||||||
schema: any
|
schema: any
|
||||||
initialValues?: Partial<InstallationFormData>
|
initialValues?: Partial<SpecialistFormData>
|
||||||
errors?: FormErrors
|
errors?: FormErrors
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
'submit': [values: InstallationFormData, resetForm: () => void]
|
'submit': [values: SpecialistFormData, resetForm: () => void]
|
||||||
'cancel': [resetForm: () => void]
|
'cancel': [resetForm: () => void]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
@@ -37,7 +27,7 @@ const formSchema = toTypedSchema(props.schema)
|
|||||||
|
|
||||||
// Form submission handler
|
// Form submission handler
|
||||||
function onSubmitForm(values: any, { resetForm }: { resetForm: () => void }) {
|
function onSubmitForm(values: any, { resetForm }: { resetForm: () => void }) {
|
||||||
const formData: InstallationFormData = {
|
const formData: SpecialistFormData = {
|
||||||
name: values.name || '',
|
name: values.name || '',
|
||||||
code: values.code || '',
|
code: values.code || '',
|
||||||
encounterClassCode: values.encounterClassCode || '',
|
encounterClassCode: values.encounterClassCode || '',
|
||||||
@@ -89,25 +79,6 @@ function onCancelForm({ resetForm }: { resetForm: () => void }) {
|
|||||||
</FormField>
|
</FormField>
|
||||||
</Field>
|
</Field>
|
||||||
</FieldGroup>
|
</FieldGroup>
|
||||||
|
|
||||||
<FieldGroup>
|
|
||||||
<Label label-for="parentId">Encounter Class</Label>
|
|
||||||
<Field id="encounterClassCode" :errors="errors">
|
|
||||||
<FormField v-slot="{ componentField }" name="encounterClassCode">
|
|
||||||
<FormItem>
|
|
||||||
<FormControl>
|
|
||||||
<Select
|
|
||||||
v-bind="componentField"
|
|
||||||
:items="installation.items"
|
|
||||||
:placeholder="installation.msg.placeholder"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</FormControl>
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
</FormField>
|
|
||||||
</Field>
|
|
||||||
</FieldGroup>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const action = defineAsyncComponent(() => import('~/components/pub/custom-ui/dat
|
|||||||
export const cols: Col[] = [{ width: 100 }, {}, {}, {}, { width: 50 }]
|
export const cols: Col[] = [{ width: 100 }, {}, {}, {}, { width: 50 }]
|
||||||
|
|
||||||
export const header: Th[][] = [
|
export const header: Th[][] = [
|
||||||
[{ label: 'Id' }, { label: 'Nama' }, { label: 'Kode' }, { label: 'Encounter Class' }, { label: '' }],
|
[{ label: 'Id' }, { label: 'Name' }, { label: 'Code' }, { label: 'Unit' }, { label: '' }],
|
||||||
]
|
]
|
||||||
|
|
||||||
export const keys = ['id', 'name', 'cellphone', 'religion_code', 'action']
|
export const keys = ['id', 'name', 'cellphone', 'religion_code', 'action']
|
||||||
@@ -30,21 +30,6 @@ export const funcParsed: RecStrFuncUnknown = {
|
|||||||
const recX = rec as SmallDetailDto
|
const recX = rec as SmallDetailDto
|
||||||
return `${recX.firstName} ${recX.lastName || ''}`.trim()
|
return `${recX.firstName} ${recX.lastName || ''}`.trim()
|
||||||
},
|
},
|
||||||
identity_number: (rec: unknown): unknown => {
|
|
||||||
const recX = rec as SmallDetailDto
|
|
||||||
if (recX.identity_number?.substring(0, 5) === 'BLANK') {
|
|
||||||
return '(TANPA NIK)'
|
|
||||||
}
|
|
||||||
return recX.identity_number
|
|
||||||
},
|
|
||||||
inPatient_itemPrice: (rec: unknown): unknown => {
|
|
||||||
const recX = rec as SmallDetailDto
|
|
||||||
return Number(recX.inPatient_itemPrice.price).toLocaleString('id-ID')
|
|
||||||
},
|
|
||||||
outPatient_itemPrice: (rec: unknown): unknown => {
|
|
||||||
const recX = rec as SmallDetailDto
|
|
||||||
return Number(recX.outPatient_itemPrice.price).toLocaleString('id-ID')
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const funcComponent: RecStrFuncComponent = {
|
export const funcComponent: RecStrFuncComponent = {
|
||||||
@@ -62,7 +47,4 @@ export const funcComponent: RecStrFuncComponent = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const funcHtml: RecStrFuncUnknown = {
|
export const funcHtml: RecStrFuncUnknown = {
|
||||||
patient_address(_rec) {
|
|
||||||
return '-'
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
@@ -1,37 +1,21 @@
|
|||||||
import * as z from 'zod'
|
import * as z from 'zod'
|
||||||
|
|
||||||
export const installationConf = {
|
|
||||||
msg: {
|
|
||||||
placeholder: '---pilih encounter class (fhir7)',
|
|
||||||
},
|
|
||||||
items: [
|
|
||||||
{ value: '1', label: 'Ambulatory', code: 'AMB' },
|
|
||||||
{ value: '2', label: 'Inpatient', code: 'IMP' },
|
|
||||||
{ value: '3', label: 'Emergency', code: 'EMER' },
|
|
||||||
{ value: '4', label: 'Observation', code: 'OBSENC' },
|
|
||||||
{ value: '5', label: 'Pre-admission', code: 'PRENC' },
|
|
||||||
{ value: '6', label: 'Short Stay', code: 'SS' },
|
|
||||||
{ value: '7', label: 'Virtual', code: 'VR' },
|
|
||||||
{ value: '8', label: 'Home Health', code: 'HH' },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
export const schemaConf = z.object({
|
export const schemaConf = z.object({
|
||||||
name: z
|
name: z
|
||||||
.string({
|
.string({
|
||||||
required_error: 'Nama instalasi harus diisi',
|
required_error: 'Nama spesialisasi harus diisi',
|
||||||
})
|
})
|
||||||
.min(3, 'Nama instalasi minimal 3 karakter'),
|
.min(3, 'Nama spesialisasi minimal 3 karakter'),
|
||||||
|
|
||||||
code: z
|
code: z
|
||||||
.string({
|
.string({
|
||||||
required_error: 'Kode instalasi harus diisi',
|
required_error: 'Kode spesialisasi harus diisi',
|
||||||
})
|
})
|
||||||
.min(3, 'Kode instalasi minimal 3 karakter'),
|
.min(3, 'Kode spesialisasi minimal 3 karakter'),
|
||||||
|
|
||||||
encounterClassCode: z
|
unitId: z
|
||||||
.string({
|
.string({
|
||||||
required_error: 'Kelompok encounter class harus dipilih',
|
required_error: 'Unit harus dipilih',
|
||||||
})
|
})
|
||||||
.min(1, 'Kelompok encounter class harus dipilih'),
|
.min(1, 'Unit harus dipilih'),
|
||||||
})
|
})
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { HeaderPrep } from '~/components/pub/custom-ui/data/types'
|
import type { HeaderPrep } from '~/components/pub/custom-ui/data/types'
|
||||||
import AppInstallationEntryForm from '~/components/app/installation/entry-form.vue'
|
import AppSpecialistEntryForm from '~/components/app/specialist/entry-form.vue'
|
||||||
import Dialog from '~/components/pub/base/modal/dialog.vue'
|
import Dialog from '~/components/pub/base/modal/dialog.vue'
|
||||||
import RecordConfirmation from '~/components/pub/custom-ui/confirmation/record-confirmation.vue'
|
import RecordConfirmation from '~/components/pub/custom-ui/confirmation/record-confirmation.vue'
|
||||||
import { ActionEvents } from '~/components/pub/custom-ui/data/types'
|
import { ActionEvents } from '~/components/pub/custom-ui/data/types'
|
||||||
import Header from '~/components/pub/custom-ui/nav-header/header.vue'
|
import Header from '~/components/pub/custom-ui/nav-header/header.vue'
|
||||||
import { usePaginatedList } from '~/composables/usePaginatedList'
|
import { usePaginatedList } from '~/composables/usePaginatedList'
|
||||||
import { installationConf, schemaConf } from './entry'
|
import { schemaConf } from './entry'
|
||||||
|
|
||||||
// #region State & Computed
|
// #region State & Computed
|
||||||
// Dialog state
|
// Dialog state
|
||||||
@@ -18,7 +18,7 @@ const recId = ref<number>(0)
|
|||||||
const recAction = ref<string>('')
|
const recAction = ref<string>('')
|
||||||
const recItem = ref<any>(null)
|
const recItem = ref<any>(null)
|
||||||
|
|
||||||
async function fetchInstallationData(params: any) {
|
async function fetchSpecialistData(params: any) {
|
||||||
const endpoint = transform('/api/v1/patient', params)
|
const endpoint = transform('/api/v1/patient', params)
|
||||||
return await xfetch(endpoint)
|
return await xfetch(endpoint)
|
||||||
}
|
}
|
||||||
@@ -31,14 +31,14 @@ const {
|
|||||||
searchInput,
|
searchInput,
|
||||||
handlePageChange,
|
handlePageChange,
|
||||||
handleSearch,
|
handleSearch,
|
||||||
fetchData: getInstallationList,
|
fetchData: getSpecialistList,
|
||||||
} = usePaginatedList({
|
} = usePaginatedList({
|
||||||
fetchFn: fetchInstallationData,
|
fetchFn: fetchSpecialistData,
|
||||||
entityName: 'installation',
|
entityName: 'specialist',
|
||||||
})
|
})
|
||||||
|
|
||||||
const headerPrep: HeaderPrep = {
|
const headerPrep: HeaderPrep = {
|
||||||
title: 'Instalasi',
|
title: 'Specialist',
|
||||||
icon: 'i-lucide-box',
|
icon: 'i-lucide-box',
|
||||||
refSearchNav: {
|
refSearchNav: {
|
||||||
placeholder: 'Cari (min. 3 karakter)...',
|
placeholder: 'Cari (min. 3 karakter)...',
|
||||||
@@ -56,7 +56,7 @@ const headerPrep: HeaderPrep = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
addNav: {
|
addNav: {
|
||||||
label: 'Tambah Instalasi',
|
label: 'Tambah Specialist',
|
||||||
icon: 'i-lucide-send',
|
icon: 'i-lucide-send',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
isFormEntryDialogOpen.value = true
|
isFormEntryDialogOpen.value = true
|
||||||
@@ -83,7 +83,7 @@ async function handleDeleteRow(record: any) {
|
|||||||
// })
|
// })
|
||||||
|
|
||||||
// Refresh data setelah berhasil delete
|
// Refresh data setelah berhasil delete
|
||||||
await getInstallationList()
|
await getSpecialistList()
|
||||||
|
|
||||||
// TODO: Show success message
|
// TODO: Show success message
|
||||||
console.log('Record deleted successfully')
|
console.log('Record deleted successfully')
|
||||||
@@ -126,7 +126,7 @@ async function onSubmitForm(values: any, resetForm: () => void) {
|
|||||||
isSuccess = true
|
isSuccess = true
|
||||||
|
|
||||||
// Refresh data after successful submission
|
// Refresh data after successful submission
|
||||||
await getInstallationList()
|
await getSpecialistList()
|
||||||
|
|
||||||
// TODO: Show success message
|
// TODO: Show success message
|
||||||
console.log('Installation created successfully')
|
console.log('Installation created successfully')
|
||||||
@@ -179,15 +179,13 @@ function handleCancelConfirmation() {
|
|||||||
<template>
|
<template>
|
||||||
<div class="rounded-md border p-4">
|
<div class="rounded-md border p-4">
|
||||||
<Header v-model="searchInput" :prep="headerPrep" @search="handleSearch" />
|
<Header v-model="searchInput" :prep="headerPrep" @search="handleSearch" />
|
||||||
<AppInstallationList :data="data" :pagination-meta="paginationMeta" @page-change="handlePageChange" />
|
<AppSpecialistList :data="data" :pagination-meta="paginationMeta" @page-change="handlePageChange" />
|
||||||
|
|
||||||
<Dialog v-model:open="isFormEntryDialogOpen" title="Tambah Instalasi" size="lg" prevent-outside>
|
<Dialog v-model:open="isFormEntryDialogOpen" :title="headerPrep.addNav?.label!" size="lg" prevent-outside>
|
||||||
<AppInstallationEntryForm :installation="installationConf" :schema="schemaConf"
|
<AppSpecialistEntryForm :schema="schemaConf" :initial-values="{ name: '', code: '', encounterClassCode: '' }"
|
||||||
:initial-values="{ name: '', code: '', encounterClassCode: '' }" @submit="onSubmitForm"
|
@submit="onSubmitForm" @cancel="onCancelForm" />
|
||||||
@cancel="onCancelForm" />
|
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
<!-- Record Confirmation Modal -->
|
|
||||||
<RecordConfirmation v-model:open="isRecordConfirmationOpen" action="delete" :record="recItem"
|
<RecordConfirmation v-model:open="isRecordConfirmationOpen" action="delete" :record="recItem"
|
||||||
@confirm="handleConfirmDelete" @cancel="handleCancelConfirmation">
|
@confirm="handleConfirmDelete" @cancel="handleCancelConfirmation">
|
||||||
<template #default="{ record }">
|
<template #default="{ record }">
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import Error from '~/components/pub/base/error/error.vue'
|
|||||||
definePageMeta({
|
definePageMeta({
|
||||||
// middleware: ['rbac'],
|
// middleware: ['rbac'],
|
||||||
roles: ['doctor', 'nurse', 'admisi', 'pharmacy', 'billing', 'management'],
|
roles: ['doctor', 'nurse', 'admisi', 'pharmacy', 'billing', 'management'],
|
||||||
title: 'List Unit',
|
title: 'List Specialist',
|
||||||
contentFrame: 'cf-full-width',
|
contentFrame: 'cf-full-width',
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ const canRead = true
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="canRead">
|
<div v-if="canRead">
|
||||||
<ContentUnitList />
|
<ContentSpecialistList />
|
||||||
</div>
|
</div>
|
||||||
<Error v-else :status-code="403" />
|
<Error v-else :status-code="403" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user