feat(specialist-position): implement crud operations for specialist positions
add handler, service, schema and update components for specialist position management update list configuration and form to handle specialist relations
This commit is contained in:
@@ -3,16 +3,17 @@
|
||||
import Dialog from '~/components/pub/my-ui/modal/dialog.vue'
|
||||
import Header from '~/components/pub/my-ui/nav-header/prep.vue'
|
||||
import RecordConfirmation from '~/components/pub/my-ui/confirmation/record-confirmation.vue'
|
||||
import AppSpecialistList from '~/components/app/specialist/list.vue'
|
||||
import AppSpecialistEntryForm from '~/components/app/specialist/entry-form.vue'
|
||||
import AppSpecialistPositionList from '~/components/app/specialist-position/list.vue'
|
||||
import AppSpecialistPositionEntryForm from '~/components/app/specialist-position/entry-form.vue'
|
||||
|
||||
// Helpers
|
||||
import { usePaginatedList } from '~/composables/usePaginatedList'
|
||||
import { toast } from '~/components/pub/ui/toast'
|
||||
import { config } from '~/components/app/specialist-position/list.cfg'
|
||||
|
||||
// Types
|
||||
import { ActionEvents, type HeaderPrep } from '~/components/pub/my-ui/data/types'
|
||||
import { SpecialistSchema, type SpecialistFormData } from '~/schemas/specialist.schema'
|
||||
import { type SpecialistPositionFormData, SpecialistPositionSchema } from '~/schemas/specialist-position.schema'
|
||||
|
||||
// Handlers
|
||||
import {
|
||||
@@ -28,13 +29,15 @@ import {
|
||||
handleActionEdit,
|
||||
handleActionRemove,
|
||||
handleCancelForm,
|
||||
} from '~/handlers/specialist.handler'
|
||||
} from '~/handlers/specialist-position.handler'
|
||||
|
||||
// Services
|
||||
import { getList, getDetail } from '~/services/specialist.service'
|
||||
import { getValueLabelList as getUnitList } from '~/services/unit.service'
|
||||
import { getList, getDetail } from '~/services/specialist-position.service'
|
||||
import { getValueLabelList as getValueLabelSpecialistList } from '~/services/specialist.service'
|
||||
import { getValueLabelList as getEmployeeLabelList } from '~/services/employee.service'
|
||||
|
||||
const units = ref<{ value: string | number; label: string }[]>([])
|
||||
const specialists = ref<{ value: string | number; label: string }[]>([])
|
||||
const employees = ref<{ value: string | number; label: string }[]>([])
|
||||
const title = ref('')
|
||||
|
||||
const {
|
||||
@@ -52,11 +55,11 @@ const {
|
||||
sort: 'createdAt:asc',
|
||||
'page-number': params['page-number'] || 0,
|
||||
'page-size': params['page-size'] || 10,
|
||||
includes: 'unit',
|
||||
includes: 'specialist,Employee.Person',
|
||||
})
|
||||
return { success: result.success || false, body: result.body || {} }
|
||||
},
|
||||
entityName: 'specialist',
|
||||
entityName: 'specialist-position',
|
||||
})
|
||||
|
||||
const headerPrep: HeaderPrep = {
|
||||
@@ -98,18 +101,17 @@ const getCurrentSpecialistDetail = async (id: number | string) => {
|
||||
isFormEntryDialogOpen.value = true
|
||||
}
|
||||
}
|
||||
|
||||
// Watch for row actions when recId or recAction changes
|
||||
watch([recId, recAction], () => {
|
||||
switch (recAction.value) {
|
||||
case ActionEvents.showDetail:
|
||||
getCurrentSpecialistDetail(recId.value)
|
||||
title.value = 'Detail Spesialis'
|
||||
title.value = 'Detail Spesialis Posisi'
|
||||
isReadonly.value = true
|
||||
break
|
||||
case ActionEvents.showEdit:
|
||||
getCurrentSpecialistDetail(recId.value)
|
||||
title.value = 'Edit Spesialis'
|
||||
title.value = 'Edit Spesialis Posisi'
|
||||
isReadonly.value = false
|
||||
break
|
||||
case ActionEvents.showConfirmDelete:
|
||||
@@ -119,8 +121,18 @@ watch([recId, recAction], () => {
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
units.value = await getUnitList()
|
||||
await getSpecialistList()
|
||||
try {
|
||||
specialists.value = await getValueLabelSpecialistList({ sort: 'createdAt:asc', 'page-size': 100 })
|
||||
employees.value = await getEmployeeLabelList({ sort: 'createdAt:asc', 'page-size': 100, includes: 'person' })
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
// show toast
|
||||
toast({
|
||||
title: 'Terjadi Kesalahan',
|
||||
description: 'Terjadi kesalahan saat memuat data',
|
||||
variant: 'destructive',
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -131,13 +143,11 @@ onMounted(async () => {
|
||||
:ref-search-nav="headerPrep.refSearchNav"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
|
||||
<AppSpecialistPositionList
|
||||
:data="data"
|
||||
:pagination-meta="paginationMeta"
|
||||
@page-change="handlePageChange"
|
||||
/>
|
||||
|
||||
<Dialog
|
||||
v-model:open="isFormEntryDialogOpen"
|
||||
:title="!!recItem ? title : 'Tambah Spesialis'"
|
||||
@@ -151,13 +161,14 @@ onMounted(async () => {
|
||||
"
|
||||
>
|
||||
<AppSpecialistPositionEntryForm
|
||||
:schema="SpecialistSchema"
|
||||
:units="units"
|
||||
:schema="SpecialistPositionSchema"
|
||||
:specialists="specialists"
|
||||
:employees="employees"
|
||||
:values="recItem"
|
||||
:is-loading="isProcessing"
|
||||
:is-readonly="isReadonly"
|
||||
@submit="
|
||||
(values: SpecialistFormData | Record<string, any>, resetForm: () => void) => {
|
||||
(values: SpecialistPositionFormData | Record<string, any>, resetForm: () => void) => {
|
||||
if (recId > 0) {
|
||||
handleActionEdit(recId, values, getSpecialistList, resetForm, toast)
|
||||
return
|
||||
@@ -168,7 +179,6 @@ onMounted(async () => {
|
||||
@cancel="handleCancelForm"
|
||||
/>
|
||||
</Dialog>
|
||||
|
||||
<!-- Record Confirmation Modal -->
|
||||
<RecordConfirmation
|
||||
v-model:open="isRecordConfirmationOpen"
|
||||
@@ -178,18 +188,14 @@ onMounted(async () => {
|
||||
@cancel=""
|
||||
>
|
||||
<template #default="{ record }">
|
||||
<div class="text-sm">
|
||||
<p>
|
||||
<strong>ID:</strong>
|
||||
{{ record?.id }}
|
||||
</p>
|
||||
<p v-if="record?.name">
|
||||
<strong>Nama:</strong>
|
||||
{{ record.name }}
|
||||
</p>
|
||||
<p v-if="record?.code">
|
||||
<strong>Kode:</strong>
|
||||
{{ record.code }}
|
||||
<div class="space-y-1 text-sm">
|
||||
<p
|
||||
v-for="field in config.delKeyNames"
|
||||
:key="field.key"
|
||||
:v-if="record?.[field.key]"
|
||||
>
|
||||
<span class="font-semibold">{{ field.label }}:</span>
|
||||
{{ record[field.key] }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user