ticket story poitns rework

This commit is contained in:
2026-04-13 00:10:09 +02:00
parent 041e79efda
commit b3f2cc3afd
17 changed files with 208 additions and 73 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ import { cn } from "@/lib/utils"
const props = defineProps<{
defaultValue?: string | number
modelValue?: string | number
modelValue?: string | number | null
class?: HTMLAttributes["class"]
}>()
+90 -64
View File
@@ -107,74 +107,100 @@ const hasTicketMetadata =
<InputError :message="errors.title" />
</div>
<div class="grid gap-2 md:grid-cols-2 md:gap-6">
<div class="grid gap-2">
<Label for="ticket_type_id">Type</Label>
<select
id="ticket_type_id"
name="ticket_type_id"
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]"
>
<option
v-for="ticketType in ticketTypes"
:key="ticketType.id"
:value="ticketType.id"
>
{{ ticketType.name }}
</option>
</select>
<InputError :message="errors.ticket_type_id" />
</div>
<div class="flex gap-2">
<div class="flex-4/5 grid gap-2 md:gap-6">
<div class="grid gap-2">
<Label for="description">Description</Label>
<textarea
id="description"
name="description"
rows="4"
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]"
placeholder="Describe the expected behavior and relevant context."
/>
<InputError :message="errors.description" />
</div>
<div class="grid gap-2">
<Label for="ticket_priority_id">
Priority
</Label>
<select
id="ticket_priority_id"
name="ticket_priority_id"
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]"
>
<option
v-for="ticketPriority in ticketPriorities"
:key="ticketPriority.id"
:value="ticketPriority.id"
<div class="grid gap-2">
<Label for="acceptance_criteria">
Acceptance criteria
</Label>
<textarea
id="acceptance_criteria"
name="acceptance_criteria"
rows="4"
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]"
placeholder="List the conditions that must be true before this ticket is done."
/>
<InputError
:message="errors.acceptance_criteria"
/>
</div>
</div>
<div
class="grid h-fit flex-1 gap-2 md:ml-4 md:gap-6"
>
<div class="grid gap-2">
<Label for="ticket_type_id">Type</Label>
<select
id="ticket_type_id"
name="ticket_type_id"
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]"
>
{{ ticketPriority.name }}
</option>
</select>
<InputError
:message="errors.ticket_priority_id"
/>
<option
v-for="ticketType in ticketTypes"
:key="ticketType.id"
:value="ticketType.id"
>
{{ ticketType.name }}
</option>
</select>
<InputError
:message="errors.ticket_type_id"
/>
</div>
<div class="grid gap-2">
<Label for="ticket_priority_id">
Priority
</Label>
<select
id="ticket_priority_id"
name="ticket_priority_id"
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]"
>
<option
v-for="ticketPriority in ticketPriorities"
:key="ticketPriority.id"
:value="ticketPriority.id"
>
{{ ticketPriority.name }}
</option>
</select>
<InputError
:message="errors.ticket_priority_id"
/>
</div>
<div
class="grid gap-2"
v-if="project.show_story_points"
>
<Label for="story_points">
Estimated story points
</Label>
<Input
id="story_points"
name="story_points"
type="number"
step="1"
/>
<InputError
:message="errors.story_points"
/>
</div>
</div>
</div>
<div class="grid gap-2">
<Label for="description">Description</Label>
<textarea
id="description"
name="description"
rows="4"
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]"
placeholder="Describe the expected behavior and relevant context."
/>
<InputError :message="errors.description" />
</div>
<div class="grid gap-2">
<Label for="acceptance_criteria">
Acceptance criteria
</Label>
<textarea
id="acceptance_criteria"
name="acceptance_criteria"
rows="4"
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]"
placeholder="List the conditions that must be true before this ticket is done."
/>
<InputError :message="errors.acceptance_criteria" />
</div>
<div class="flex items-center gap-3">
<Button type="submit" :disabled="processing">
Create ticket
+20
View File
@@ -117,6 +117,7 @@ const form = useForm({
ticket_priority_id: props.ticket.ticket_priority_id,
ticket_type_id: props.ticket.ticket_type_id,
title: props.ticket.title,
story_points: props.ticket.story_points,
});
const isCreateBranchDialogOpen = ref(false);
@@ -460,6 +461,25 @@ const formatDateTime = (value: string): string => {
</div>
</div>
<div
class="grid gap-2"
v-if="project.show_story_points"
>
<Label for="story_points">
Estimated story points
</Label>
<Input
id="story_points"
name="story_points"
v-model="form.story_points"
type="number"
step="1"
/>
<InputError
:message="form.errors.story_points"
/>
</div>
<div class="grid gap-2">
<Label for="parent_ticket_id">
Parent ticket
@@ -106,13 +106,43 @@ const breadcrumbs: BreadcrumbItem[] = [
</div>
<div class="grid gap-6 xl:grid-cols-2">
<Card class="gap-0 overflow-hidden">
<CardHeader class="border-b">
<CardTitle>General ticket settings</CardTitle>
</CardHeader>
<CardContent class="space-y-4 p-6">
<Form
v-bind="
ProjectTicketMetadataSettingsController.update.form(
project.id,
)
"
class="border-border space-y-4 rounded-xl border border-dashed p-4"
v-slot="{ errors, processing }"
>
<Label for="enable-story-points">
<Checkbox
id="enable-story-points"
name="show_story_points"
:default-value="project.show_story_points"
value="1"
/>
Enable story points for tickets
</Label>
<InputError :message="errors.show_story_points" />
<Button type="submit" :disabled="processing">
Save
</Button>
</Form>
</CardContent>
</Card>
<Card class="gap-0 overflow-hidden">
<CardHeader class="border-b">
<CardTitle>Ticket types</CardTitle>
<CardDescription>
Built-in Task and Parent always exist. Custom types
can be added and reordered per project.
</CardDescription>
</CardHeader>
<CardContent class="space-y-4 p-6">
@@ -139,7 +169,7 @@ const breadcrumbs: BreadcrumbItem[] = [
<Checkbox
id="type-is-parent"
name="is_parent"
required
value="1"
/>
Ticket type is can be a parent
</Label>
@@ -183,10 +213,10 @@ const breadcrumbs: BreadcrumbItem[] = [
<Checkbox
:id="`type-is-parent-${ticketType.id}}`"
name="is_parent"
required
:default-value="
ticketType.is_parent
"
value="1"
/>
Ticket type is can be a parent
</Label>
@@ -2,6 +2,7 @@ export type ProjectModel = {
id: number;
name: string;
key: string;
show_story_points: boolean;
created_at: string;
updated_at: string;
};
@@ -21,6 +21,7 @@ export type TicketModel = {
ticket_type_id: number;
title: string;
worklog_entries?: TicketWorklogEntryModel[];
story_points: number | null;
created_at: string;
updated_at: string;
};