Files
onboard/resources/js/Pages/Admin/Metrics/Item.vue
brusnitsyn 739168d427 Обновлен стартовый экран
Переписаны запросы для статистики, отчетов
Добавлена интеграция отчета сестры
2026-05-28 22:10:00 +09:00

161 lines
8.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 {
NButton, NFlex, NForm, NFormItem, NInput, NSelect,
NSwitch, NText, NIcon, NAlert, NGrid, NGi,
} from 'naive-ui'
import {
TbAdjustments, TbLayoutDashboard, TbChartBar,
} 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 { useForm, Link, usePage } from '@inertiajs/vue3'
import { computed } from 'vue'
const props = defineProps({
item: { type: Object, default: null },
})
const page = usePage()
const flash = computed(() => page.props.flash ?? {})
const isEdit = computed(() => !!props.item)
const dataTypeOptions = [
{ label: 'Целое число (integer)', value: 'integer' },
{ label: 'Дробное число (float)', value: 'float' },
{ label: 'Строка (string)', value: 'string' },
{ label: 'Текст (text)', value: 'text' },
{ label: 'Да / Нет (boolean)', value: 'boolean' },
{ label: 'Список значений (select)', value: 'select' },
]
const form = useForm({
name: props.item?.name ?? '',
description: props.item?.description ?? '',
data_type: props.item?.data_type ?? 'string',
is_active: props.item?.is_active ?? true,
is_required: props.item?.is_required ?? false,
default_value: props.item?.default_value ?? '',
placeholder: props.item?.placeholder ?? '',
})
const submit = () => {
if (isEdit.value) {
form.put(`/admin/metrics/items/${props.item.id}`)
} else {
form.post('/admin/metrics/items/new')
}
}
</script>
<template>
<AppLayout>
<AppContainer>
<NAlert v-if="flash.success" type="success" closable style="margin-bottom: 4px;">
{{ flash.success }}
</NAlert>
<PageBanner
:title="isEdit ? item.name : 'Новый показатель'"
:icon="TbAdjustments"
:color="isEdit ? null : 'default'"
:breadcrumbs="[
{ label: 'Администратор', href: '/admin', icon: TbLayoutDashboard, tag: Link },
{ label: 'Метрики', href: '/admin/metrics', icon: TbChartBar, tag: Link },
]"
>
<template #meta>
<NFlex align="center" :size="8">
<NText depth="3" style="font-size: 13px;">
{{ isEdit ? 'Редактирование показателя' : 'Создание нового показателя' }}
</NText>
<template v-if="isEdit">
<span style="opacity: .3; font-size: 11px;"></span>
<NText depth="3" style="font-size: 12px; font-family: monospace;">{{ item.code }}</NText>
</template>
</NFlex>
</template>
<template #actions>
<NButton :tag="Link" href="/admin/metrics">Отмена</NButton>
<NButton type="primary" :loading="form.processing" @click="submit">
{{ isEdit ? 'Сохранить' : 'Создать показатель' }}
</NButton>
</template>
</PageBanner>
<NGrid :cols="2" :x-gap="16" :y-gap="16">
<NGi>
<SectionCard title="Основные данные" :icon="TbAdjustments">
<NForm label-placement="top">
<NFormItem label="Название" :feedback="form.errors.name" :validation-status="form.errors.name ? 'error' : undefined">
<NInput v-model:value="form.name" placeholder="Название показателя" />
</NFormItem>
<NFormItem label="Описание" :feedback="form.errors.description" :validation-status="form.errors.description ? 'error' : undefined">
<NInput v-model:value="form.description" type="textarea" placeholder="Краткое описание" :rows="3" />
</NFormItem>
<NFormItem label="Тип данных" :feedback="form.errors.data_type" :validation-status="form.errors.data_type ? 'error' : undefined" style="margin-bottom: 0;">
<NSelect v-model:value="form.data_type" :options="dataTypeOptions" />
</NFormItem>
</NForm>
</SectionCard>
</NGi>
<NGi>
<NFlex vertical :size="12">
<SectionCard
title="Параметры"
:icon="TbAdjustments"
:color="form.is_active ? 'success' : null"
>
<NForm label-placement="top">
<NFormItem label="Статус" style="margin-bottom: 12px;">
<NFlex align="center" justify="space-between" style="width: 100%;">
<div>
<NText style="font-size: 14px; display: block;">
{{ form.is_active ? 'Показатель активен' : 'Показатель отключён' }}
</NText>
<NText depth="3" style="font-size: 12px;">
{{ form.is_active ? 'Доступен для использования в группах' : 'Не отображается в группах' }}
</NText>
</div>
<NSwitch v-model:value="form.is_active" />
</NFlex>
</NFormItem>
<NFormItem label="Обязательный" style="margin-bottom: 0;">
<NFlex align="center" justify="space-between" style="width: 100%;">
<div>
<NText style="font-size: 14px; display: block;">
{{ form.is_required ? 'Обязательно для заполнения' : 'Необязательный' }}
</NText>
</div>
<NSwitch v-model:value="form.is_required" />
</NFlex>
</NFormItem>
</NForm>
</SectionCard>
<SectionCard title="Ввод" :icon="TbAdjustments">
<NForm label-placement="top">
<NFormItem label="Placeholder" :feedback="form.errors.placeholder" :validation-status="form.errors.placeholder ? 'error' : undefined">
<NInput v-model:value="form.placeholder" placeholder="Текст-подсказка в поле" />
</NFormItem>
<NFormItem label="Значение по умолчанию" :feedback="form.errors.default_value" :validation-status="form.errors.default_value ? 'error' : undefined" style="margin-bottom: 0;">
<NInput v-model:value="form.default_value" placeholder="Оставьте пустым если не нужно" />
</NFormItem>
</NForm>
</SectionCard>
</NFlex>
</NGi>
</NGrid>
</AppContainer>
</AppLayout>
</template>