161 lines
8.1 KiB
Vue
161 lines
8.1 KiB
Vue
<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>
|