* добавил удаление карты, если она была добавлена не из МИС
* добавил диалог при удалении карты * добавил сохранение движения * добавил вывод сохраненного отчета * изменил логику сохранения отчета
This commit is contained in:
53
resources/js/Components/AppDialog.vue
Normal file
53
resources/js/Components/AppDialog.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<script setup>
|
||||
import { NModal, NSpace, NButton, NText, NFlex, NSpin } from 'naive-ui'
|
||||
|
||||
const props = defineProps({
|
||||
show: Boolean,
|
||||
loading: Boolean,
|
||||
title: String,
|
||||
content: String,
|
||||
positiveText: { type: String, default: 'Подтвердить' },
|
||||
negativeText: { type: String, default: 'Отмена' },
|
||||
maskClosable: { type: Boolean, default: false },
|
||||
positiveProps: { type: Object, default: { type: 'error', secondary: true } },
|
||||
negativeProps: { type: Object, default: { type: 'primary', secondary: true } }
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:show', 'confirm', 'cancel'])
|
||||
|
||||
const handleAction = (type) => {
|
||||
emit(type)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NModal
|
||||
:show="show"
|
||||
:mask-closable="maskClosable"
|
||||
@update:show="(val) => emit('update:show', val)"
|
||||
@after-leave="emit('after-leave')"
|
||||
preset="card"
|
||||
class="max-w-sm relative overflow-clip"
|
||||
:title="title"
|
||||
>
|
||||
<NFlex vertical size="large">
|
||||
<NSpace vertical :size="0">
|
||||
<NText v-if="content" tag="p">{{ content }}</NText>
|
||||
</NSpace>
|
||||
|
||||
<NSpace vertical size="small">
|
||||
<NButton v-if="negativeText" block v-bind="negativeProps" @click="handleAction('cancel')">
|
||||
{{ negativeText }}
|
||||
</NButton>
|
||||
<NButton v-if="positiveText" block v-bind="positiveProps" @click="handleAction('confirm')">
|
||||
{{ positiveText }}
|
||||
</NButton>
|
||||
</NSpace>
|
||||
</NFlex>
|
||||
<div v-if="loading" class="absolute inset-0" style="background-color: color-mix(in srgb, var(--n-color-embedded-modal), transparent 50%);">
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<NSpin description="Загрузка" />
|
||||
</div>
|
||||
</div>
|
||||
</NModal>
|
||||
</template>
|
||||
40
resources/js/Components/AppDialogManager.vue
Normal file
40
resources/js/Components/AppDialogManager.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<script setup>
|
||||
import {dialogQueue, closeDialog, cleanupDialog} from '../Composables/useAppDialog'
|
||||
import AppDialog from './AppDialog.vue'
|
||||
|
||||
const handleConfirm = async (dialog) => {
|
||||
dialog.loading = true
|
||||
try {
|
||||
// Ждём выполнения вашего запроса
|
||||
if (typeof dialog.onConfirm === 'function') {
|
||||
await dialog.onConfirm()
|
||||
}
|
||||
closeDialog(dialog.id, true)
|
||||
} catch (error) {
|
||||
console.error('Ошибка при подтверждении:', error)
|
||||
dialog.loading = false // Оставляем диалог открытым при ошибке
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Teleport to="body">
|
||||
<AppDialog
|
||||
v-for="dialog in dialogQueue"
|
||||
:key="dialog.id"
|
||||
:show="dialog.show"
|
||||
:loading="dialog.loading"
|
||||
:title="dialog.title"
|
||||
:content="dialog.content"
|
||||
:positive-text="dialog.positiveText"
|
||||
:negative-text="dialog.negativeText"
|
||||
:positive-props="dialog.positiveProps"
|
||||
:negative-props="dialog.negativeProps"
|
||||
:mask-closable="dialog.maskClosable"
|
||||
@confirm="handleConfirm(dialog)"
|
||||
@cancel="closeDialog(dialog.id, false)"
|
||||
@update:show="(val) => !val && dialog.show && !dialog.loading && closeDialog(dialog.id, false)"
|
||||
@after-leave="cleanupDialog(dialog.id)"
|
||||
/>
|
||||
</Teleport>
|
||||
</template>
|
||||
@@ -120,37 +120,52 @@ const modelComputed = computed({
|
||||
const formattedValue = computed(() => {
|
||||
const value = reportStore.timestampCurrentRange
|
||||
|
||||
if (authStore.isHeadOfDepartment || authStore.isAdmin) {
|
||||
if (props.isOneDay) {
|
||||
const dateToFormat = Array.isArray(value) ? value[1] : value
|
||||
return formatRussianDate(dateToFormat)
|
||||
} else if (Array.isArray(value) && value.length >= 2 && value[0] && value[1]) { // Для админа - диапазон дат
|
||||
return formatRussianDateRange(value)
|
||||
}
|
||||
|
||||
// Если что-то пошло не так, форматируем как одиночную дату
|
||||
if (value) {
|
||||
const dateToFormat = Array.isArray(value) ? value[0] : value
|
||||
return formatRussianDate(dateToFormat)
|
||||
}
|
||||
|
||||
return ''
|
||||
} else {
|
||||
// Для врача - одиночная дата
|
||||
let dateToFormat
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
dateToFormat = value[1] || value[0]
|
||||
} else {
|
||||
dateToFormat = value
|
||||
}
|
||||
|
||||
// Если выбрана сегодняшняя дата - показываем текущее время
|
||||
if (dateToFormat) {
|
||||
return formatRussianDate(dateToFormat)
|
||||
}
|
||||
return ''
|
||||
if (props.isOneDay) {
|
||||
const dateToFormat = Array.isArray(value) ? value[1] : value
|
||||
return formatRussianDate(dateToFormat)
|
||||
} else if (Array.isArray(value) && value.length >= 2 && value[0] && value[1]) { // Для админа - диапазон дат
|
||||
return formatRussianDateRange(value)
|
||||
}
|
||||
|
||||
// Если что-то пошло не так, форматируем как одиночную дату
|
||||
if (value) {
|
||||
const dateToFormat = Array.isArray(value) ? value[0] : value
|
||||
return formatRussianDate(dateToFormat)
|
||||
}
|
||||
|
||||
return ''
|
||||
|
||||
// if (authStore.isHeadOfDepartment || authStore.isAdmin) {
|
||||
// if (props.isOneDay) {
|
||||
// const dateToFormat = Array.isArray(value) ? value[1] : value
|
||||
// return formatRussianDate(dateToFormat)
|
||||
// } else if (Array.isArray(value) && value.length >= 2 && value[0] && value[1]) { // Для админа - диапазон дат
|
||||
// return formatRussianDateRange(value)
|
||||
// }
|
||||
//
|
||||
// // Если что-то пошло не так, форматируем как одиночную дату
|
||||
// if (value) {
|
||||
// const dateToFormat = Array.isArray(value) ? value[0] : value
|
||||
// return formatRussianDate(dateToFormat)
|
||||
// }
|
||||
//
|
||||
// return ''
|
||||
// } else {
|
||||
// // Для врача - одиночная дата
|
||||
// let dateToFormat
|
||||
//
|
||||
// if (Array.isArray(value)) {
|
||||
// dateToFormat = value[1] || value[0]
|
||||
// } else {
|
||||
// dateToFormat = value
|
||||
// }
|
||||
//
|
||||
// // Если выбрана сегодняшняя дата - показываем текущее время
|
||||
// if (dateToFormat) {
|
||||
// return formatRussianDate(dateToFormat)
|
||||
// }
|
||||
// return ''
|
||||
// }
|
||||
})
|
||||
|
||||
const classComputed = computed(() => {
|
||||
|
||||
37
resources/js/Composables/useAppDialog.js
Normal file
37
resources/js/Composables/useAppDialog.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import { h, ref, render, nextTick } from 'vue'
|
||||
import AppDialog from '../Components/AppDialog.vue'
|
||||
|
||||
// Глобальная очередь диалогов
|
||||
export const dialogQueue = ref([])
|
||||
let idCounter = 0
|
||||
|
||||
// Вызывается при клике на кнопку / Esc / клик по маске
|
||||
export function closeDialog(id, confirmed = false) {
|
||||
const dialog = dialogQueue.value.find(d => d.id === id)
|
||||
if (dialog && dialog.show) {
|
||||
dialog.show = false // Запускает leave-анимацию
|
||||
dialog.resolve(confirmed) // Резолвим промис сразу для лучшего UX
|
||||
}
|
||||
}
|
||||
|
||||
// Вызывается после завершения leave-анимации
|
||||
export function cleanupDialog(id) {
|
||||
dialogQueue.value = dialogQueue.value.filter(d => d.id !== id)
|
||||
}
|
||||
|
||||
export function useAppDialog({title, content, positiveProps, negativeProps, positiveText = 'Подтвердить', negativeText = 'Отмена', maskClosable = false, onConfirm } = {}) {
|
||||
return new Promise((resolve) => {
|
||||
const id = idCounter++
|
||||
// 1. Добавляем скрытым, чтобы сработала enter-анимация
|
||||
dialogQueue.value.push({
|
||||
id, show: false, title, content, loading: false, onConfirm,
|
||||
positiveText, negativeText, positiveProps, negativeProps, maskClosable, resolve
|
||||
})
|
||||
|
||||
// 2. Переключаем в visible на следующем тике
|
||||
nextTick(() => {
|
||||
const dialog = dialogQueue.value.find(d => d.id === id)
|
||||
if (dialog) dialog.show = true
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1,99 +1,85 @@
|
||||
<script setup>
|
||||
import {NLayout, NLayoutSider, NConfigProvider, NLayoutHeader, ruRU, dateRuRU, darkTheme, NEl, NAlert, NSpin, NText} from "naive-ui";
|
||||
import SideMenu from "./Components/SideMenu.vue";
|
||||
import {NLayout, NLayoutHeader, NEl, NAlert, NSpin, NText} from "naive-ui";
|
||||
import AppHeader from "./Components/AppHeader.vue";
|
||||
import {useGlobalLoading} from "../Composables/useGlobalLoading.js";
|
||||
import AppDialogManager from "../Components/AppDialogManager.vue";
|
||||
|
||||
const {isGlobalLoading} = useGlobalLoading()
|
||||
|
||||
const themeOverrides = {
|
||||
Modal: {
|
||||
peers: {
|
||||
Dialog: {
|
||||
borderRadius: '8px'
|
||||
},
|
||||
Card: {
|
||||
borderRadius: '8px'
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NConfigProvider :theme="darkTheme" :theme-overrides="themeOverrides" :locale="ruRU" :date-locale="dateRuRU">
|
||||
<NLayout position="absolute">
|
||||
<AppDialogManager />
|
||||
<NLayout position="absolute">
|
||||
|
||||
<NLayoutHeader style="height: 48px;" bordered>
|
||||
<AppHeader>
|
||||
<template #headerExtra>
|
||||
<slot name="headerExtra" />
|
||||
</template>
|
||||
<NLayoutHeader style="height: 48px;" bordered>
|
||||
<AppHeader>
|
||||
<template #headerExtra>
|
||||
<slot name="headerExtra" />
|
||||
</template>
|
||||
|
||||
<template #headerSuffix>
|
||||
<slot name="headerSuffix" />
|
||||
</template>
|
||||
</AppHeader>
|
||||
</NLayoutHeader>
|
||||
<template #headerSuffix>
|
||||
<slot name="headerSuffix" />
|
||||
</template>
|
||||
</AppHeader>
|
||||
</NLayoutHeader>
|
||||
|
||||
<Transition name="wait-alert">
|
||||
<NEl
|
||||
v-if="isGlobalLoading"
|
||||
class="wait-layer pointer-events-none fixed inset-x-0 top-[56px] z-[2600] flex justify-center px-3"
|
||||
>
|
||||
<NAlert
|
||||
type="info"
|
||||
:show-icon="false"
|
||||
class="wait-banner w-full max-w-md"
|
||||
style="
|
||||
<Transition name="wait-alert">
|
||||
<NEl
|
||||
v-if="isGlobalLoading"
|
||||
class="wait-layer pointer-events-none fixed inset-x-0 top-[56px] z-[2600] flex justify-center px-3"
|
||||
>
|
||||
<NAlert
|
||||
type="info"
|
||||
:show-icon="false"
|
||||
class="wait-banner w-full max-w-md"
|
||||
style="
|
||||
--n-color: color-mix(in oklch, var(--info-color) 12%, transparent);
|
||||
--n-border: 1px solid color-mix(in oklch, var(--info-color) 36%, transparent);
|
||||
"
|
||||
>
|
||||
<div class="flex items-center justify-center gap-2.5 text-[13px] leading-none">
|
||||
<NSpin :size="14" />
|
||||
<NText depth="1" class="tracking-[0.1px]">Подождите, загружаем данные…</NText>
|
||||
</div>
|
||||
</NAlert>
|
||||
</NEl>
|
||||
</Transition>
|
||||
|
||||
<NEl class="pointer-events-none fixed inset-x-0 top-12 bottom-0 overflow-hidden z-0">
|
||||
<div class="absolute inset-x-0 top-[-12rem] mx-auto h-80 w-80 rounded-full blur-3xl"
|
||||
style="background: color-mix(in oklch, var(--primary-color) 22%, transparent);" />
|
||||
<div class="absolute right-[-8rem] top-48 h-72 w-72 rounded-full blur-3xl"
|
||||
style="background: color-mix(in oklch, var(--warning-color) 28%, transparent);" />
|
||||
<div class="absolute left-[-10rem] bottom-10 h-80 w-80 rounded-full blur-3xl"
|
||||
style="background: color-mix(in oklch, var(--info-color) 24%, transparent);" />
|
||||
<div class="grid-overlay absolute inset-0 opacity-65" />
|
||||
</NEl>
|
||||
|
||||
<NLayout
|
||||
has-sider
|
||||
position="absolute"
|
||||
class="top-12! bottom-0! relative overflow-hidden z-10"
|
||||
content-class="relative z-10"
|
||||
:native-scrollbar="false"
|
||||
style="--n-color: transparent;"
|
||||
>
|
||||
<!-- <NLayoutSider-->
|
||||
<!-- :native-scrollbar="false"-->
|
||||
<!-- width="290"-->
|
||||
<!-- class="h-[100vh-48px]!"-->
|
||||
<!-- >-->
|
||||
<!-- <SideMenu />-->
|
||||
<!-- </NLayoutSider>-->
|
||||
|
||||
<NLayout style="--n-color: transparent;">
|
||||
<div>
|
||||
<slot name="header" />
|
||||
>
|
||||
<div class="flex items-center justify-center gap-2.5 text-[13px] leading-none">
|
||||
<NSpin :size="14" />
|
||||
<NText depth="1" class="tracking-[0.1px]">Подождите, загружаем данные…</NText>
|
||||
</div>
|
||||
<slot />
|
||||
</NLayout>
|
||||
</NLayout>
|
||||
</NAlert>
|
||||
</NEl>
|
||||
</Transition>
|
||||
|
||||
<NEl class="pointer-events-none fixed inset-x-0 top-12 bottom-0 overflow-hidden z-0">
|
||||
<div class="absolute inset-x-0 top-[-12rem] mx-auto h-80 w-80 rounded-full blur-3xl"
|
||||
style="background: color-mix(in oklch, var(--primary-color) 22%, transparent);" />
|
||||
<div class="absolute right-[-8rem] top-48 h-72 w-72 rounded-full blur-3xl"
|
||||
style="background: color-mix(in oklch, var(--warning-color) 28%, transparent);" />
|
||||
<div class="absolute left-[-10rem] bottom-10 h-80 w-80 rounded-full blur-3xl"
|
||||
style="background: color-mix(in oklch, var(--info-color) 24%, transparent);" />
|
||||
<div class="grid-overlay absolute inset-0 opacity-65" />
|
||||
</NEl>
|
||||
|
||||
<NLayout
|
||||
has-sider
|
||||
position="absolute"
|
||||
class="top-12! bottom-0! relative overflow-hidden z-10"
|
||||
content-class="relative z-10"
|
||||
:native-scrollbar="false"
|
||||
style="--n-color: transparent;"
|
||||
>
|
||||
<!-- <NLayoutSider-->
|
||||
<!-- :native-scrollbar="false"-->
|
||||
<!-- width="290"-->
|
||||
<!-- class="h-[100vh-48px]!"-->
|
||||
<!-- >-->
|
||||
<!-- <SideMenu />-->
|
||||
<!-- </NLayoutSider>-->
|
||||
|
||||
<NLayout style="--n-color: transparent;">
|
||||
<div>
|
||||
<slot name="header" />
|
||||
</div>
|
||||
<slot />
|
||||
</NLayout>
|
||||
</NLayout>
|
||||
</NConfigProvider>
|
||||
|
||||
</NLayout>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<script setup>
|
||||
import {NFlex, NButton} from 'naive-ui'
|
||||
import {TbPencil, TbTrash} from 'vue-icons-plus/tb'
|
||||
import {computed} from "vue";
|
||||
const props = defineProps({
|
||||
row: {
|
||||
type: Object
|
||||
}
|
||||
})
|
||||
const emits = defineEmits(['clickEdit', 'clickDelete'])
|
||||
|
||||
const onClickEdit = () => {
|
||||
emits('clickEdit', props.row.id)
|
||||
}
|
||||
const onClickDelete = () => {
|
||||
emits('clickDelete', props.row.id)
|
||||
}
|
||||
|
||||
const isMisType = computed(() => props.row.source_type === 'mis')
|
||||
const isManualType = computed(() => props.row.source_type === 'manual')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NFlex align="center" justify="end">
|
||||
<NButton v-if="isManualType" type="error" secondary size="tiny" @click="onClickDelete">
|
||||
<template #icon>
|
||||
<TbTrash />
|
||||
</template>
|
||||
Удалить
|
||||
</NButton>
|
||||
<NButton secondary size="tiny" @click="onClickEdit">
|
||||
<template #icon>
|
||||
<TbPencil />
|
||||
</template>
|
||||
Редактировать
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -160,10 +160,10 @@ const onChangeSearch = (historyId) => {
|
||||
form.value.urgency_id = res.data.urgency_id
|
||||
form.value.visit_result_id = res.data.visit_result_id
|
||||
|
||||
form.value.birth_date = res.data.birth_date ? format(new Date(res.data.birth_date), 'yyyy-MM-dd HH:mm:ss') : null
|
||||
form.value.death_date = res.data.death_date ? format(new Date(res.data.death_date), 'yyyy-MM-dd HH:mm:ss') : null
|
||||
form.value.extract_date = res.data.extract_date ? format(new Date(res.data.extract_date), 'yyyy-MM-dd HH:mm:ss') : null
|
||||
form.value.recipient_date = res.data.recipient_date ? format(new Date(res.data.recipient_date), 'yyyy-MM-dd HH:mm:ss') : null
|
||||
form.value.birth_date = res.data.birth_date
|
||||
form.value.death_date = res.data.death_date
|
||||
form.value.extract_date = res.data.extract_date
|
||||
form.value.recipient_date = res.data.recipient_date
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ const props = defineProps({
|
||||
|
||||
const form = ref({
|
||||
patient_source: 'mis',
|
||||
original_id: null,
|
||||
patient_id: null,
|
||||
full_name: '',
|
||||
urgency_id: 1,
|
||||
@@ -128,7 +129,9 @@ const fetchPatient = async (historyId) => {
|
||||
loading.value = true
|
||||
await axios.get(`/api/nurse/patients/${historyId}`)
|
||||
.then(res => {
|
||||
form.value.patient_source = res.data.source_type
|
||||
form.value.patient_id = historyId
|
||||
form.value.original_id = res.data.original_id
|
||||
form.value.full_name = res.data.full_name
|
||||
form.value.urgency_id = res.data.urgency_id
|
||||
form.value.visit_result_id = res.data.visit_result_id
|
||||
|
||||
@@ -5,12 +5,14 @@ import AppContainer from "../../../Components/AppContainer.vue";
|
||||
import AppPanel from "../../../Components/AppPanel.vue";
|
||||
import DatePickerQuery from "../../../Components/DatePickerQuery.vue";
|
||||
import UrgencyBadge from "../../../Components/UrgencyBadge.vue";
|
||||
import {h, ref, shallowRef} from "vue"
|
||||
import {h, onMounted, ref, shallowRef} from "vue"
|
||||
import {TbCirclePlus, TbPencil} from 'vue-icons-plus/tb'
|
||||
import {useAuthStore} from "../../../Stores/auth.js";
|
||||
import AddMedicalHistoryModal from "../Components/AddMedicalHistoryModal.vue";
|
||||
import EditMedicalHistoryModal from "../Components/EditMedicalHistoryModal.vue";
|
||||
import {router} from "@inertiajs/vue3";
|
||||
import ActionsColumnDataTable from "../Components/ActionsColumnDataTable.vue";
|
||||
import {useAppDialog} from "../../../Composables/useAppDialog.js";
|
||||
|
||||
const props = defineProps({
|
||||
inDepartmentHistories: {
|
||||
@@ -44,6 +46,7 @@ const showEditMedicalHistoryModal = shallowRef(false)
|
||||
const editHistoryId = ref(null)
|
||||
const authStore = useAuthStore()
|
||||
const userDepartment = authStore.userDepartment
|
||||
const loading = ref(false)
|
||||
|
||||
const columns = [
|
||||
{
|
||||
@@ -74,8 +77,13 @@ const columns = [
|
||||
align: 'end',
|
||||
render: (row) => {
|
||||
return h(
|
||||
NButton, { size: 'tiny', type: 'default', secondary: true, onClick: () => onClickEditButton(row.id) },
|
||||
{ default: () => 'Редактировать', icon: () => h(TbPencil, { size: '18px' }) })
|
||||
ActionsColumnDataTable,
|
||||
{
|
||||
row: row,
|
||||
onClickDelete: (historyId) => onClickDeleteButton(historyId),
|
||||
onClickEdit: (historyId) => onClickEditButton(historyId),
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -85,6 +93,32 @@ const onClickEditButton = (historyId) => {
|
||||
editHistoryId.value = historyId
|
||||
}
|
||||
|
||||
const onClickDeleteButton = async (historyId) => {
|
||||
const confirmed = await useAppDialog({
|
||||
title: 'Удалить историю?',
|
||||
content: 'Это действие необратимо',
|
||||
onConfirm: async () => {
|
||||
await axios.delete(`/api/nurse/patients/${historyId}`)
|
||||
}
|
||||
})
|
||||
|
||||
if (confirmed) {
|
||||
loading.value = true
|
||||
router.reload({
|
||||
only: [
|
||||
'inDepartmentHistories',
|
||||
'recipientHistories',
|
||||
'dischargedHistories',
|
||||
'deceasedHistories',
|
||||
'transferredHistories'
|
||||
],
|
||||
onSuccess: () => {
|
||||
loading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const submit = () => {
|
||||
router.post('/nurse/report/save', {}, {
|
||||
onSuccess: () => {
|
||||
@@ -111,7 +145,7 @@ const formattedLabel = (word, count) => {
|
||||
</AppPanel>
|
||||
<AppPanel header="Пациенты в отделении" header-include-body>
|
||||
<template #header-extra>
|
||||
<NButton secondary @click="showAddMedicalHistoryModal = true">
|
||||
<NButton secondary :loading="loading" @click="showAddMedicalHistoryModal = true">
|
||||
<template #icon>
|
||||
<TbCirclePlus />
|
||||
</template>
|
||||
@@ -127,6 +161,7 @@ const formattedLabel = (word, count) => {
|
||||
table-layout="fixed"
|
||||
max-height="calc(100vh - 435px)"
|
||||
min-height="calc(100vh - 435px)"
|
||||
:loading="loading"
|
||||
/>
|
||||
</NTabPane>
|
||||
<NTabPane name="income" :tab="formattedLabel('Поступившие', recipientHistories.length)">
|
||||
@@ -135,6 +170,7 @@ const formattedLabel = (word, count) => {
|
||||
table-layout="fixed"
|
||||
max-height="calc(100vh - 435px)"
|
||||
min-height="calc(100vh - 435px)"
|
||||
:loading="loading"
|
||||
/>
|
||||
</NTabPane>
|
||||
<NTabPane name="outcome" :tab="formattedLabel('Выписанные', dischargedHistories.length)">
|
||||
@@ -143,6 +179,7 @@ const formattedLabel = (word, count) => {
|
||||
table-layout="fixed"
|
||||
max-height="calc(100vh - 435px)"
|
||||
min-height="calc(100vh - 435px)"
|
||||
:loading="loading"
|
||||
/>
|
||||
</NTabPane>
|
||||
<NTabPane name="dead" :tab="formattedLabel('Умершие', deceasedHistories.length)">
|
||||
@@ -151,6 +188,7 @@ const formattedLabel = (word, count) => {
|
||||
table-layout="fixed"
|
||||
max-height="calc(100vh - 435px)"
|
||||
min-height="calc(100vh - 435px)"
|
||||
:loading="loading"
|
||||
/>
|
||||
</NTabPane>
|
||||
<NTabPane name="transfer" :tab="formattedLabel('Переведенные', transferredHistories.length)">
|
||||
@@ -159,11 +197,12 @@ const formattedLabel = (word, count) => {
|
||||
table-layout="fixed"
|
||||
max-height="calc(100vh - 435px)"
|
||||
min-height="calc(100vh - 435px)"
|
||||
:loading="loading"
|
||||
/>
|
||||
</NTabPane>
|
||||
</NTabs>
|
||||
</AppPanel>
|
||||
<NButton secondary size="large" @click="submit">
|
||||
<NButton secondary size="large" @click="submit" :loading="loading">
|
||||
Сохранить отчет
|
||||
</NButton>
|
||||
</AppContainer>
|
||||
|
||||
@@ -6,6 +6,7 @@ import * as Sentry from "@sentry/vue";
|
||||
import {startGlobalLoading, stopGlobalLoading} from "./Composables/useGlobalLoading.js";
|
||||
import './bootstrap';
|
||||
import '../css/app.css';
|
||||
import {NConfigProvider, NDialogProvider, NMessageProvider, ruRU, dateRuRU, darkTheme} from "naive-ui";
|
||||
|
||||
router.on('start', () => {
|
||||
startGlobalLoading()
|
||||
@@ -23,6 +24,21 @@ router.on('exception', () => {
|
||||
stopGlobalLoading()
|
||||
})
|
||||
|
||||
const themeOverrides = {
|
||||
Modal: {
|
||||
peers: {
|
||||
Dialog: {
|
||||
borderRadius: '8px'
|
||||
},
|
||||
Card: {
|
||||
borderRadius: '8px'
|
||||
},
|
||||
}
|
||||
},
|
||||
Dialog: {
|
||||
borderRadius: '8px'
|
||||
},
|
||||
}
|
||||
|
||||
createInertiaApp({
|
||||
id: 'onboard',
|
||||
@@ -31,8 +47,19 @@ createInertiaApp({
|
||||
return pages[`./Pages/${name}.vue`]
|
||||
},
|
||||
setup({el, App, props, plugin}) {
|
||||
const vueApp = createApp({
|
||||
render: () => h(App, props)
|
||||
const vueApp = createApp({
|
||||
render: () => h(NConfigProvider, {
|
||||
theme: darkTheme,
|
||||
themeOverrides: themeOverrides,
|
||||
locale: ruRU,
|
||||
dateLocale: dateRuRU
|
||||
}, {
|
||||
default: () => h(NDialogProvider, {}, {
|
||||
default: () => h(NMessageProvider, {}, {
|
||||
default: () => h(App, props)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
const pinia = createPinia()
|
||||
|
||||
Reference in New Issue
Block a user