Files
onboard/resources/js/Pages/Admin/ReportTemplates/Form.vue
2026-06-21 23:40:55 +09:00

136 lines
5.9 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 {
NButton, NFlex, NForm, NFormItem, NInput, NSelect,
NText, NDynamicInput, NAlert, NTag,
} from 'naive-ui'
import {
TbReportAnalytics, TbLayoutDashboard,
} from 'vue-icons-plus/tb'
import AppLayout from '../../../Layouts/AppLayout.vue'
import AppContainer from '../../../Components/AppContainer.vue'
import SectionCard from '../../../Components/SectionCard.vue'
import PageBanner from '../../../Components/PageBanner.vue'
import SectionEditor from './Components/SectionEditor.vue'
import { useForm, Link, usePage } from '@inertiajs/vue3'
import { computed } from 'vue'
const props = defineProps({
template: { type: Object, default: null },
sources: { type: Array, default: () => [] },
})
const page = usePage()
const flash = computed(() => page.props.flash ?? {})
const isEdit = computed(() => !!props.template)
const createSection = () => ({
source: props.sources[0]?.key ?? null,
title: '',
columns: [],
filters: [],
})
const form = useForm({
name: props.template?.name ?? '',
sections: props.template?.sections?.length ? props.template.sections : [createSection()],
required_permissions: props.template?.requiredPermissions ?? [],
})
const visibilityOptions = [
{ label: 'Дежурный врач', value: 'report.view' },
{ label: 'Старшая медсестра', value: 'nurse.report.view' },
]
const submit = () => {
if (isEdit.value) {
form.put(`/admin/report-templates/${props.template.id}`)
} else {
form.post('/admin/report-templates/new')
}
}
</script>
<template>
<AppLayout>
<AppContainer>
<NAlert v-if="flash.success" type="success" closable style="margin-bottom: 4px;">
{{ flash.success }}
</NAlert>
<PageBanner
:title="isEdit ? template.name : 'Новый шаблон отчёта'"
:icon="TbReportAnalytics"
:color="isEdit ? null : 'default'"
:breadcrumbs="[
{ label: 'Администратор', href: '/admin', icon: TbLayoutDashboard, tag: Link },
{ label: 'Шаблоны отчётов', href: '/admin/report-templates', icon: TbReportAnalytics, tag: Link },
]"
>
<template #meta>
<NText depth="3" style="font-size: 13px;">
{{ isEdit ? 'Редактирование шаблона' : 'Название → секции с данными → кому виден' }}
</NText>
</template>
<template #actions>
<NButton :tag="Link" href="/admin/report-templates">Отмена</NButton>
<NButton type="primary" :loading="form.processing" @click="submit">
{{ isEdit ? 'Сохранить' : 'Создать шаблон' }}
</NButton>
</template>
</PageBanner>
<NFlex vertical :size="16">
<SectionCard title="1 · Название и видимость">
<NFlex :size="16" :wrap="true">
<NForm label-placement="top" style="flex: 2; min-width: 280px;">
<NFormItem label="Название отчёта" :feedback="form.errors.name" :validation-status="form.errors.name ? 'error' : undefined" style="margin-bottom: 0;">
<NInput v-model:value="form.name" placeholder="Например: Сводка по отделению" />
</NFormItem>
</NForm>
<NForm label-placement="top" style="flex: 1; min-width: 280px;">
<NFormItem label="Кому виден отчёт" style="margin-bottom: 0;">
<NSelect
v-model:value="form.required_permissions"
:options="visibilityOptions"
multiple
placeholder="Все с доступом к отчётам"
clearable
/>
</NFormItem>
</NForm>
</NFlex>
<NText depth="3" style="font-size: 12px; display: block; margin-top: 4px;">
Ничего не выбрано отчёт увидят все, у кого есть доступ к разделу «Отчёты»
</NText>
</SectionCard>
<SectionCard title="2 · Секции с данными">
<NText v-if="form.errors.sections" type="error" style="display: block; margin-bottom: 8px; font-size: 12px;">
{{ form.errors.sections }}
</NText>
<NDynamicInput
v-model:value="form.sections"
:on-create="createSection"
item-style="margin-bottom: 16px; padding-bottom: 16px; border-bottom: 1px solid var(--n-border-color, rgba(255,255,255,.08));"
>
<template #default="{ index, value }">
<NFlex vertical :size="8" style="width: 100%;">
<NTag size="small" round :bordered="false">Секция {{ index + 1 }}</NTag>
<SectionEditor :section="value" :sources="sources" />
</NFlex>
</template>
<template #create-button-default>
Добавить секцию
</template>
</NDynamicInput>
</SectionCard>
</NFlex>
</AppContainer>
</AppLayout>
</template>