Implement ticket statuses

This commit is contained in:
2026-04-14 03:09:12 +02:00
parent 2dc12c5d60
commit 8f4a8276ac
40 changed files with 1602 additions and 100 deletions
+253 -4
View File
@@ -93,20 +93,135 @@ const breadcrumbs: BreadcrumbItem[] = [
<CardHeader>
<CardTitle>Workflow model</CardTitle>
<CardDescription>
Backlog is always the intake queue and stays outside the
normal board column list.
Backlog is always the intake queue; board columns group
the statuses that appear on the board.
</CardDescription>
</CardHeader>
<CardContent class="flex flex-wrap gap-3">
<Badge class="px-3 py-1">Backlog</Badge>
<Badge
v-for="ticketStatus in backlogTicketStatuses"
:key="ticketStatus.id"
variant="outline"
class="px-3 py-1"
>
{{ ticketStatus.name }}
</Badge>
<p class="text-muted-foreground text-sm">
Tickets will later be valid only in backlog or in one of
the ordered columns below.
Tickets move between statuses; backlog statuses are not
included in a board column.
</p>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Backlog statuses</CardTitle>
<CardDescription>
New backlog tickets choose one of these statuses.
</CardDescription>
</CardHeader>
<CardContent class="space-y-4">
<div
v-for="ticketStatus in backlogTicketStatuses"
:key="ticketStatus.id"
class="border-border rounded-lg border p-4"
>
<Form
v-bind="
ProjectBoardSettingsController.updateStatus.form(
[project.id, ticketStatus.id],
)
"
class="grid gap-4 md:grid-cols-[minmax(0,1fr)_auto]"
v-slot="{ errors, processing }"
>
<div class="grid gap-2">
<Label
:for="`backlog-status-${ticketStatus.id}`"
>
Status name
</Label>
<Input
:id="`backlog-status-${ticketStatus.id}`"
name="name"
:default-value="ticketStatus.name"
required
/>
<InputError :message="errors.name" />
</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.destroyStatus.form(
[project.id, ticketStatus.id],
)
"
v-slot="{ errors, processing }"
>
<InputError
:message="errors.ticket_status_id"
class="mb-2"
/>
<Button
type="submit"
variant="destructive"
:disabled="
processing ||
backlogTicketStatuses.length <= 1
"
>
Delete
</Button>
</Form>
</div>
</div>
<Form
v-bind="
ProjectBoardSettingsController.storeStatus.form(
project.id,
)
"
class="grid gap-4 md:grid-cols-[minmax(0,1fr)_auto]"
v-slot="{ errors, processing }"
>
<div class="grid gap-2">
<Label for="backlog-status-name">
New backlog status
</Label>
<Input
id="backlog-status-name"
name="name"
placeholder="Ready"
required
/>
<InputError :message="errors.name" />
</div>
<div class="flex items-end">
<Button type="submit" :disabled="processing">
Add status
</Button>
</div>
</Form>
</CardContent>
</Card>
<div class="grid gap-6 xl:grid-cols-[22rem_minmax(0,1fr)]">
<Card>
<CardHeader>
@@ -239,6 +354,140 @@ const breadcrumbs: BreadcrumbItem[] = [
</Button>
</Form>
</div>
<div class="border-border mt-4 border-t pt-4">
<div class="mb-3">
<p class="text-sm font-medium">
Ticket statuses
</p>
<p class="text-muted-foreground text-sm">
Moving into this column requires a
specific status.
</p>
</div>
<div class="space-y-3">
<div
v-for="ticketStatus in column.ticket_statuses ??
[]"
:key="ticketStatus.id"
class="border-border rounded-lg border p-3"
>
<Form
v-bind="
ProjectBoardSettingsController.updateStatus.form(
[
project.id,
ticketStatus.id,
],
)
"
class="grid gap-4 md:grid-cols-[minmax(0,1fr)_auto]"
v-slot="{ errors, processing }"
>
<div class="grid gap-2">
<Label
:for="`column-status-${ticketStatus.id}`"
>
Status name
</Label>
<Input
:id="`column-status-${ticketStatus.id}`"
name="name"
:default-value="
ticketStatus.name
"
required
/>
<InputError
:message="errors.name"
/>
</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.destroyStatus.form(
[
project.id,
ticketStatus.id,
],
)
"
v-slot="{ errors, processing }"
>
<InputError
:message="
errors.ticket_status_id
"
class="mb-2"
/>
<Button
type="submit"
variant="destructive"
:disabled="
processing ||
(column.ticket_statuses
?.length ?? 0) <= 1
"
>
Delete
</Button>
</Form>
</div>
</div>
</div>
<Form
v-bind="
ProjectBoardSettingsController.storeStatus.form(
project.id,
)
"
class="mt-4 grid gap-4 md:grid-cols-[minmax(0,1fr)_auto]"
v-slot="{ errors, processing }"
>
<input
type="hidden"
name="board_column_id"
:value="column.id"
/>
<div class="grid gap-2">
<Label
:for="`new-column-status-${column.id}`"
>
New status
</Label>
<Input
:id="`new-column-status-${column.id}`"
name="name"
placeholder="Ready for QA"
required
/>
<InputError :message="errors.name" />
</div>
<div class="flex items-end">
<Button
type="submit"
:disabled="processing"
>
Add status
</Button>
</div>
</Form>
</div>
</div>
</CardContent>
</Card>