Files
KanbanGit/resources/js/pages/projects/settings/Board.vue
T

238 lines
9.6 KiB
Vue

<script setup lang="ts">
import { Form, Head, Link } from '@inertiajs/vue3';
import ProjectBoardSettingsController from '@/actions/App/Http/Controllers/ProjectBoardSettingsController';
import Heading from '@/components/Heading.vue';
import InputError from '@/components/InputError.vue';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import AppLayout from '@/layouts/AppLayout.vue';
import { index, show } from '@/routes/projects';
import {
board as boardSettings,
repositories as repositorySettings,
} from '@/routes/projects/settings';
import type { BreadcrumbItem, ProjectBoardSettingsPageProps } from '@/types';
const props = defineProps<ProjectBoardSettingsPageProps>();
const breadcrumbs: BreadcrumbItem[] = [
{
title: 'Projects',
href: index(),
},
{
title: props.project.name,
href: show(props.project.id),
},
{
title: 'Board settings',
href: boardSettings(props.project.id),
},
];
</script>
<template>
<AppLayout :breadcrumbs="breadcrumbs">
<Head :title="`${project.name} board settings`" />
<div class="flex flex-1 flex-col gap-6 p-4">
<div
class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between"
>
<div class="space-y-3">
<Badge variant="outline" class="px-3 py-1">
{{ project.key }}
</Badge>
<Heading
:title="`${project.name} board settings`"
description="Configure the ordered board columns that define valid in-board ticket statuses for this project."
/>
</div>
<div class="flex flex-wrap gap-3">
<Button as-child variant="outline">
<Link :href="repositorySettings(project.id)">
Repository settings
</Link>
</Button>
<Button as-child variant="outline">
<Link :href="show(project.id)">Back to project</Link>
</Button>
</div>
</div>
<div
v-if="status"
class="rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-900 dark:border-emerald-900/70 dark:bg-emerald-950/40 dark:text-emerald-100"
>
{{ status }}
</div>
<Card>
<CardHeader>
<CardTitle>Workflow model</CardTitle>
<CardDescription>
Backlog is always the intake queue and stays outside the
normal board column list.
</CardDescription>
</CardHeader>
<CardContent class="flex flex-wrap gap-3">
<Badge class="px-3 py-1">Backlog</Badge>
<p class="text-sm text-muted-foreground">
Tickets will later be valid only in backlog or in one of
the ordered columns below.
</p>
</CardContent>
</Card>
<div class="grid gap-6 xl:grid-cols-[22rem_minmax(0,1fr)]">
<Card>
<CardHeader>
<CardTitle>Add column</CardTitle>
<CardDescription>
New columns extend the project-specific workflow and
are inserted at the end unless you specify a
position later.
</CardDescription>
</CardHeader>
<CardContent>
<Form
v-bind="
ProjectBoardSettingsController.store.form(
project.id,
)
"
class="space-y-4"
v-slot="{ errors, processing }"
>
<div class="grid gap-2">
<Label for="name">Column name</Label>
<Input
id="name"
name="name"
required
autofocus
placeholder="In Review"
/>
<InputError :message="errors.name" />
</div>
<Button type="submit" :disabled="processing">
Add column
</Button>
</Form>
</CardContent>
</Card>
<Card class="gap-0 overflow-hidden">
<CardHeader class="border-b">
<CardTitle>Board columns</CardTitle>
<CardDescription>
Rename columns or change the numeric position to
reorder the board from left to right.
</CardDescription>
</CardHeader>
<CardContent class="space-y-4 p-6">
<div
v-if="boardColumns.length === 0"
class="text-sm text-muted-foreground"
>
No board columns exist yet.
</div>
<div
v-for="column in boardColumns"
:key="column.id"
class="rounded-xl border border-border p-4"
>
<Form
v-bind="
ProjectBoardSettingsController.update.form([
project.id,
column.id,
])
"
class="grid gap-4 lg:grid-cols-[minmax(0,1fr)_8rem_auto_auto]"
v-slot="{ errors, processing }"
>
<div class="grid gap-2">
<Label :for="`column-name-${column.id}`">
Name
</Label>
<Input
:id="`column-name-${column.id}`"
name="name"
:default-value="column.name"
required
/>
<InputError :message="errors.name" />
</div>
<div class="grid gap-2">
<Label
:for="`column-position-${column.id}`"
>
Position
</Label>
<Input
:id="`column-position-${column.id}`"
name="position"
type="number"
min="1"
:max="boardColumns.length"
:default-value="column.position"
required
/>
<InputError :message="errors.position" />
</div>
<div class="flex items-end">
<Button
type="submit"
variant="outline"
:disabled="processing"
>
Save
</Button>
</div>
</Form>
<div class="mt-3 flex justify-end">
<Form
v-bind="
ProjectBoardSettingsController.destroy.form(
[project.id, column.id],
)
"
v-slot="{ processing }"
>
<Button
type="submit"
variant="destructive"
:disabled="processing"
>
Delete
</Button>
</Form>
</div>
</div>
</CardContent>
</Card>
</div>
</div>
</AppLayout>
</template>