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
+72 -23
View File
@@ -33,7 +33,8 @@ const returnHref =
props.source === 'board'
? boardIndex(props.project.id)
: backlogIndex(props.project.id);
const returnLabel = props.source === 'board' ? 'Back to board' : 'Back to backlog';
const returnLabel =
props.source === 'board' ? 'Back to board' : 'Back to backlog';
const breadcrumbs: BreadcrumbItem[] = [
{
@@ -64,7 +65,9 @@ const hasTicketMetadata =
const acceptanceCriteriaChecklist = ref('');
const form = useForm({
acceptance_criteria: buildAcceptanceCriteria(acceptanceCriteriaChecklist.value),
acceptance_criteria: buildAcceptanceCriteria(
acceptanceCriteriaChecklist.value,
),
assignee_user_id: '',
description: '',
parent_ticket_id: '',
@@ -92,7 +95,9 @@ const acceptanceCriteriaError = computed(() => {
});
const submit = (): void => {
form.acceptance_criteria = buildAcceptanceCriteria(acceptanceCriteriaChecklist.value);
form.acceptance_criteria = buildAcceptanceCriteria(
acceptanceCriteriaChecklist.value,
);
form.submit(ProjectTicketController.store({ project: props.project.id }), {
preserveScroll: true,
@@ -173,7 +178,9 @@ const ticketStatusLabel = (ticketStatus: TicketStatusModel): string => {
<InputError :message="form.errors.title" />
</div>
<div class="grid gap-6 lg:grid-cols-[minmax(0,1fr)_20rem]">
<div
class="grid gap-6 lg:grid-cols-[minmax(0,1fr)_20rem]"
>
<div class="grid gap-6">
<div class="grid gap-2">
<Label for="description">Description</Label>
@@ -185,30 +192,46 @@ const ticketStatusLabel = (ticketStatus: TicketStatusModel): string => {
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-60"
placeholder="Describe the expected behavior and relevant context."
/>
<InputError :message="form.errors.description" />
<InputError
:message="form.errors.description"
/>
</div>
<div class="grid gap-4">
<div class="grid gap-2">
<Label for="acceptance_criteria_checklist">
<Label
for="acceptance_criteria_checklist"
>
Acceptance criteria checklist
</Label>
<textarea
id="acceptance_criteria_checklist"
v-model="acceptanceCriteriaChecklist"
v-model="
acceptanceCriteriaChecklist
"
rows="6"
:disabled="form.processing"
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-60"
placeholder="[ ] User can sign in&#10; [x] Validation is shown for invalid credentials"
/>
<p class="text-muted-foreground text-xs">
Use <code>[ ]</code> / <code>[x]</code> for checklist items. Indent with two spaces for nested steps.
<p
class="text-muted-foreground text-xs"
>
Use <code>[ ]</code> /
<code>[x]</code> for checklist
items. Indent with two spaces for
nested steps.
</p>
<InputError :message="acceptanceCriteriaError" />
<InputError
:message="acceptanceCriteriaError"
/>
</div>
<div
v-if="acceptanceCriteriaPreviewItems.length > 0"
v-if="
acceptanceCriteriaPreviewItems.length >
0
"
class="border-border rounded-xl border p-4 text-sm"
>
<p class="mb-3 font-medium">
@@ -216,14 +239,18 @@ const ticketStatusLabel = (ticketStatus: TicketStatusModel): string => {
</p>
<ul class="space-y-2">
<li
v-for="(item, index) in acceptanceCriteriaPreviewItems"
v-for="(
item, index
) in acceptanceCriteriaPreviewItems"
:key="index"
:style="{
marginLeft: `${item.indent * 1.25}rem`,
}"
class="flex items-start gap-2"
>
<span class="mt-0.5">{{ item.checked ? '☑' : '☐' }}</span>
<span class="mt-0.5">{{
item.checked ? '☑' : '☐'
}}</span>
<span>{{ item.text }}</span>
</li>
</ul>
@@ -248,7 +275,9 @@ const ticketStatusLabel = (ticketStatus: TicketStatusModel): string => {
{{ ticketType.name }}
</option>
</select>
<InputError :message="form.errors.ticket_type_id" />
<InputError
:message="form.errors.ticket_type_id"
/>
</div>
<div class="grid gap-2">
@@ -269,7 +298,11 @@ const ticketStatusLabel = (ticketStatus: TicketStatusModel): string => {
{{ ticketPriority.name }}
</option>
</select>
<InputError :message="form.errors.ticket_priority_id" />
<InputError
:message="
form.errors.ticket_priority_id
"
/>
</div>
<div class="grid gap-2">
@@ -285,10 +318,14 @@ const ticketStatusLabel = (ticketStatus: TicketStatusModel): string => {
:key="ticketStatus.id"
:value="String(ticketStatus.id)"
>
{{ ticketStatusLabel(ticketStatus) }}
{{
ticketStatusLabel(ticketStatus)
}}
</option>
</select>
<InputError :message="form.errors.ticket_status_id" />
<InputError
:message="form.errors.ticket_status_id"
/>
</div>
<div class="grid gap-2">
@@ -310,7 +347,9 @@ const ticketStatusLabel = (ticketStatus: TicketStatusModel): string => {
{{ user.name }}
</option>
</select>
<InputError :message="form.errors.assignee_user_id" />
<InputError
:message="form.errors.assignee_user_id"
/>
</div>
<div class="grid gap-2">
@@ -323,16 +362,24 @@ const ticketStatusLabel = (ticketStatus: TicketStatusModel): string => {
:disabled="form.processing"
class="border-input bg-background shadow-xs focus-visible:border-ring focus-visible:ring-ring/50 rounded-md border px-3 py-2 text-sm outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-60"
>
<option value="">No parent ticket</option>
<option value="">
No parent ticket
</option>
<option
v-for="parentTicketOption in parentTicketOptions"
:key="parentTicketOption.id"
:value="String(parentTicketOption.id)"
:value="
String(parentTicketOption.id)
"
>
{{ `${parentTicketOption.ticket_key} - ${parentTicketOption.title}` }}
{{
`${parentTicketOption.ticket_key} - ${parentTicketOption.title}`
}}
</option>
</select>
<InputError :message="form.errors.parent_ticket_id" />
<InputError
:message="form.errors.parent_ticket_id"
/>
</div>
<div
@@ -349,7 +396,9 @@ const ticketStatusLabel = (ticketStatus: TicketStatusModel): string => {
step="1"
:disabled="form.processing"
/>
<InputError :message="form.errors.story_points" />
<InputError
:message="form.errors.story_points"
/>
</div>
</div>
</div>