* восстановление окна наблюдения
* добавил получение выбывших * фильтрация выбывших по результатам лечения * добавил подсказку при наведении на операции * добавил вывод причины наблюдения * добавил вкладки для выбывших * изменил связь и сохранение пациентов на контроле * добавил возможность редактирования причины контроля * полное изменение окна с нежелательными событиями * исправил просмотр причины контроля * работа над окном редактирования причины контроля в таблице * визуальное выделение умерших и проведенных операций * добавил выбор даты для роли врач * центрирование блоков статистики * разделение выполненных операций на срочность * поправил метод определения текущего дня для роли врач * функция блокировки при выборе другой даты для роли врач
This commit is contained in:
56
resources/js/Pages/Report/Components/MoveModalComment.vue
Normal file
56
resources/js/Pages/Report/Components/MoveModalComment.vue
Normal file
@@ -0,0 +1,56 @@
|
||||
<script setup>
|
||||
import {NModal, NForm, NFormItem, NInput, NButton} from 'naive-ui'
|
||||
import {useReportStore} from "../../../Stores/report.js";
|
||||
import {ref, watch} from "vue";
|
||||
const show = defineModel('show')
|
||||
const props = defineProps({
|
||||
patientId: {
|
||||
type: Number,
|
||||
default: null
|
||||
}
|
||||
})
|
||||
const reportStore = useReportStore()
|
||||
const droppedPatient = ref(null)
|
||||
|
||||
const rules = {
|
||||
comment: {
|
||||
required: true,
|
||||
trigger: ['blur'],
|
||||
message: 'Введите описание причины'
|
||||
}
|
||||
}
|
||||
watch(() => props.patientId, (newPatientId) => {
|
||||
if (newPatientId) {
|
||||
const patientIndex = reportStore.patientsData.observation.findIndex(itm => itm.id === newPatientId)
|
||||
const patient = reportStore.patientsData.observation[patientIndex]
|
||||
droppedPatient.value = patient
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NModal v-model:show="show"
|
||||
title="Постановка на контроль"
|
||||
:mask-closable="false"
|
||||
:closable="false"
|
||||
class="max-w-lg"
|
||||
preset="card"
|
||||
>
|
||||
<NForm :model="droppedPatient" :rules="rules">
|
||||
<NFormItem label="Опишите причину" path="comment">
|
||||
<NInput type="textarea" :rows="6" :resizable="false" v-model:value="droppedPatient.comment" />
|
||||
</NFormItem>
|
||||
</NForm>
|
||||
<template #action>
|
||||
<div class="flex justify-end">
|
||||
<NButton type="primary" secondary @click="show = false">
|
||||
Сохранить
|
||||
</NButton>
|
||||
</div>
|
||||
</template>
|
||||
</NModal>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -5,6 +5,7 @@ import ReportFormInput from "./ReportFormInput.vue";
|
||||
import ReportSection from "./ReportSection.vue";
|
||||
import {useReportStore} from "../../../Stores/report.js";
|
||||
import {useAuthStore} from "../../../Stores/auth.js";
|
||||
import {computed} from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
mode: {
|
||||
@@ -21,17 +22,19 @@ const onSubmit = () => {
|
||||
departmentId: authStore.userDepartment.department_id
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NFlex vertical class="max-w-6xl mx-auto mt-6 mb-4 w-full">
|
||||
<ReportHeader :mode="mode" />
|
||||
|
||||
<ReportFormInput v-if="mode === 'fillable'" />
|
||||
<ReportFormInput />
|
||||
|
||||
<ReportSection label="Планово" />
|
||||
|
||||
<NButton secondary size="large" @click="onSubmit">
|
||||
<NButton v-if="reportStore.reportInfo?.report.isActiveSendButton" secondary size="large" @click="onSubmit">
|
||||
Сохранить отчет
|
||||
</NButton>
|
||||
</NFlex>
|
||||
|
||||
@@ -1,30 +1,69 @@
|
||||
<script setup>
|
||||
import {NCard, NSkeleton, NFlex, NFormItem, NForm, NInputNumber} from "naive-ui";
|
||||
import {NCard, NSkeleton, NSpace, NFlex, NFormItem, NForm, NInputNumber, NStatistic} from "naive-ui";
|
||||
import {useReportStore} from "../../../Stores/report.js";
|
||||
import {useAuthStore} from "../../../Stores/auth.js";
|
||||
|
||||
const reportStore = useReportStore()
|
||||
const authStore = useAuthStore()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NCard>
|
||||
<NForm>
|
||||
<NFlex>
|
||||
<div class="grid grid-cols-[1fr_auto] gap-x-3">
|
||||
<NCard v-if="reportStore.reportInfo?.report.isActiveSendButton">
|
||||
<NForm>
|
||||
<template v-if="reportStore.isLoadReportInfo">
|
||||
<NSkeleton class="w-[246px]! h-[60px]!" />
|
||||
<NSkeleton class="w-[246px]! h-[60px]!" />
|
||||
<NSkeleton class="w-[246px]! h-[60px]!" />
|
||||
<NFlex>
|
||||
<NSkeleton class="rounded-md w-[246px]! h-[65px]!" />
|
||||
<NSkeleton class="rounded-md w-[246px]! h-[65px]!" />
|
||||
<NSkeleton class="rounded-md w-[246px]! h-[65px]!" />
|
||||
</NFlex>
|
||||
</template>
|
||||
<template v-for="metrikaItem in reportStore.reportInfo?.metrikaItems">
|
||||
<NFormItem :label="metrikaItem.name" :show-feedback="false">
|
||||
<NInputNumber v-model:value="reportStore.reportForm[`metrika_item_${metrikaItem.metrika_item_id}`]"
|
||||
:default-value="metrikaItem.default_value" />
|
||||
</NFormItem>
|
||||
</template>
|
||||
</NFlex>
|
||||
</NForm>
|
||||
</NCard>
|
||||
<NFlex v-else justify="space-between" align="center">
|
||||
<NSpace>
|
||||
<template v-for="metrikaItem in reportStore.reportInfo?.metrikaItems">
|
||||
<NFormItem :label="metrikaItem.name" :show-feedback="false">
|
||||
<NInputNumber v-model:value="reportStore.reportForm[`metrika_item_${metrikaItem.metrika_item_id}`]"
|
||||
:default-value="metrikaItem.default_value" />
|
||||
</NFormItem>
|
||||
</template>
|
||||
</NSpace>
|
||||
</NFlex>
|
||||
</NForm>
|
||||
</NCard>
|
||||
<NSpace :wrap="false">
|
||||
<NCard class="min-w-[120px] max-w-[120px] min-h-[100px] max-h-[102px] h-full"
|
||||
style="--n-padding-top: 0; --n-padding-left: 0; --n-padding-bottom: 0; --n-padding-right: 0;"
|
||||
>
|
||||
<div class="w-full h-full flex flex items-center justify-center">
|
||||
<NStatistic label="Умерло" :value="reportStore.reportInfo?.department.deadCount" />
|
||||
</div>
|
||||
</NCard>
|
||||
<NCard class="min-w-[120px] max-w-[120px] min-h-[100px] max-h-[102px] h-full"
|
||||
style="--n-padding-top: 0; --n-padding-bottom: 0; --n-padding-left: 8px; --n-padding-right: 8px;">
|
||||
<div class="w-full h-full flex flex items-center justify-center">
|
||||
<NStatistic :value="reportStore.reportInfo?.department.surgicalCount[1]">
|
||||
<template #label>
|
||||
<div class="flex flex-col">
|
||||
<span>Операций</span>
|
||||
<span>Э / П</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #suffix>
|
||||
/ {{ reportStore.reportInfo?.department.surgicalCount[0] }}
|
||||
</template>
|
||||
</NStatistic>
|
||||
</div>
|
||||
</NCard>
|
||||
</NSpace>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
:deep(.n-statistic__label),
|
||||
:deep(.n-statistic-value__content) {
|
||||
@apply text-center;
|
||||
}
|
||||
:deep(.n-statistic-value) {
|
||||
@apply flex justify-center items-center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -7,6 +7,7 @@ import {ru} from "date-fns/locale";
|
||||
import {useAuthStore} from "../../../Stores/auth.js";
|
||||
import {storeToRefs} from "pinia";
|
||||
import {RiAddCircleLine} from 'vue-icons-plus/ri'
|
||||
import {TbAlertCircle} from 'vue-icons-plus/tb'
|
||||
import {useReportStore} from "../../../Stores/report.js";
|
||||
import ReportSelectDate from "../../../Components/ReportSelectDate.vue";
|
||||
import DepartmentSelect from "../../../Components/DepartmentSelect.vue";
|
||||
@@ -53,19 +54,16 @@ const currentDate = computed(() => {
|
||||
<template>
|
||||
<NCard>
|
||||
<NFlex vertical>
|
||||
<NFlex align="center" justify="space-between" :wrap="false">
|
||||
<div class="grid grid-cols-[auto_1fr_auto] items-center">
|
||||
<NTag v-if="isFillableMode" type="info" :bordered="false">
|
||||
{{ authStore.userDepartment.name_full }}
|
||||
</NTag>
|
||||
<DepartmentSelect v-if="isReadonlyMode" />
|
||||
|
||||
<NFlex align="center" :wrap="false">
|
||||
<NH2 v-if="isFillableMode" class="mb-0!">
|
||||
{{ currentDate }}
|
||||
</NH2>
|
||||
<ReportSelectDate v-if="isReadonlyMode" />
|
||||
</NFlex>
|
||||
</NFlex>
|
||||
<div class="col-3 w-full">
|
||||
<ReportSelectDate />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<NFlex justify="space-between" align="center" :wrap="false">
|
||||
<NRow class="grow">
|
||||
@@ -113,9 +111,9 @@ const currentDate = computed(() => {
|
||||
|
||||
<NButton type="error" secondary @click="openUnwantedEventModal = true">
|
||||
<template #icon>
|
||||
<RiAddCircleLine />
|
||||
<TbAlertCircle />
|
||||
</template>
|
||||
Нежелательное событие
|
||||
Нежелательные события ({{ reportStore.unwantedEvents.length }})
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</NFlex>
|
||||
@@ -125,5 +123,11 @@ const currentDate = computed(() => {
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
:deep(.n-statistic__label),
|
||||
:deep(.n-statistic-value__content) {
|
||||
@apply text-center;
|
||||
}
|
||||
:deep(.n-statistic-value) {
|
||||
@apply flex justify-center items-center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import {NCard, NFlex, NAlert, NCollapse, NCollapseItem} from 'naive-ui'
|
||||
import {NCard, NFlex, NAlert, NCollapse, NCollapseItem, NTabPane, NTabs} from 'naive-ui'
|
||||
import ReportSectionItem from "./ReportSectionItem.vue";
|
||||
import {computed} from "vue";
|
||||
import {useReportStore} from "../../../Stores/report.js";
|
||||
@@ -79,12 +79,37 @@ const isReadonlyMode = computed(() => props.mode.toLowerCase() === 'readonly')
|
||||
</NCollapseItem>
|
||||
<NCollapseItem name="4">
|
||||
<template #header>
|
||||
<ReportSectionHeader title="Умершие" status="deceased" />
|
||||
<ReportSectionHeader title="Выбывшие" status="outcome" />
|
||||
</template>
|
||||
<ReportSectionItem status="deceased"
|
||||
@item-dragged="handleItemDragged"
|
||||
@item-dropped="handleItemDropped"
|
||||
/>
|
||||
<NTabs type="segment" animated>
|
||||
<NTabPane name="transferred">
|
||||
<template #tab>
|
||||
<ReportSectionHeader title="Переведённые" status="outcome-transferred" />
|
||||
</template>
|
||||
<ReportSectionItem status="outcome-transferred"
|
||||
@item-dragged="handleItemDragged"
|
||||
@item-dropped="handleItemDropped"
|
||||
/>
|
||||
</NTabPane>
|
||||
<NTabPane name="discharged">
|
||||
<template #tab>
|
||||
<ReportSectionHeader title="Выписанные" status="outcome-discharged" />
|
||||
</template>
|
||||
<ReportSectionItem status="outcome-discharged"
|
||||
@item-dragged="handleItemDragged"
|
||||
@item-dropped="handleItemDropped"
|
||||
/>
|
||||
</NTabPane>
|
||||
<NTabPane name="deceased">
|
||||
<template #tab>
|
||||
<ReportSectionHeader title="Умершие" status="outcome-deceased" />
|
||||
</template>
|
||||
<ReportSectionItem status="outcome-deceased"
|
||||
@item-dragged="handleItemDragged"
|
||||
@item-dropped="handleItemDropped"
|
||||
/>
|
||||
</NTabPane>
|
||||
</NTabs>
|
||||
</NCollapseItem>
|
||||
</NCollapse>
|
||||
</NCard>
|
||||
|
||||
@@ -19,21 +19,17 @@ const reportStore = useReportStore()
|
||||
const isLoading = ref(true)
|
||||
const countPatient = ref(null)
|
||||
const fetchPatientCount = async () => {
|
||||
if (props.status === 'plan' || props.status === 'emergency') {
|
||||
isLoading.value = true
|
||||
const data = {
|
||||
status: props.status,
|
||||
startAt: reportStore.timestampCurrentRange[0],
|
||||
endAt: reportStore.timestampCurrentRange[1]
|
||||
}
|
||||
await axios.post('/api/mis/patients/count', data).then((res) => {
|
||||
countPatient.value = res.data
|
||||
}).finally(() => {
|
||||
isLoading.value = false
|
||||
})
|
||||
} else {
|
||||
isLoading.value = false
|
||||
isLoading.value = true
|
||||
const data = {
|
||||
status: props.status,
|
||||
startAt: reportStore.timestampCurrentRange[0],
|
||||
endAt: reportStore.timestampCurrentRange[1]
|
||||
}
|
||||
await axios.post('/api/mis/patients/count', data).then((res) => {
|
||||
countPatient.value = res.data
|
||||
}).finally(() => {
|
||||
isLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const computedHeader = computed(() => {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<script setup>
|
||||
import {NIcon, NText, NDataTable, NButton} from "naive-ui";
|
||||
import {NIcon, NText, NDataTable, NButton, NTabs, NTabPane} from "naive-ui";
|
||||
import {useReportStore} from "../../../Stores/report.js";
|
||||
import {computed, h, onMounted, ref, watch} from "vue";
|
||||
import { VueDraggableNext } from 'vue-draggable-next'
|
||||
import {storeToRefs} from "pinia";
|
||||
import {TbGripVertical} from "vue-icons-plus/tb";
|
||||
import MoveModalComment from "./MoveModalComment.vue";
|
||||
|
||||
const props = defineProps({
|
||||
mode: {
|
||||
@@ -30,7 +31,7 @@ const props = defineProps({
|
||||
accentIds: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
const isFillableMode = computed(() => props.mode.toLowerCase() === 'fillable')
|
||||
@@ -46,10 +47,12 @@ const {patientsData} = storeToRefs(reportStore)
|
||||
const baseColumns = reportStore.getColumnsByKey(props.keys)
|
||||
const data = ref([])
|
||||
const isLoading = ref(true)
|
||||
const showMoveModal = ref(false)
|
||||
const latestDropItem = ref(null)
|
||||
|
||||
// Добавляем drag колонку если режим fillable
|
||||
const columns = computed(() => {
|
||||
if (!isFillableMode.value) return baseColumns
|
||||
// if (!isFillableMode.value) return baseColumns
|
||||
|
||||
const newColumns = []
|
||||
|
||||
@@ -83,7 +86,11 @@ const columns = computed(() => {
|
||||
{
|
||||
text: true,
|
||||
onClick: () => {
|
||||
alert('message')
|
||||
axios.post('/api/report/observation/remove', {
|
||||
id: row.id
|
||||
}).then(async () => {
|
||||
await fetchPatients()
|
||||
})
|
||||
}
|
||||
},
|
||||
[
|
||||
@@ -92,11 +99,30 @@ const columns = computed(() => {
|
||||
)
|
||||
}
|
||||
|
||||
const expandColumn = {
|
||||
type: 'expand',
|
||||
renderExpand: (rowData) => {
|
||||
return h(
|
||||
NText,
|
||||
{
|
||||
class: 'max-w-full break-words whitespace-normal'
|
||||
},
|
||||
{
|
||||
default: rowData.comment ?? 'Причина наблюдения не указана'
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (props.status === 'observation') {
|
||||
newColumns.push(expandColumn)
|
||||
}
|
||||
|
||||
if (props.isDraggable) newColumns.push(dragColumn)
|
||||
newColumns.push(...baseColumns)
|
||||
if (props.isRemovable) newColumns.push(removeColumn)
|
||||
|
||||
if (props.status === 'emergency') {
|
||||
if (props.status === 'emergency' || props.status === 'plan') {
|
||||
const operationColumn = {
|
||||
title: 'Операции',
|
||||
key: 'operations',
|
||||
@@ -109,11 +135,25 @@ const columns = computed(() => {
|
||||
return `${itm.code}; `
|
||||
})
|
||||
]
|
||||
) : h('div', {}, '-')
|
||||
) : h('div', {}, '-'),
|
||||
ellipsis: {
|
||||
tooltip: true
|
||||
}
|
||||
}
|
||||
newColumns.push(operationColumn)
|
||||
}
|
||||
|
||||
if (props.status === 'outcome') {
|
||||
const typeColumn = {
|
||||
title: 'Причина',
|
||||
key: 'outcome_type',
|
||||
ellipsis: {
|
||||
tooltip: true
|
||||
}
|
||||
}
|
||||
newColumns.push(typeColumn)
|
||||
}
|
||||
|
||||
return newColumns
|
||||
})
|
||||
|
||||
@@ -156,6 +196,9 @@ const handleDrop = (e) => {
|
||||
fromStatus: dragData.fromStatus,
|
||||
toStatus: props.status
|
||||
})
|
||||
|
||||
latestDropItem.value = dragData.row
|
||||
showMoveModal.value = true
|
||||
} catch (error) {
|
||||
console.error('Drop error:', error)
|
||||
}
|
||||
@@ -216,24 +259,21 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NDataTable :columns="columns"
|
||||
ref="tableRef"
|
||||
:data="patientsData[status]"
|
||||
size="small"
|
||||
@drop="handleDrop"
|
||||
@dragover="handleDragOver"
|
||||
:loading="isLoading"
|
||||
max-height="200"
|
||||
min-height="200"
|
||||
:row-props="rowProps"
|
||||
class="text-sm!">
|
||||
</NDataTable>
|
||||
<!-- <NDataTable :columns="columns"-->
|
||||
<!-- :data="data"-->
|
||||
<!-- size="small"-->
|
||||
<!-- max-height="200"-->
|
||||
<!-- class="text-sm!">-->
|
||||
<!-- </NDataTable>-->
|
||||
<NDataTable :columns="columns"
|
||||
ref="tableRef"
|
||||
:data="patientsData[status]"
|
||||
size="small"
|
||||
@drop="handleDrop"
|
||||
@dragover="handleDragOver"
|
||||
:loading="isLoading"
|
||||
max-height="200"
|
||||
min-height="200"
|
||||
:row-props="rowProps"
|
||||
:row-key="(row) => row.id"
|
||||
class="text-sm!">
|
||||
</NDataTable>
|
||||
|
||||
<MoveModalComment v-model:show="showMoveModal" :patient-id="latestDropItem?.id" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
<script setup>
|
||||
import {NModal, NForm, NFormItem, NInput, NFlex, NButton} from 'naive-ui'
|
||||
import {useForm} from "@inertiajs/vue3";
|
||||
import {NModal, NList, NListItem, NThing, NAvatar, NIcon, NDrawer, NDrawerContent,
|
||||
NText, NDivider, NForm, NFormItem, NInput, NFlex, NButton, NScrollbar, NEmpty
|
||||
} from 'naive-ui'
|
||||
import {useReportStore} from "../../../Stores/report.js";
|
||||
import {ref} from "vue";
|
||||
const open = defineModel('open')
|
||||
import { TbAlertCircle, TbPencil, TbTrashX, TbCirclePlus, TbCheck, TbX } from 'vue-icons-plus/tb'
|
||||
import {format, isValid} from "date-fns";
|
||||
|
||||
const reportStore = useReportStore()
|
||||
const formRef = ref()
|
||||
const createDrawerShow = ref(false)
|
||||
const rules = {
|
||||
comment: {
|
||||
required: true,
|
||||
@@ -14,34 +18,191 @@ const rules = {
|
||||
trigger: 'blur'
|
||||
}
|
||||
}
|
||||
const selectedEvent = ref(null)
|
||||
const drawerCreatingMode = ref(true) // or false = editing
|
||||
|
||||
const onSubmit = () => {
|
||||
// Создание в сторе и открытие drawer с формой нежелательного события
|
||||
const onCreateEvent = () => {
|
||||
drawerCreatingMode.value = true
|
||||
const createDate = format(new Date(), 'Создано dd.MM.yyyy в HH:mm')
|
||||
reportStore.unwantedEvents.push({
|
||||
title: `Нежелательное событие №${reportStore.unwantedEvents.length + 1}`,
|
||||
comment: '',
|
||||
created_at: createDate
|
||||
})
|
||||
|
||||
const length = reportStore.unwantedEvents.length
|
||||
|
||||
selectedEvent.value = reportStore.unwantedEvents[length - 1]
|
||||
createDrawerShow.value = true
|
||||
}
|
||||
|
||||
const onEditEvent = (event) => {
|
||||
drawerCreatingMode.value = false
|
||||
selectedEvent.value = event
|
||||
createDrawerShow.value = true
|
||||
}
|
||||
|
||||
const onDeleteEvent = (event) => {
|
||||
const indexOfDelete = reportStore.unwantedEvents.findIndex(itm => itm === event)
|
||||
|
||||
if (typeof event.unwanted_event_id !== 'undefined') {
|
||||
axios.delete(`/api/report/unwanted-event/${event.unwanted_event_id}`)
|
||||
.then(() => {
|
||||
reportStore.unwantedEvents.splice(indexOfDelete, 1)
|
||||
})
|
||||
} else {
|
||||
reportStore.unwantedEvents.splice(indexOfDelete, 1)
|
||||
}
|
||||
}
|
||||
|
||||
const onCancelDrawerEvent = (event) => {
|
||||
onDeleteEvent(event)
|
||||
createDrawerShow.value = false
|
||||
}
|
||||
|
||||
const onCreateDrawerEvent = () => {
|
||||
formRef.value?.validate((errors) => {
|
||||
if (!errors) {
|
||||
open.value = false
|
||||
console.log(createDrawerShow.value)
|
||||
createDrawerShow.value = false
|
||||
console.log(createDrawerShow.value)
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const onBeforeLeaveModal = () => {
|
||||
selectedEvent.value = null
|
||||
drawerCreatingMode.value = true
|
||||
createDrawerShow.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NModal v-model:show="open" title="Нежелательное событие" preset="card" class="max-w-xl">
|
||||
<NForm ref="formRef" :model="reportStore.reportForm" :rules="rules">
|
||||
<NFormItem :show-label="false" path="comment">
|
||||
<NInput type="textarea" :rows="8" v-model:value="reportStore.reportForm.comment" />
|
||||
</NFormItem>
|
||||
</NForm>
|
||||
<NModal v-model:show="open"
|
||||
title="Нежелательные события"
|
||||
preset="card"
|
||||
:mask-closable="false"
|
||||
:close-on-esc="false"
|
||||
@before-leave="onBeforeLeaveModal"
|
||||
class="max-w-4xl overflow-clip h-[calc(100vh-220px)]"
|
||||
>
|
||||
<template v-if="reportStore.unwantedEvents.length">
|
||||
<NScrollbar class="max-h-[calc(100vh-282px)] pr-3">
|
||||
<NList>
|
||||
<NListItem v-for="event in reportStore.unwantedEvents">
|
||||
<NThing>
|
||||
<template #avatar>
|
||||
<NAvatar>
|
||||
<NIcon>
|
||||
<TbAlertCircle class="text-red-400" />
|
||||
</NIcon>
|
||||
</NAvatar>
|
||||
</template>
|
||||
<template #header>
|
||||
{{ event.title }}
|
||||
</template>
|
||||
<template #description>
|
||||
<NText depth="3">
|
||||
{{ event.created_at }}
|
||||
</NText>
|
||||
</template>
|
||||
<NText>
|
||||
{{ event.comment }}
|
||||
</NText>
|
||||
<template #action>
|
||||
<NFlex align="center">
|
||||
<NButton secondary size="small" @click="onEditEvent(event)">
|
||||
<template #icon>
|
||||
<TbPencil />
|
||||
</template>
|
||||
Редактировать
|
||||
</NButton>
|
||||
<NDivider vertical />
|
||||
<NButton type="error" secondary size="small" @click="onDeleteEvent(event)">
|
||||
<template #icon>
|
||||
<TbTrashX />
|
||||
</template>
|
||||
Удалить
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</template>
|
||||
</NThing>
|
||||
</NListItem>
|
||||
</NList>
|
||||
</NScrollbar>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="h-full flex items-center justify-center">
|
||||
<NEmpty description="Нежелательных событий не найдено!">
|
||||
<template #extra>
|
||||
<NButton type="primary" secondary @click="onCreateEvent()" size="small">
|
||||
<template #icon>
|
||||
<TbCirclePlus />
|
||||
</template>
|
||||
Создать
|
||||
</NButton>
|
||||
</template>
|
||||
</NEmpty>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #action>
|
||||
<NFlex align="center" justify="end">
|
||||
<NButton type="primary" tertiary @click="onSubmit">
|
||||
Сохранить
|
||||
<NFlex id="modal-action" align="center" justify="space-between">
|
||||
<NButton type="primary" secondary @click="onCreateEvent()">
|
||||
<template #icon>
|
||||
<TbCirclePlus />
|
||||
</template>
|
||||
Создать событие
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</template>
|
||||
|
||||
<NDrawer
|
||||
:show="createDrawerShow"
|
||||
placement="bottom"
|
||||
:max-height="600"
|
||||
:min-height="400"
|
||||
:default-height="400"
|
||||
resizable
|
||||
:trap-focus="false"
|
||||
:block-scroll="false"
|
||||
:mask-closable="false"
|
||||
to="#modal-action"
|
||||
>
|
||||
<NDrawerContent>
|
||||
<template #header>
|
||||
<template v-if="drawerCreatingMode">Создание события</template>
|
||||
<template v-else>Редактирование события</template>
|
||||
</template>
|
||||
<NForm ref="formRef" :model="selectedEvent" :rules="rules">
|
||||
<NFormItem :show-label="false" path="comment">
|
||||
<NInput type="textarea" :rows="8" v-model:value="selectedEvent.comment" />
|
||||
</NFormItem>
|
||||
</NForm>
|
||||
<template #footer>
|
||||
<NFlex align="center">
|
||||
<NButton v-if="drawerCreatingMode" type="error" secondary @click="onCancelDrawerEvent(selectedEvent)">
|
||||
<template #icon>
|
||||
<TbX />
|
||||
</template>
|
||||
Отменить создание
|
||||
</NButton>
|
||||
<NDivider v-if="drawerCreatingMode" vertical />
|
||||
<NButton type="primary" @click="onCreateDrawerEvent">
|
||||
<template #icon>
|
||||
<TbCheck />
|
||||
</template>
|
||||
<template v-if="drawerCreatingMode">Создать</template>
|
||||
<template v-else>Сохранить</template>
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</template>
|
||||
</NDrawerContent>
|
||||
</NDrawer>
|
||||
</NModal>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user