feat: mentions and following tickets
Mention project members in comments with @, follow and unfollow tickets, and get told when something changes on the tickets you follow. Commenting on a ticket starts following it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -183,6 +183,25 @@ export class IssueResolver {
|
||||
);
|
||||
}
|
||||
|
||||
@Mutation(() => CommandResultGql, {
|
||||
description:
|
||||
'Follow a ticket: be told when it moves, is reassigned or gets a comment',
|
||||
})
|
||||
watchIssue(
|
||||
@CurrentUser() me: User,
|
||||
@Args('issueId', { type: () => ID }) issueId: string,
|
||||
) {
|
||||
return this.issuesService.watch(me.id, issueId, true);
|
||||
}
|
||||
|
||||
@Mutation(() => CommandResultGql, { description: 'Stop following a ticket' })
|
||||
unwatchIssue(
|
||||
@CurrentUser() me: User,
|
||||
@Args('issueId', { type: () => ID }) issueId: string,
|
||||
) {
|
||||
return this.issuesService.watch(me.id, issueId, false);
|
||||
}
|
||||
|
||||
@Mutation(() => CommandResultGql, {
|
||||
description:
|
||||
'Remove a file from a ticket (whoever uploaded it, or an owner/admin). Upload with the REST API.',
|
||||
|
||||
@@ -143,6 +143,8 @@ export class IssueGql {
|
||||
@Field(() => String, { nullable: true }) dueDate!: string | null;
|
||||
@Field(() => [IssueLinkGql]) links!: IssueLinkGql[];
|
||||
@Field(() => [AttachmentGql]) attachments!: AttachmentGql[];
|
||||
@Field(() => [UserRefGql], { description: 'People following the ticket' })
|
||||
watchers!: UserRefGql[];
|
||||
@Field(() => Int) commentCount!: number;
|
||||
@Field() createdAt!: string;
|
||||
@Field() updatedAt!: string;
|
||||
|
||||
@@ -159,6 +159,8 @@ export class IssueDto {
|
||||
dueDate!: string | null;
|
||||
@ApiProperty({ type: [IssueLinkDto] }) links!: IssueLinkDto[];
|
||||
@ApiProperty({ type: [AttachmentDto] }) attachments!: AttachmentDto[];
|
||||
@ApiProperty({ type: [UserRefDto], description: 'People following it' })
|
||||
watchers!: UserRefDto[];
|
||||
@ApiProperty() commentCount!: number;
|
||||
@ApiProperty({ format: 'date-time' }) createdAt!: string;
|
||||
@ApiProperty({ format: 'date-time' }) updatedAt!: string;
|
||||
|
||||
@@ -77,6 +77,36 @@ export class IssuesController {
|
||||
private readonly refs: Refs,
|
||||
) {}
|
||||
|
||||
@Put('issues/:issue/watch')
|
||||
@ISSUE
|
||||
@ApiOperation({
|
||||
summary: 'Follow a ticket (members, viewers included)',
|
||||
description:
|
||||
'Followers are told when it moves, is reassigned or gets a comment. Commenting follows it too.',
|
||||
})
|
||||
@ApiOkResponse({ type: CommandResultDto })
|
||||
@ApiCommandErrors()
|
||||
async watch(@CurrentUser() me: User, @Param('issue') issue: string) {
|
||||
return this.issues.watch(
|
||||
me.id,
|
||||
await this.refs.issueId(me.id, issue),
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
@Delete('issues/:issue/watch')
|
||||
@ISSUE
|
||||
@ApiOperation({ summary: 'Stop following a ticket' })
|
||||
@ApiOkResponse({ type: CommandResultDto })
|
||||
@ApiCommandErrors()
|
||||
async unwatch(@CurrentUser() me: User, @Param('issue') issue: string) {
|
||||
return this.issues.watch(
|
||||
me.id,
|
||||
await this.refs.issueId(me.id, issue),
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
@Get('me/issues')
|
||||
@ApiOperation({
|
||||
summary: 'My work: tickets across all my projects',
|
||||
|
||||
Reference in New Issue
Block a user