formatted
CI/CD / test_and_check_app (push) Successful in 3m53s
CI/CD / Publish immutable image (push) Successful in 1m33s

This commit is contained in:
2026-09-08 14:24:04 +02:00
parent bd7be4e41e
commit 1d8fff1d51
20 changed files with 395 additions and 151 deletions
+40 -12
View File
@@ -15,7 +15,10 @@ import {
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import AppLayout from '@/layouts/AppLayout.vue';
import { index as projectsIndex, show as projectShow } from '@/routes/projects/index';
import {
index as projectsIndex,
show as projectShow,
} from '@/routes/projects/index';
import {
create as projectTemplateCreate,
store as projectTemplateStore,
@@ -40,7 +43,9 @@ const breadcrumbs: BreadcrumbItem[] = [
];
const form = useForm({
copy_areas: props.copyAreaOptions.map((copyAreaOption) => copyAreaOption.value),
copy_areas: props.copyAreaOptions.map(
(copyAreaOption) => copyAreaOption.value,
),
name: `${props.project.name} template`,
slug: `${props.project.key.toLowerCase()}-template`,
});
@@ -48,7 +53,9 @@ const form = useForm({
const copyAreasError = computed(() => {
return (
form.errors.copy_areas ??
Object.entries(form.errors).find(([key]) => key.startsWith('copy_areas.'))?.[1] ??
Object.entries(form.errors).find(([key]) =>
key.startsWith('copy_areas.'),
)?.[1] ??
''
);
});
@@ -66,7 +73,9 @@ const submit = (): void => {
<div class="mx-auto flex w-full max-w-3xl flex-1 flex-col gap-6 p-4">
<div class="space-y-3">
<Badge variant="outline" class="px-3 py-1">{{ project.key }}</Badge>
<Badge variant="outline" class="px-3 py-1">{{
project.key
}}</Badge>
<Heading
:title="`Save ${project.name} as new template`"
description="Capture reusable project configuration without copying operational ticket data."
@@ -77,7 +86,8 @@ const submit = (): void => {
<CardHeader>
<CardTitle>Template details</CardTitle>
<CardDescription>
Pick the configuration groups that should be reusable in future projects.
Pick the configuration groups that should be reusable in
future projects.
</CardDescription>
</CardHeader>
@@ -85,15 +95,26 @@ const submit = (): void => {
<form class="space-y-6" @submit.prevent="submit">
<div class="grid gap-2">
<Label for="name">Template name</Label>
<Input id="name" v-model="form.name" required placeholder="Foundation template" />
<Input
id="name"
v-model="form.name"
required
placeholder="Foundation template"
/>
<InputError :message="form.errors.name" />
</div>
<div class="grid gap-2">
<Label for="slug">Template slug</Label>
<Input id="slug" v-model="form.slug" required placeholder="foundation-template" />
<Input
id="slug"
v-model="form.slug"
required
placeholder="foundation-template"
/>
<p class="text-muted-foreground text-sm">
Slugs are normalized automatically and used to identify reusable templates.
Slugs are normalized automatically and used to
identify reusable templates.
</p>
<InputError :message="form.errors.slug" />
</div>
@@ -102,7 +123,8 @@ const submit = (): void => {
<div>
<Label>Configuration groups</Label>
<p class="text-muted-foreground text-sm">
Only the selected groups will be stored in the template.
Only the selected groups will be stored in
the template.
</p>
</div>
@@ -119,8 +141,12 @@ const submit = (): void => {
class="mt-1"
/>
<div class="space-y-1">
<div class="font-medium">{{ copyAreaOption.label }}</div>
<p class="text-muted-foreground text-sm">
<div class="font-medium">
{{ copyAreaOption.label }}
</div>
<p
class="text-muted-foreground text-sm"
>
{{ copyAreaOption.description }}
</p>
</div>
@@ -135,7 +161,9 @@ const submit = (): void => {
</Button>
<Button as-child variant="outline">
<Link :href="projectShow(project.id)">Cancel</Link>
<Link :href="projectShow(project.id)"
>Cancel</Link
>
</Button>
</div>
</form>