import { type } from '@ngrx/signals'; import { eventGroup } from '@ngrx/signals/events'; import { BoardColumn, BoardFilter, CommandResult, CreateIssueInput, IssueChanged, IssuePriority, SavedFilter, } from '@task-stream/web/tracker/domain'; /** What a card can change without opening the ticket. */ export type CardChange = | { priority: IssuePriority } | { storyPoints: number | null } | { assigneeId: string | null }; export const boardPageEvents = eventGroup({ source: 'Board Page', events: { opened: type(), filterChanged: type(), /** Optimistic: the card moves immediately and comes back if the API refuses. */ issueMoved: type<{ issueId: string; to: string; reason?: string | null; /** Where it was: «Deshacer» takes it back. */ from?: string; /** It is the «Deshacer» of a move: no undo for it. */ undoing?: boolean; }>(), issueCreateRequested: type(), /** From the card: priority, estimate or assignee (the live update repaints it). */ issueEditRequested: type<{ issueId: string; change: CardChange; /** It is the «Deshacer» of a change: no undo for it. */ undoing?: boolean; }>(), /** Save the current filter under a name. */ viewSaveRequested: type<{ name: string; shared: boolean }>(), viewDeleteRequested: type<{ id: string }>(), }, }); export const boardApiEvents = eventGroup({ source: 'Board API', events: { loaded: type(), loadFailed: type(), issueMoveFailed: type(), issueEditFailed: type(), issueCreated: type(), issueCreateFailed: type(), viewsLoaded: type(), viewSaved: type(), viewDeleted: type(), viewFailed: type(), }, }); export const boardRealtimeEvents = eventGroup({ source: 'Board Realtime', events: { issueChanged: type(), }, });