Files
onboard/resources/js/Pages/Report/Components/ReportSection.vue
2026-04-21 10:08:14 +09:00

277 lines
16 KiB
Vue

<script setup>
import {NButton, NCard, NFlex, NAlert, NCollapse, NCollapseItem, NTabPane, NTabs} from 'naive-ui'
import ReportSectionItem from "./ReportSectionItem.vue";
import {computed, ref, watch} from "vue";
import {useReportStore} from "../../../Stores/report.js";
import {storeToRefs} from "pinia";
import ReportSectionHeader from "./ReportSectionHeader.vue";
import ManualPatientModal from "./ManualPatientModal.vue";
import {useDebounceFn} from "@vueuse/core";
const props = defineProps({
mode: {
type: String,
default: 'fillable' // 'fillable', 'readonly'
}
})
const reportStore = useReportStore()
const {patientsData} = storeToRefs(reportStore)
const showPlanManualPatientModal = ref(false)
const showEmergencyManualPatientModal = ref(false)
const activeRootTab = ref('mis')
const activeMisOutcomeTab = ref('discharged')
const activeSpecialOutcomeTab = ref('discharged')
const handleItemDragged = (event) => {
// console.log('Начато перетаскивание:', event)
}
const handleCollapseItemDragEnter = (e, itemName) => {
// Проверяем, активно ли перетаскивание и наведение происходит на нужную секцию ("3")
if (reportStore.isDragActive && itemName === '3') {
// Открываем секцию, если она еще не открыта
if (!reportStore.openedCollapsible.includes(itemName)) {
// Добавляем имя в массив открытых, если используется массив
reportStore.openedCollapsible = [...reportStore.openedCollapsible, itemName];
}
}
}
// Обработка события drop
const handleItemDropped = (event) => {
const { item, fromStatus, toStatus } = event
console.log(event)
// Добавляем в целевую таблицу
if (toStatus && patientsData.value[toStatus]) {
// Проверяем, нет ли уже такого элемента
if (!patientsData.value[toStatus].some(i => i.id === item.id)) {
patientsData.value[toStatus].push(item)
}
}
}
const isFillableMode = computed(() => props.mode.toLowerCase() === 'fillable')
const isReadonlyMode = computed(() => props.mode.toLowerCase() === 'readonly')
const canEditReport = computed(() => Boolean(reportStore.reportInfo?.report?.isActiveSendButton))
const loadCounts = useDebounceFn(async () => {
await reportStore.loadAllStatusCounts()
}, 250)
watch(
() => [reportStore.reportInfo?.dates?.startAt, reportStore.reportInfo?.dates?.endAt, reportStore.reportInfo?.department?.department_id],
async () => {
await loadCounts()
},
{ immediate: true }
)
</script>
<template>
<NCard>
<NTabs v-model:value="activeRootTab" type="segment" animated>
<NTabPane name="mis" tab="МИС">
<NCollapse v-model:expanded-names="reportStore.openedCollapsible">
<NCollapseItem name="1">
<template #header>
<div class="flex w-full items-center justify-between gap-3 pr-4">
<ReportSectionHeader title="Планово" status="mis-plan" />
</div>
</template>
<ReportSectionItem status="mis-plan"
:enabled="activeRootTab === 'mis' && reportStore.openedCollapsible.includes('1')"
:accent-ids="reportStore.reportInfo?.department?.recipientIds"
is-draggable
@item-dragged="handleItemDragged"
/>
</NCollapseItem>
<NCollapseItem name="2">
<template #header>
<div class="flex w-full items-center justify-between gap-3 pr-4">
<ReportSectionHeader title="Экстренно" status="mis-emergency" />
</div>
</template>
<ReportSectionItem status="mis-emergency"
:enabled="activeRootTab === 'mis' && reportStore.openedCollapsible.includes('2')"
:accent-ids="reportStore.reportInfo?.department?.recipientIds"
is-draggable
@item-dragged="handleItemDragged"
/>
</NCollapseItem>
<NCollapseItem name="3" @dragenter="(e) => handleCollapseItemDragEnter(e, '3')">
<template #header>
<ReportSectionHeader title="Находятся на контроле" status="mis-observation" />
</template>
<NFlex :size="12">
<ReportSectionItem status="mis-observation"
:enabled="activeRootTab === 'mis' && reportStore.openedCollapsible.includes('3')"
id="observation-table"
@item-dragged="handleItemDragged"
@item-dropped="handleItemDropped"
is-removable
is-draggable-drop
/>
<NAlert v-if="isFillableMode" type="info" class="w-full">
Перетаскивайте строки из верхних таблиц, что бы добавить в наблюдение
</NAlert>
</NFlex>
</NCollapseItem>
<NCollapseItem name="4">
<template #header>
<ReportSectionHeader title="Находятся в реанимации" status="mis-reanimation" />
</template>
<ReportSectionItem status="mis-reanimation"
:enabled="activeRootTab === 'mis' && reportStore.openedCollapsible.includes('4')"
/>
</NCollapseItem>
<NCollapseItem name="5">
<template #header>
<ReportSectionHeader title="Выбывшие" status="mis-outcome" />
</template>
<NTabs v-model:value="activeMisOutcomeTab" type="segment" animated>
<NTabPane name="discharged">
<template #tab>
<ReportSectionHeader title="Выписанные" status="mis-outcome-discharged" />
</template>
<ReportSectionItem status="mis-outcome-discharged"
:enabled="activeRootTab === 'mis' && reportStore.openedCollapsible.includes('5') && activeMisOutcomeTab === 'discharged'"
@item-dragged="handleItemDragged"
@item-dropped="handleItemDropped"
/>
</NTabPane>
<NTabPane name="deceased">
<template #tab>
<ReportSectionHeader title="Умершие" status="mis-outcome-deceased" />
</template>
<ReportSectionItem status="mis-outcome-deceased"
:enabled="activeRootTab === 'mis' && reportStore.openedCollapsible.includes('5') && activeMisOutcomeTab === 'deceased'"
@item-dragged="handleItemDragged"
@item-dropped="handleItemDropped"
/>
</NTabPane>
<NTabPane name="transferred">
<template #tab>
<ReportSectionHeader title="Переведённые" status="mis-outcome-transferred" />
</template>
<ReportSectionItem status="mis-outcome-transferred"
:enabled="activeRootTab === 'mis' && reportStore.openedCollapsible.includes('5') && activeMisOutcomeTab === 'transferred'"
@item-dragged="handleItemDragged"
@item-dropped="handleItemDropped"
/>
</NTabPane>
</NTabs>
</NCollapseItem>
</NCollapse>
</NTabPane>
<NTabPane name="special" tab="Спец. контингент">
<NCollapse v-model:expanded-names="reportStore.openedCollapsible">
<NCollapseItem name="1">
<template #header>
<div class="flex w-full items-center justify-between gap-3 pr-4">
<ReportSectionHeader title="Планово" status="special-plan" />
<NButton v-if="isFillableMode && canEditReport" text type="primary" @click.stop="showPlanManualPatientModal = true">
Добавить
</NButton>
</div>
</template>
<ReportSectionItem status="special-plan"
:enabled="activeRootTab === 'special' && reportStore.openedCollapsible.includes('1')"
:accent-ids="reportStore.reportInfo?.department?.recipientIds"
is-draggable
@item-dragged="handleItemDragged"
/>
</NCollapseItem>
<NCollapseItem name="2">
<template #header>
<div class="flex w-full items-center justify-between gap-3 pr-4">
<ReportSectionHeader title="Экстренно" status="special-emergency" />
<NButton v-if="isFillableMode && canEditReport" text type="primary" @click.stop="showEmergencyManualPatientModal = true">
Добавить
</NButton>
</div>
</template>
<ReportSectionItem status="special-emergency"
:enabled="activeRootTab === 'special' && reportStore.openedCollapsible.includes('2')"
:accent-ids="reportStore.reportInfo?.department?.recipientIds"
is-draggable
@item-dragged="handleItemDragged"
/>
</NCollapseItem>
<NCollapseItem name="3" @dragenter="(e) => handleCollapseItemDragEnter(e, '3')">
<template #header>
<ReportSectionHeader title="Находятся на контроле" status="special-observation" />
</template>
<NFlex :size="12">
<ReportSectionItem status="special-observation"
:enabled="activeRootTab === 'special' && reportStore.openedCollapsible.includes('3')"
id="observation-table"
@item-dragged="handleItemDragged"
@item-dropped="handleItemDropped"
is-removable
is-draggable-drop
/>
<NAlert v-if="isFillableMode" type="info" class="w-full">
Перетаскивайте строки из верхних таблиц, что бы добавить в наблюдение
</NAlert>
</NFlex>
</NCollapseItem>
<NCollapseItem name="4">
<template #header>
<ReportSectionHeader title="Находятся в реанимации" status="special-reanimation" />
</template>
<ReportSectionItem status="special-reanimation"
:enabled="activeRootTab === 'special' && reportStore.openedCollapsible.includes('4')"
/>
</NCollapseItem>
<NCollapseItem name="5">
<template #header>
<ReportSectionHeader title="Выбывшие" status="special-outcome" />
</template>
<NTabs v-model:value="activeSpecialOutcomeTab" type="segment" animated>
<NTabPane name="discharged">
<template #tab>
<ReportSectionHeader title="Выписанные" status="special-outcome-discharged" />
</template>
<ReportSectionItem status="special-outcome-discharged"
:enabled="activeRootTab === 'special' && reportStore.openedCollapsible.includes('5') && activeSpecialOutcomeTab === 'discharged'"
@item-dragged="handleItemDragged"
@item-dropped="handleItemDropped"
/>
</NTabPane>
<NTabPane name="deceased">
<template #tab>
<ReportSectionHeader title="Умершие" status="special-outcome-deceased" />
</template>
<ReportSectionItem status="special-outcome-deceased"
:enabled="activeRootTab === 'special' && reportStore.openedCollapsible.includes('5') && activeSpecialOutcomeTab === 'deceased'"
@item-dragged="handleItemDragged"
@item-dropped="handleItemDropped"
/>
</NTabPane>
<NTabPane name="transferred">
<template #tab>
<ReportSectionHeader title="Переведённые" status="special-outcome-transferred" />
</template>
<ReportSectionItem status="special-outcome-transferred"
:enabled="activeRootTab === 'special' && reportStore.openedCollapsible.includes('5') && activeSpecialOutcomeTab === 'transferred'"
@item-dragged="handleItemDragged"
@item-dropped="handleItemDropped"
/>
</NTabPane>
</NTabs>
</NCollapseItem>
</NCollapse>
</NTabPane>
</NTabs>
<ManualPatientModal v-model:show="showPlanManualPatientModal" patient-kind="plan" />
<ManualPatientModal v-model:show="showEmergencyManualPatientModal" patient-kind="emergency" />
</NCard>
</template>
<style scoped>
</style>