import { type } from '@ngrx/signals'; import { eventGroup } from '@ngrx/signals/events'; import { Activity, ChangeStatusInput, Comment, CommentChanged, Issue, IssueSummary, LinkIssuesInput, UpdateIssueInput, ReviewVerdict, } from '@task-stream/web/tracker/domain'; export const issuePageEvents = eventGroup({ source: 'Issue Page', events: { opened: type<{ idOrKey: string }>(), /** `undoing`: it is the «Deshacer» of a change, which offers none. */ statusChangeRequested: type(), assignRequested: type<{ issueId: string; assigneeId: string | null; undoing?: boolean; }>(), updateRequested: type(), linkRequested: type(), /** Relate by the other ticket's key (e.g. BE-3), resolved to its id first. */ linkByKeyRequested: type<{ issueId: string; type: LinkIssuesInput['type']; targetKey: string; }>(), unlinkRequested: type(), sprintChangeRequested: type<{ issueId: string; sprintId: string | null; }>(), releaseChangeRequested: type<{ issueId: string; releaseId: string | null; }>(), commentAddRequested: type<{ issueId: string; body: string; /** Uploaded under the new comment once it exists. */ files?: File[]; /** Comment it answers (one level of replies). */ replyTo?: string | null; /** A quick poll's options. */ poll?: string[] | null; }>(), pollVoteRequested: type<{ commentId: string; option: number | null }>(), pollCloseRequested: type<{ commentId: string; decide: boolean }>(), watchRequested: type<{ issueId: string; watching: boolean }>(), pinRequested: type<{ issueId: string; pinned: boolean }>(), followTreeRequested: type<{ issueId: string; on: boolean }>(), reviewRequested: type<{ issueId: string; reviewerId: string; note: string | null; }>(), reviewAnswerRequested: type<{ issueId: string; reviewId: string; verdict: ReviewVerdict; answer: string | null; }>(), reviewCancelRequested: type<{ issueId: string; reviewId: string }>(), reminderRequested: type<{ issueId: string; /** null: drop it. */ at: string | null; note: string | null; }>(), trashRequested: type<{ issueId: string; trashed: boolean; undoing?: boolean; }>(), /** Place the ticket under another one by its key (e.g. WEB-3); null: out. */ parentRequested: type<{ issueId: string; parentKey: string | null }>(), subtaskCreateRequested: type<{ projectId: string; parentId: string; type: string; title: string; }>(), checklistAddRequested: type<{ issueId: string; text: string }>(), checklistUpdateRequested: type<{ issueId: string; itemId: string; changes: { text?: string; done?: boolean }; }>(), checklistRemoveRequested: type<{ issueId: string; itemId: string }>(), attachRequested: type<{ issueId: string; files: File[]; commentId?: string | null; }>(), attachmentRemoveRequested: type<{ issueId: string; attachmentId: string; }>(), commentEditRequested: type<{ commentId: string; body: string }>(), reactRequested: type<{ commentId: string; emoji: string; on: boolean }>(), decisionRequested: type<{ commentId: string; on: boolean }>(), threadResolveRequested: type<{ commentId: string; resolved: boolean; conclusion: string | null; }>(), commentToIssueRequested: type<{ commentId: string; title: string; type: string; asSubtask: boolean; }>(), voteRequested: type<{ issueId: string; on: boolean }>(), /** An image pasted into a text was uploaded (it joins the ticket's files). */ imagePasted: type<{ issueId: string }>(), commentDeleteRequested: type<{ commentId: string }>(), }, }); export const issueApiEvents = eventGroup({ source: 'Issue API', events: { loaded: type(), loadFailed: type(), commentsLoaded: type(), historyLoaded: type(), childrenLoaded: type(), commandSucceeded: type(), /** A checklist step was saved (no toast for something so small). */ checklistSaved: type(), /** Changed, and «Deshacer» offered instead of a plain toast. */ undoOffered: type(), commandFailed: type(), }, }); export const issueRealtimeEvents = eventGroup({ source: 'Issue Realtime', events: { /** Something about this ticket changed: refetch it. */ issueTouched: type<{ issueId: string; version: number }>(), /** A ticket under this one changed, arrived or left: reload them. */ childrenTouched: type<{ issueId: string }>(), commentChanged: type(), }, });