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

136 lines
5.1 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 {
NFlex, NButton, NDataTable, NTag,
NText, NIcon, NAlert, NPopconfirm, NEmpty,
} from 'naive-ui'
import {
TbReportAnalytics, TbPlus, TbPencil, TbTrash, 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 { Link, router, usePage } from '@inertiajs/vue3'
import { computed, h } from 'vue'
const props = defineProps({
templates: { type: Array, default: () => [] },
})
const page = usePage()
const flash = computed(() => page.props.flash ?? {})
const visibilityLabels = {
'report.view': 'Дежурный врач',
'nurse.report.view': 'Старшая медсестра',
}
const removeTemplate = (template) => {
router.delete(`/admin/report-templates/${template.id}`, { preserveScroll: true })
}
const columns = computed(() => [
{
key: 'name',
title: 'Название',
render: (row) => h(NFlex, { vertical: true, size: 2 }, () => [
h(NText, { style: 'font-weight: 500; font-size: 13px;' }, () => row.name),
h(NText, { depth: 3, style: 'font-size: 12px;' }, () => row.sourceLabels.join(', ')),
])
},
{
key: 'sectionsCount',
title: 'Секций',
width: 90,
render: (row) => h(NTag, { size: 'small', round: true, bordered: false }, () => `${row.sectionsCount}`)
},
{
key: 'requiredPermissions',
title: 'Видимость',
width: 240,
render: (row) => row.requiredPermissions.length
? h(NFlex, { size: 4 }, () => row.requiredPermissions.map((p) => h(NTag, { size: 'small', round: true, bordered: false, type: 'info', key: p }, () => visibilityLabels[p] ?? p)))
: h(NTag, { size: 'small', round: true, bordered: false }, () => 'Все с доступом к отчётам')
},
{
key: 'creator',
title: 'Автор',
width: 180,
render: (row) => row.creator ?? '—'
},
{
key: 'actions',
title: '',
width: 90,
align: 'center',
render: (row) => h(NFlex, { justify: 'center', size: 4 }, () => [
h(NButton, {
text: true, size: 'small', tag: Link,
href: `/admin/report-templates/${row.id}`,
title: 'Редактировать',
}, { icon: () => h(NIcon, { size: 18 }, () => h(TbPencil)) }),
h(NPopconfirm, {
onPositiveClick: () => removeTemplate(row),
}, {
trigger: () => h(NButton, {
text: true, size: 'small', title: 'Удалить',
}, { icon: () => h(NIcon, { size: 18 }, () => h(TbTrash)) }),
default: () => 'Удалить шаблон?',
}),
])
},
])
</script>
<template>
<AppLayout>
<AppContainer>
<NAlert v-if="flash.success" type="success" closable style="margin-bottom: 4px;">
{{ flash.success }}
</NAlert>
<PageBanner
title="Шаблоны отчётов"
:icon="TbReportAnalytics"
:breadcrumbs="[{ label: 'Администратор', href: '/admin', icon: TbLayoutDashboard, tag: Link }]"
>
<template #meta>
<NText depth="3" style="font-size: 13px;">
{{ templates.length ? `${templates.length} ${templates.length === 1 ? 'шаблон' : 'шаблонов'}` : 'Конструктор пользовательских отчётов' }}
</NText>
</template>
<template #actions>
<NButton type="primary" :tag="Link" href="/admin/report-templates/new">
<template #icon><NIcon><TbPlus /></NIcon></template>
Новый шаблон
</NButton>
</template>
</PageBanner>
<SectionCard :icon="TbReportAnalytics" title="Шаблоны" no-padding style="margin-top: 4px;">
<NEmpty
v-if="!templates.length"
description="Пока нет ни одного шаблона"
style="padding: 32px 24px;"
>
<template #extra>
<NButton size="small" type="primary" :tag="Link" href="/admin/report-templates/new">
<template #icon><NIcon><TbPlus /></NIcon></template>
Создать первый шаблон
</NButton>
</template>
</NEmpty>
<NDataTable
v-else
:columns="columns"
:data="templates"
:bordered="false"
size="small"
/>
</SectionCard>
</AppContainer>
</AppLayout>
</template>