feat(sep): implement table history
This commit is contained in:
No files matched your search
@@ -75,6 +75,10 @@ if (Object.keys(patient).length > 0) {
|
|||||||
const onSubmit = handleSubmit((values) => {
|
const onSubmit = handleSubmit((values) => {
|
||||||
console.log('✅ Validated form values:', values)
|
console.log('✅ Validated form values:', values)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(patient, () => {
|
||||||
|
console.log('patient changed:', patient)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -141,7 +145,6 @@ const onSubmit = handleSubmit((values) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Block
|
<Block
|
||||||
v-if="!isLoading"
|
|
||||||
labelSize="thin"
|
labelSize="thin"
|
||||||
class="!pt-0"
|
class="!pt-0"
|
||||||
:colCount="3"
|
:colCount="3"
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import type { Config } from '~/components/pub/my-ui/data-table'
|
||||||
|
|
||||||
|
export interface SepHistoryData {
|
||||||
|
sepNumber: string
|
||||||
|
sepDate: string
|
||||||
|
referralNumber: string
|
||||||
|
diagnosis: string
|
||||||
|
serviceType: string
|
||||||
|
careClass: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const config: Config = {
|
||||||
|
cols: [{ width: 100 }, { width: 100 }, { width: 100 }, { width: 100 }, { width: 100 }, { width: 100 }],
|
||||||
|
|
||||||
|
headers: [
|
||||||
|
[
|
||||||
|
{ label: 'NO. SEP' },
|
||||||
|
{ label: 'TGL. SEP' },
|
||||||
|
{ label: 'NO. RUJUKAN' },
|
||||||
|
{ label: 'DIAGNOSIS AWAL' },
|
||||||
|
{ label: 'JENIS PELAYANAN' },
|
||||||
|
{ label: 'KELAS RAWAT' },
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
keys: ['sepNumber', 'sepDate', 'referralNumber', 'diagnosis', 'serviceType', 'careClass'],
|
||||||
|
|
||||||
|
delKeyNames: [{ key: 'code', label: 'Kode' }],
|
||||||
|
|
||||||
|
parses: {},
|
||||||
|
|
||||||
|
components: {},
|
||||||
|
|
||||||
|
htmls: {},
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
// Components
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
|
DialogFooter,
|
||||||
|
} from '~/components/pub/ui/dialog'
|
||||||
|
import ListHistory from './list-history.vue'
|
||||||
|
|
||||||
|
// Types
|
||||||
|
import type { SepHistoryData } from './list-cfg.history'
|
||||||
|
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
open: boolean
|
||||||
|
histories: Array<SepHistoryData>
|
||||||
|
paginationMeta?: PaginationMeta
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'update:open', value: boolean): void
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Dialog
|
||||||
|
:open="props.open"
|
||||||
|
@update:open="emit('update:open', $event)"
|
||||||
|
>
|
||||||
|
<DialogTrigger as-child></DialogTrigger>
|
||||||
|
<DialogContent class="max-w-[50%]">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>History SEP</DialogTitle>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
<div class="overflow-x-auto rounded-lg border">
|
||||||
|
<ListHistory :data="histories" :pagination-meta="paginationMeta" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<DialogFooter></DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
// Components
|
||||||
|
import PaginationView from '~/components/pub/my-ui/pagination/pagination-view.vue'
|
||||||
|
|
||||||
|
// Types
|
||||||
|
import type { SepHistoryData } from './list-cfg.history'
|
||||||
|
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
|
||||||
|
|
||||||
|
// Configs
|
||||||
|
import { config } from './list-cfg.history'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
data: SepHistoryData[]
|
||||||
|
paginationMeta?: PaginationMeta
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
pageChange: [page: number]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
function handlePageChange(page: number) {
|
||||||
|
emit('pageChange', page)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PubMyUiDataTable
|
||||||
|
v-bind="config"
|
||||||
|
:rows="props.data"
|
||||||
|
/>
|
||||||
|
<PaginationView
|
||||||
|
v-if="paginationMeta"
|
||||||
|
:pagination-meta="paginationMeta"
|
||||||
|
@page-change="handlePageChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { ref } from 'vue'
|
|
||||||
import {
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogHeader,
|
|
||||||
DialogTitle,
|
|
||||||
DialogTrigger,
|
|
||||||
DialogFooter,
|
|
||||||
} from '~/components/pub/ui/dialog'
|
|
||||||
import { Input } from '~/components/pub/ui/input'
|
|
||||||
|
|
||||||
const props = defineProps<{
|
|
||||||
open: boolean
|
|
||||||
histories: Array<{
|
|
||||||
no_sep: string
|
|
||||||
tgl_sep: string
|
|
||||||
no_rujukan: string
|
|
||||||
diagnosis: string
|
|
||||||
pelayanan: string
|
|
||||||
kelas: string
|
|
||||||
}>
|
|
||||||
}>()
|
|
||||||
|
|
||||||
// {
|
|
||||||
// "diagnosa": "string",
|
|
||||||
// "jnsPelayanan": "string",
|
|
||||||
// "kelasRawat": "string",
|
|
||||||
// "namaPeserta": "string",
|
|
||||||
// "noKartu": "string",
|
|
||||||
// "noSep": "string",
|
|
||||||
// "noRujukan": "string",
|
|
||||||
// "poli": "string",
|
|
||||||
// "ppkPelayanan": "string",
|
|
||||||
// "tglPlgSep": "2025-10-20",
|
|
||||||
// "tglSep": "2025-10-20"
|
|
||||||
// }
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
|
||||||
(e: 'update:open', value: boolean): void
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const search = ref('')
|
|
||||||
|
|
||||||
const filteredHistories = computed(() => {
|
|
||||||
const histories = props.histories || []
|
|
||||||
return histories.filter((p) => p.no_sep.includes(search.value))
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<Dialog :open="props.open" @update:open="emit('update:open', $event)">
|
|
||||||
<DialogTrigger as-child></DialogTrigger>
|
|
||||||
<DialogContent class="max-w-[50%]">
|
|
||||||
<DialogHeader>
|
|
||||||
<DialogTitle>History SEP</DialogTitle>
|
|
||||||
</DialogHeader>
|
|
||||||
|
|
||||||
<!-- Input Search -->
|
|
||||||
<div class="mb-2 max-w-[50%]">
|
|
||||||
<Input v-model="search" placeholder="Cari berdasarkan No. SEP" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Table -->
|
|
||||||
<div class="overflow-x-auto rounded-lg border">
|
|
||||||
<table class="w-full text-sm">
|
|
||||||
<thead class="bg-gray-100">
|
|
||||||
<tr class="text-left">
|
|
||||||
<th class="p-2">NO. SEP</th>
|
|
||||||
<th class="p-2">TGL. SEP</th>
|
|
||||||
<th class="p-2">NO. RUJUKAN</th>
|
|
||||||
<th class="p-2">DIAGNOSIS AWAL</th>
|
|
||||||
<th class="p-2">JENIS PELAYANAN</th>
|
|
||||||
<th class="p-2">KELAS RAWAT</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody class="font-normal">
|
|
||||||
<tr v-for="p in filteredHistories" :key="p.no_sep" class="border-t hover:bg-gray-50">
|
|
||||||
<td class="p-2">{{ p.no_sep }}</td>
|
|
||||||
<td class="p-2">{{ p.tgl_sep }}</td>
|
|
||||||
<td class="p-2">{{ p.no_rujukan }}</td>
|
|
||||||
<td class="p-2">{{ p.diagnosis }}</td>
|
|
||||||
<td class="p-2">{{ p.pelayanan }}</td>
|
|
||||||
<td class="p-2">{{ p.kelas }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Footer -->
|
|
||||||
<DialogFooter>
|
|
||||||
</DialogFooter>
|
|
||||||
</DialogContent>
|
|
||||||
</Dialog>
|
|
||||||
</template>
|
|
||||||
@@ -1,9 +1,13 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
|
|
||||||
|
// Components
|
||||||
|
import AppListHistoryDialog from '~/components/app/sep/list-history-dialog.vue'
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
|
import type { PaginationMeta } from '~/components/pub/my-ui/pagination/pagination.type'
|
||||||
import type { PatientEntity } from '~/models/patient'
|
import type { PatientEntity } from '~/models/patient'
|
||||||
|
import type { SepHistoryData } from '~/components/app/sep/list-cfg.history'
|
||||||
|
|
||||||
// Services
|
// Services
|
||||||
import { getPatientDetail, getPatients } from '~/services/patient.service'
|
import { getPatientDetail, getPatients } from '~/services/patient.service'
|
||||||
@@ -14,6 +18,7 @@ import { getList as getDoctorList } from '~/services/vclaim-doctor.service'
|
|||||||
import { getList as getDiagnoseReferralList } from '~/services/vclaim-diagnose-referral.service'
|
import { getList as getDiagnoseReferralList } from '~/services/vclaim-diagnose-referral.service'
|
||||||
import { getList as geMonitoringVisitList } from '~/services/vclaim-monitoring-visit.service'
|
import { getList as geMonitoringVisitList } from '~/services/vclaim-monitoring-visit.service'
|
||||||
import { getList as getMonitoringHistoryList } from '~/services/vclaim-monitoring-history.service'
|
import { getList as getMonitoringHistoryList } from '~/services/vclaim-monitoring-history.service'
|
||||||
|
import { get } from '@vueuse/core'
|
||||||
|
|
||||||
const openPatient = ref(false)
|
const openPatient = ref(false)
|
||||||
const openLetter = ref(false)
|
const openLetter = ref(false)
|
||||||
@@ -21,6 +26,7 @@ const openHistory = ref(false)
|
|||||||
const selectedPatient = ref('')
|
const selectedPatient = ref('')
|
||||||
const selectedPatientObject = ref<PatientEntity | null>(null)
|
const selectedPatientObject = ref<PatientEntity | null>(null)
|
||||||
const selectedLetter = ref('SK22334442')
|
const selectedLetter = ref('SK22334442')
|
||||||
|
const histories = ref<Array<SepHistoryData>>([])
|
||||||
|
|
||||||
// patients used by AppSepTableSearchPatient (will be filled from API)
|
// patients used by AppSepTableSearchPatient (will be filled from API)
|
||||||
const patients = ref<Array<{ id: string; identity: string; number: string; bpjs: string; name: string }>>([])
|
const patients = ref<Array<{ id: string; identity: string; number: string; bpjs: string; name: string }>>([])
|
||||||
@@ -60,7 +66,7 @@ function mapPaginationMetaToRow(meta: any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchPatients(params: any = { 'page-size': 10 }) {
|
async function getPatientsList(params: any = { 'page-size': 10 }) {
|
||||||
try {
|
try {
|
||||||
isPatientsLoading.value = true
|
isPatientsLoading.value = true
|
||||||
patients.value = []
|
patients.value = []
|
||||||
@@ -81,6 +87,40 @@ async function fetchPatients(params: any = { 'page-size': 10 }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getPatientCurrent(id: string) {
|
||||||
|
isPatientsLoading.value = true
|
||||||
|
selectedPatientObject.value = null
|
||||||
|
try {
|
||||||
|
const result = await getPatientDetail(Number(id))
|
||||||
|
if (result && result.success && result.body && result.body.data) {
|
||||||
|
const patient = result.body.data || null
|
||||||
|
selectedPatientObject.value = patient
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to fetch patient:', err)
|
||||||
|
}
|
||||||
|
isPatientsLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getMonitoringHistoryMappers() {
|
||||||
|
histories.value = []
|
||||||
|
const result = await getMonitoringHistoryList({ nop: '0002078925513', tglawal: '2025-07-20', tglakhir: '2025-10-10' })
|
||||||
|
if (result && result.success && result.body) {
|
||||||
|
const historiesRaw = result.body?.response?.histori || []
|
||||||
|
if (!historiesRaw) return
|
||||||
|
historiesRaw.forEach((result: any) => {
|
||||||
|
histories.value.push({
|
||||||
|
sepNumber: result.noSep,
|
||||||
|
sepDate: result.tglSep,
|
||||||
|
referralNumber: result.noRujukan,
|
||||||
|
diagnosis: result.diagnosa,
|
||||||
|
serviceType: !result.jnsPelayanan ? '-' : result.jnsPelayanan === '1' ? 'Rawat Jalan' : 'Rawat Inap',
|
||||||
|
careClass: result.kelasRawat,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const letters = [
|
const letters = [
|
||||||
{
|
{
|
||||||
noSurat: 'SK22334442',
|
noSurat: 'SK22334442',
|
||||||
@@ -102,40 +142,8 @@ const letters = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const histories = [
|
|
||||||
{
|
|
||||||
no_sep: 'SP23311224',
|
|
||||||
tgl_sep: '12 Agustus 2025',
|
|
||||||
no_rujukan: '123444',
|
|
||||||
diagnosis: 'C34.9 – Karsinoma Paru',
|
|
||||||
pelayanan: 'Rawat Jalan',
|
|
||||||
kelas: 'Kelas II',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
no_sep: 'SP23455667',
|
|
||||||
tgl_sep: '11 Agustus 2025',
|
|
||||||
no_rujukan: '2331221',
|
|
||||||
diagnosis: 'K35 – Apendisitis akut',
|
|
||||||
pelayanan: 'Rawat Jalan',
|
|
||||||
kelas: 'Kelas II',
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
function handleSavePatient() {
|
function handleSavePatient() {
|
||||||
const getPatient = async () => {
|
getPatientCurrent(selectedPatient.value)
|
||||||
isPatientsLoading.value = true
|
|
||||||
try {
|
|
||||||
const result = await getPatientDetail(Number(selectedPatient.value))
|
|
||||||
if (result && result.success && result.body && result.body.data) {
|
|
||||||
const patient = result.body.data || null
|
|
||||||
selectedPatientObject.value = patient
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Failed to fetch patient:', err)
|
|
||||||
}
|
|
||||||
isPatientsLoading.value = false
|
|
||||||
}
|
|
||||||
getPatient()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSaveLetter() {
|
function handleSaveLetter() {
|
||||||
@@ -145,7 +153,7 @@ function handleSaveLetter() {
|
|||||||
function handleEvent(value: string) {
|
function handleEvent(value: string) {
|
||||||
if (value === 'search-patient') {
|
if (value === 'search-patient') {
|
||||||
// fetch patients from API then open the dialog
|
// fetch patients from API then open the dialog
|
||||||
fetchPatients({ 'page-size': 10, includes: 'person' }).then(() => {
|
getPatientsList({ 'page-size': 10, includes: 'person' }).then(() => {
|
||||||
openPatient.value = true
|
openPatient.value = true
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@@ -155,6 +163,10 @@ function handleEvent(value: string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (value === 'history-sep') {
|
if (value === 'history-sep') {
|
||||||
|
// fetch history sep from API then open the dialog
|
||||||
|
getMonitoringHistoryMappers().then((value) => {
|
||||||
|
console.log('value:', value)
|
||||||
|
})
|
||||||
openHistory.value = true
|
openHistory.value = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -173,7 +185,11 @@ onMounted(() => {
|
|||||||
getDistrictList({ city: '0187' }).then((value) => {
|
getDistrictList({ city: '0187' }).then((value) => {
|
||||||
console.log('value:', value)
|
console.log('value:', value)
|
||||||
})
|
})
|
||||||
getDoctorList({ 'jenis-pelayanan': 1, 'tgl-pelayanan': new Date().toISOString().substring(0, 19), 'kode-spesialis': 0 }).then((value) => {
|
getDoctorList({
|
||||||
|
'jenis-pelayanan': 1,
|
||||||
|
'tgl-pelayanan': new Date().toISOString().substring(0, 19),
|
||||||
|
'kode-spesialis': 0,
|
||||||
|
}).then((value) => {
|
||||||
console.log('value:', value)
|
console.log('value:', value)
|
||||||
})
|
})
|
||||||
getDiagnoseReferralList().then((value) => {
|
getDiagnoseReferralList().then((value) => {
|
||||||
@@ -198,7 +214,6 @@ onMounted(() => {
|
|||||||
SEP
|
SEP
|
||||||
</div>
|
</div>
|
||||||
<AppSepEntryForm
|
<AppSepEntryForm
|
||||||
:is-loading="isPatientsLoading"
|
|
||||||
:patient="selectedPatientObject"
|
:patient="selectedPatientObject"
|
||||||
@event="handleEvent"
|
@event="handleEvent"
|
||||||
/>
|
/>
|
||||||
@@ -207,7 +222,7 @@ onMounted(() => {
|
|||||||
v-model:selected="selectedPatient"
|
v-model:selected="selectedPatient"
|
||||||
:patients="patients"
|
:patients="patients"
|
||||||
:pagination-meta="paginationMeta"
|
:pagination-meta="paginationMeta"
|
||||||
@fetch="(value) => fetchPatients({ ...value, 'page-size': 10, includes: 'person' })"
|
@fetch="(value) => getPatientsList({ ...value, 'page-size': 10, includes: 'person' })"
|
||||||
@save="handleSavePatient"
|
@save="handleSavePatient"
|
||||||
/>
|
/>
|
||||||
<AppSepTableSearchLetter
|
<AppSepTableSearchLetter
|
||||||
@@ -216,7 +231,7 @@ onMounted(() => {
|
|||||||
:letters="letters"
|
:letters="letters"
|
||||||
@save="handleSaveLetter"
|
@save="handleSaveLetter"
|
||||||
/>
|
/>
|
||||||
<AppSepTableHistorySep
|
<AppListHistoryDialog
|
||||||
v-model:open="openHistory"
|
v-model:open="openHistory"
|
||||||
:histories="histories"
|
:histories="histories"
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user