Files
onboard/resources/js/Pages/Statistic/Components/InfoModal/PatientListModal.vue

120 lines
3.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import {
NModal, NDataTable, NEmpty, NSpin
} from 'naive-ui'
import { computed, ref, watch, h } from 'vue'
import { MODAL_TYPES } from './config'
import { getColumns } from './columns' // фабрика колонок
const props = defineProps({
type: {
type: String,
required: true,
validator: (val) => Object.keys(MODAL_TYPES).includes(val),
},
startAt: { type: String, default: null },
endAt: { type: String, default: null },
// Дополнительные параметры фильтрации (например, отделение)
departmentId: { type: Number, default: null },
})
const open = defineModel('open')
const config = computed(() => MODAL_TYPES[props.type])
const loading = ref(true)
const patients = ref([])
const filteredDepartments = ref([])
// Получаем уникальные отделения для фильтра
const departmentOptions = computed(() => {
const depts = new Set()
patients.value.forEach(p => {
if (p.department_name) depts.add(p.department_name)
})
return Array.from(depts).map(d => ({ label: d, value: d }))
.sort((a, b) => a.label.localeCompare(b.label))
})
// Фильтр по отделениям
const filteredData = computed(() => {
if (!filteredDepartments.value.length) return patients.value
return patients.value.filter(p =>
filteredDepartments.value.includes(p.department_name)
)
})
// Динамические колонки получаем из фабрики
const columns = computed(() => {
const baseColumns = getColumns(props.type)
// Добавляем фильтр по отделению в колонку 'department_name' если она существует
return baseColumns.map(col => {
if (col.key === 'department_name') {
return {
...col,
filterMultiple: true,
filterOptions: departmentOptions.value,
filter: (value, row) => row.department_name?.includes(value) ?? false,
}
}
return col
})
})
const fetchData = () => {
loading.value = true
const params = {
startAt: props.startAt,
endAt: props.endAt,
departmentId: props.departmentId,
type: props.type
}
axios.get('/api/statistics/reports/patients', { params })
.then(res => {
patients.value = res.data ?? []
filteredDepartments.value = []
})
.finally(() => { loading.value = false })
}
watch(open, (val) => {
if (val) fetchData()
})
</script>
<template>
<NModal
v-model:show="open"
:title="config?.title"
preset="card"
:mask-closable="false"
:close-on-esc="false"
class="max-w-5xl h-[calc(100vh-220px)]"
>
<template v-if="loading">
<div class="flex items-center justify-center h-full"><NSpin /></div>
</template>
<template v-else-if="patients.length">
<NDataTable
:columns="columns"
:data="filteredData"
table-layout="fixed"
size="small"
max-height="calc(100vh - 350px)"
:row-key="row => row.id"
/>
</template>
<template v-else>
<div class="h-full flex items-center justify-center">
<NEmpty description="Нет данных" />
</div>
</template>
</NModal>
</template>
<style scoped>
:deep(.n-data-table-th),
:deep(.n-data-table-td) {
font-size: var(--n-font-size);
}
</style>