feat: templates per ticket type

Each ticket type can carry a starting description and a checklist, edited
in the project settings. New tickets of that type get the description
when they come without one and always get the checklist; the new ticket
form says what the template will add.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 15:58:37 +02:00
parent 8994590b54
commit 5863d773be
23 changed files with 565 additions and 9 deletions

View File

@@ -548,6 +548,21 @@ export class StatusTransitionsInput {
to!: string[];
}
@InputType('IssueTemplateInput')
export class IssueTemplateInput {
@Field(() => String, { nullable: true })
@IsOptional()
@IsString()
@MaxLength(5000)
description?: string | null;
@Field(() => [String], { defaultValue: [] })
@IsArray()
@ArrayMaxSize(20)
@IsString({ each: true })
@MaxLength(300, { each: true })
checklist!: string[];
}
@InputType()
export class IssueTypeOptionInput {
@Field() @Matches(SETTING_ID) id!: string;
@@ -555,6 +570,11 @@ export class IssueTypeOptionInput {
@Field() @IsString() icon!: string;
@Field() @IsString() color!: string;
@Field({ defaultValue: false }) @IsBoolean() archived!: boolean;
@Field(() => IssueTemplateInput, { nullable: true })
@IsOptional()
@ValidateNested()
@Type(() => IssueTemplateInput)
template?: IssueTemplateInput | null;
}
@InputType()

View File

@@ -53,6 +53,19 @@ export class StatusTransitionsGql {
@Field(() => [String]) to!: string[];
}
@ObjectType('IssueTemplate', {
description: 'What a new ticket of the type starts with',
})
export class IssueTemplateGql {
@Field(() => String, {
nullable: true,
description: 'Used when the ticket comes without a description',
})
description!: string | null;
@Field(() => [String], { description: 'Steps added to every new ticket' })
checklist!: string[];
}
@ObjectType('IssueTypeOption')
export class IssueTypeOptionGql {
@Field() id!: string;
@@ -60,6 +73,8 @@ export class IssueTypeOptionGql {
@Field() icon!: string;
@Field() color!: string;
@Field() archived!: boolean;
@Field(() => IssueTemplateGql, { nullable: true })
template?: IssueTemplateGql | null;
}
@ObjectType('AreaOption')