107 lines
4.1 KiB
Vue
107 lines
4.1 KiB
Vue
<script setup>
|
|
import {
|
|
NButton, NFlex, NForm, NFormItem, NInput, NTransfer,
|
|
NText, NIcon, NAlert,
|
|
} from 'naive-ui'
|
|
import {
|
|
TbStack2, TbLayoutDashboard, TbChartBar, TbAdjustments,
|
|
} 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({
|
|
group: { type: Object, default: null },
|
|
itemIds: { type: Array, default: () => [] },
|
|
allItems: { type: Array, default: () => [] },
|
|
})
|
|
|
|
const page = usePage()
|
|
const flash = computed(() => page.props.flash ?? {})
|
|
|
|
const isEdit = computed(() => !!props.group)
|
|
|
|
const transferOptions = computed(() => props.allItems.map(i => ({
|
|
label: i.name,
|
|
value: i.metrika_item_id,
|
|
})))
|
|
|
|
const form = useForm({
|
|
name: props.group?.name ?? '',
|
|
description: props.group?.description ?? '',
|
|
items: [...props.itemIds],
|
|
})
|
|
|
|
const submit = () => {
|
|
if (isEdit.value) {
|
|
form.put(`/admin/metrics/groups/${props.group.id}`)
|
|
} else {
|
|
form.post('/admin/metrics/groups/new')
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<AppLayout>
|
|
<AppContainer>
|
|
|
|
<NAlert v-if="flash.success" type="success" closable style="margin-bottom: 4px;">
|
|
{{ flash.success }}
|
|
</NAlert>
|
|
|
|
<PageBanner
|
|
:title="isEdit ? group.name : 'Новая группа'"
|
|
:icon="TbStack2"
|
|
:color="isEdit ? null : 'default'"
|
|
:breadcrumbs="[
|
|
{ label: 'Администратор', href: '/admin', icon: TbLayoutDashboard, tag: Link },
|
|
{ label: 'Метрики', href: '/admin/metrics', icon: TbChartBar, tag: Link },
|
|
]"
|
|
>
|
|
<template #meta>
|
|
<NText depth="3" style="font-size: 13px;">
|
|
{{ isEdit ? 'Редактирование группы показателей' : 'Создание новой группы' }}
|
|
</NText>
|
|
</template>
|
|
<template #actions>
|
|
<NButton :tag="Link" href="/admin/metrics">Отмена</NButton>
|
|
<NButton type="primary" :loading="form.processing" @click="submit">
|
|
{{ isEdit ? 'Сохранить' : 'Создать группу' }}
|
|
</NButton>
|
|
</template>
|
|
</PageBanner>
|
|
|
|
<SectionCard title="Основные данные" :icon="TbStack2">
|
|
<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" style="margin-bottom: 0;">
|
|
<NInput v-model:value="form.description" type="textarea" placeholder="Краткое описание группы" :rows="3" />
|
|
</NFormItem>
|
|
</NForm>
|
|
</SectionCard>
|
|
|
|
<SectionCard title="Показатели" :icon="TbAdjustments" no-padding>
|
|
<NTransfer
|
|
v-model:value="form.items"
|
|
:options="transferOptions"
|
|
source-filterable
|
|
target-filterable
|
|
source-title="Доступные показатели"
|
|
target-title="Показатели группы"
|
|
style="height: calc(100vh - 520px); min-height: 200px;"
|
|
/>
|
|
</SectionCard>
|
|
|
|
</AppContainer>
|
|
</AppLayout>
|
|
</template>
|
|
|
|
<style scoped>
|
|
:deep(.n-transfer) { border: none !important; border-radius: 0 !important; }
|
|
</style>
|