@flusys/ng-task-manager 9.1.2 → 9.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/fesm2022/{flusys-ng-task-manager-board-list-page.component-Dmay3IyF.mjs → flusys-ng-task-manager-board-list-page.component-BAkiTEpy.mjs} +2 -2
- package/fesm2022/{flusys-ng-task-manager-board-list-page.component-Dmay3IyF.mjs.map → flusys-ng-task-manager-board-list-page.component-BAkiTEpy.mjs.map} +1 -1
- package/fesm2022/{flusys-ng-task-manager-board-view-page.component-CkC8-UKF.mjs → flusys-ng-task-manager-board-view-page.component-9ZrU7hON.mjs} +18 -21
- package/fesm2022/flusys-ng-task-manager-board-view-page.component-9ZrU7hON.mjs.map +1 -0
- package/fesm2022/flusys-ng-task-manager.mjs +148 -51
- package/fesm2022/flusys-ng-task-manager.mjs.map +1 -1
- package/package.json +4 -4
- package/types/flusys-ng-task-manager.d.ts +10 -1
- package/fesm2022/flusys-ng-task-manager-board-view-page.component-CkC8-UKF.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flusys-ng-task-manager.mjs","names":[],"sources":["../../../projects/ng-task-manager/services/task-board-api.service.ts","../../../projects/ng-task-manager/services/task-api.service.ts","../../../projects/ng-task-manager/services/task-board-socket.service.ts","../../../projects/ng-task-manager/services/task-board-state.service.ts","../../../projects/ng-task-manager/utils/task-utils.ts","../../../projects/ng-task-manager/components/task-card/task-card.component.ts","../../../projects/ng-task-manager/components/task-form-dialog/task-form-dialog.component.ts","../../../projects/ng-task-manager/components/task-detail-panel/task-detail-panel.component.ts","../../../projects/ng-task-manager/constants/messages.ts","../../../projects/ng-task-manager/routes/task-manager.routes.ts"],"sourcesContent":["import { Service } from '@angular/core';\nimport {\n ApiResourceService,\n IListResponse,\n IMessageResponse,\n ISingleResponse,\n} from '@flusys/ng-shared';\nimport { firstValueFrom } from 'rxjs';\nimport {\n ITaskBoard,\n ITaskBoardMember,\n IUpdateTaskBoardDto,\n} from '../interfaces/task.interface';\n\n@Service()\nexport class TaskBoardApiService extends ApiResourceService<\n IUpdateTaskBoardDto,\n ITaskBoard\n> {\n constructor() {\n super('board', 'taskManager');\n }\n\n getMembers(boardId: string): Promise<IListResponse<ITaskBoardMember>> {\n return firstValueFrom(\n this.http.post<IListResponse<ITaskBoardMember>>(\n `${this.baseUrl}/get-members`,\n { boardId },\n ),\n );\n }\n\n addMember(\n boardId: string,\n userId: string,\n role = 'MEMBER',\n ): Promise<ISingleResponse<ITaskBoardMember>> {\n return firstValueFrom(\n this.http.post<ISingleResponse<ITaskBoardMember>>(\n `${this.baseUrl}/add-member`,\n { boardId, userId, role },\n ),\n );\n }\n\n removeMember(boardId: string, userId: string): Promise<IMessageResponse> {\n return firstValueFrom(\n this.http.post<IMessageResponse>(`${this.baseUrl}/remove-member`, {\n boardId,\n userId,\n }),\n );\n }\n}\n","import { Service } from '@angular/core';\nimport { ApiResourceService, IMessageResponse, ISingleResponse } from '@flusys/ng-shared';\nimport { firstValueFrom } from 'rxjs';\nimport {\n ICreateTaskCommentDto,\n ICreateTaskLabelDto,\n ICreateTaskListDto,\n ITask,\n ITaskComment,\n ITaskLabel,\n ITaskList,\n IMoveTaskDto,\n IReorderTaskListsDto,\n IUpdateTaskListDto,\n IUpdateTaskDto,\n} from '../interfaces/task.interface';\n\n@Service()\nexport class TaskApiService extends ApiResourceService<IUpdateTaskDto, ITask> {\n constructor() {\n super('task', 'taskManager');\n }\n\n moveTask(dto: IMoveTaskDto): Promise<ISingleResponse<ITask>> {\n return firstValueFrom(\n this.http.post<ISingleResponse<ITask>>(`${this.baseUrl}/move`, dto),\n );\n }\n}\n\n@Service()\nexport class TaskListApiService extends ApiResourceService<ICreateTaskListDto, ITaskList> {\n constructor() {\n super('list', 'taskManager');\n }\n\n updateList(dto: IUpdateTaskListDto): Promise<ISingleResponse<ITaskList>> {\n return firstValueFrom(\n this.http.post<ISingleResponse<ITaskList>>(`${this.baseUrl}/update`, dto),\n );\n }\n\n reorderLists(dto: IReorderTaskListsDto): Promise<IMessageResponse> {\n return firstValueFrom(\n this.http.post<IMessageResponse>(`${this.baseUrl}/reorder`, dto),\n );\n }\n}\n\n@Service()\nexport class TaskLabelApiService extends ApiResourceService<ICreateTaskLabelDto, ITaskLabel> {\n constructor() {\n super('label', 'taskManager');\n }\n}\n\n@Service()\nexport class TaskCommentApiService extends ApiResourceService<ICreateTaskCommentDto, ITaskComment> {\n constructor() {\n super('comment', 'taskManager');\n }\n}\n","import { inject, signal, Service } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { io, Socket } from 'socket.io-client';\nimport { APP_CONFIG } from '@flusys/ng-core';\nimport { IBoardSocketEvent } from '../interfaces/task.interface';\n\n@Service()\nexport class TaskBoardSocketService {\n private socket: Socket | null = null;\n private readonly appConfig = inject(APP_CONFIG);\n\n private readonly _isConnected = signal(false);\n readonly isConnected = this._isConnected.asReadonly();\n\n private readonly boardEvent$ = new Subject<IBoardSocketEvent>();\n readonly onBoardEvent = this.boardEvent$.asObservable();\n\n connect(accessToken: string): void {\n if (this.socket?.connected) return;\n\n const baseUrl = this.getBaseUrl();\n this.socket = io(`${baseUrl}/task-boards`, {\n auth: { token: accessToken },\n transports: ['websocket', 'polling'],\n reconnection: true,\n reconnectionAttempts: 5,\n reconnectionDelay: 1000,\n });\n\n this.socket.on('connect', () => this._isConnected.set(true));\n this.socket.on('disconnect', (reason: string) => {\n this._isConnected.set(false);\n if (reason === 'io server disconnect') this.socket?.connect();\n });\n this.socket.on('connect_error', () => this._isConnected.set(false));\n this.socket.on('board:event', (event: IBoardSocketEvent) => this.boardEvent$.next(event));\n }\n\n joinBoard(boardId: string): void {\n this.socket?.emit('board:join', { boardId });\n }\n\n leaveBoard(boardId: string): void {\n this.socket?.emit('board:leave', { boardId });\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n this._isConnected.set(false);\n }\n\n private getBaseUrl(): string {\n const services = this.appConfig.services as Record<string, { socketUrl?: string }> | undefined;\n return services?.['taskManager']?.socketUrl ?? this.appConfig.apiBaseUrl;\n }\n}\n","import { computed, DestroyRef, inject, signal, Service } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { IBoardSocketEvent, ITask, ITaskBoard, ITaskBoardMember, ITaskLabel, ITaskList, IUpdateTaskBoardDto } from '../interfaces/task.interface';\nimport { TaskApiService, TaskLabelApiService, TaskListApiService } from './task-api.service';\nimport { TaskBoardApiService } from './task-board-api.service';\nimport { TaskBoardSocketService } from './task-board-socket.service';\n\n@Service()\nexport class TaskBoardStateService {\n private readonly boardApi = inject(TaskBoardApiService);\n private readonly taskApi = inject(TaskApiService);\n private readonly listApi = inject(TaskListApiService);\n private readonly labelApi = inject(TaskLabelApiService);\n private readonly socketService = inject(TaskBoardSocketService);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly _boards = signal<ITaskBoard[]>([]);\n private readonly _activeBoard = signal<ITaskBoard | null>(null);\n private readonly _lists = signal<ITaskList[]>([]);\n private readonly _tasks = signal<ITask[]>([]);\n private readonly _labels = signal<ITaskLabel[]>([]);\n private readonly _members = signal<ITaskBoardMember[]>([]);\n private readonly _selectedTask = signal<ITask | null>(null);\n private readonly _isLoading = signal(false);\n private readonly _isBoardLoading = signal(false);\n\n readonly boards = this._boards.asReadonly();\n readonly activeBoard = this._activeBoard.asReadonly();\n readonly lists = this._lists.asReadonly();\n readonly tasks = this._tasks.asReadonly();\n readonly labels = this._labels.asReadonly();\n readonly members = this._members.asReadonly();\n readonly selectedTask = this._selectedTask.asReadonly();\n readonly isLoading = this._isLoading.asReadonly();\n readonly isBoardLoading = this._isBoardLoading.asReadonly();\n\n readonly tasksByList = computed(() => {\n const map = new Map<string, ITask[]>();\n for (const task of this._tasks()) {\n const list = map.get(task.listId) ?? [];\n list.push(task);\n map.set(task.listId, list);\n }\n return map;\n });\n\n readonly listsWithTasks = computed(() =>\n this._lists()\n .slice()\n .sort((a, b) => a.position - b.position)\n .map((list) => ({\n ...list,\n tasks: (this.tasksByList().get(list.id) ?? []).slice().sort((a, b) => a.position - b.position),\n })),\n );\n\n readonly hasActiveBoard = computed(() => this._activeBoard() !== null);\n readonly isSocketConnected = this.socketService.isConnected;\n\n constructor() {\n this.socketService.onBoardEvent\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((event) => this.handleBoardEvent(event));\n }\n\n async loadBoards(): Promise<void> {\n this._isLoading.set(true);\n try {\n const res = await this.boardApi.getAll({ sort: { createdAt: 'DESC' } });\n this._boards.set(res.data ?? []);\n } finally {\n this._isLoading.set(false);\n }\n }\n\n async openBoard(boardId: string): Promise<void> {\n this._isBoardLoading.set(true);\n try {\n const prevBoard = this._activeBoard();\n if (prevBoard) this.socketService.leaveBoard(prevBoard.id);\n\n const [boardRes, listsRes, tasksRes, labelsRes, membersRes] = await Promise.all([\n this.boardApi.findById(boardId),\n this.listApi.getAll({ filter: { boardId, isActive: true }, sort: { position: 'ASC' } }),\n this.taskApi.getAll({ filter: { boardId }, sort: { position: 'ASC' } }),\n this.labelApi.getAll({ filter: { boardId } }),\n this.boardApi.getMembers(boardId),\n ]);\n\n this._activeBoard.set(boardRes.data ?? null);\n this._lists.set(listsRes.data ?? []);\n this._tasks.set(tasksRes.data ?? []);\n this._labels.set(labelsRes.data ?? []);\n this._members.set(membersRes.data ?? []);\n\n this.socketService.joinBoard(boardId);\n } finally {\n this._isBoardLoading.set(false);\n }\n }\n\n closeBoard(): void {\n const board = this._activeBoard();\n if (board) this.socketService.leaveBoard(board.id);\n this._activeBoard.set(null);\n this._lists.set([]);\n this._tasks.set([]);\n this._labels.set([]);\n this._members.set([]);\n this._selectedTask.set(null);\n }\n\n selectTask(task: ITask | null): void {\n this._selectedTask.set(task);\n }\n\n async addLabel(boardId: string, name: string, color: string): Promise<void> {\n await this.labelApi.insert({ boardId, name, color });\n const res = await this.labelApi.getAll({ filter: { boardId } });\n this._labels.set(res.data ?? []);\n }\n\n async deleteLabel(labelId: string): Promise<void> {\n await this.labelApi.delete({ id: labelId, type: 'delete' });\n this._labels.update((list) => list.filter((l) => l.id !== labelId));\n }\n\n async addMember(userId: string, role = 'MEMBER'): Promise<void> {\n const board = this._activeBoard();\n if (!board) return;\n const res = await this.boardApi.addMember(board.id, userId, role);\n if (res.data) this._members.update((list) => [...list, res.data!]);\n }\n\n async removeMember(userId: string): Promise<void> {\n const board = this._activeBoard();\n if (!board) return;\n await this.boardApi.removeMember(board.id, userId);\n this._members.update((list) => list.filter((m) => m.userId !== userId));\n }\n\n async reorderLists(boardId: string, orderedIds: string[]): Promise<void> {\n const posMap = new Map(orderedIds.map((id, i) => [id, i * 100]));\n this._lists.update((list) =>\n list\n .map((l) => (posMap.has(l.id) ? { ...l, position: posMap.get(l.id)! } : l))\n .sort((a, b) => a.position - b.position),\n );\n await this.listApi.reorderLists({ boardId, orderedIds });\n }\n\n async renameList(listId: string, name: string): Promise<void> {\n await this.listApi.updateList({ id: listId, name });\n this._lists.update((list) => list.map((l) => (l.id === listId ? { ...l, name } : l)));\n }\n\n async updateBoard(dto: IUpdateTaskBoardDto): Promise<void> {\n await this.boardApi.update(dto);\n const id = dto.id;\n if (!id) return;\n this._activeBoard.update((b) => (b?.id === id ? { ...b, ...dto } : b));\n this._boards.update((list) => list.map((b) => (b.id === id ? { ...b, ...dto } : b)));\n }\n\n addTaskOptimistic(task: ITask): void {\n this._tasks.update((list) => {\n if (list.some((t) => t.id === task.id)) {\n return list.map((t) => (t.id === task.id ? { ...t, ...task } : t));\n }\n return [...list, task];\n });\n }\n\n async deleteTask(taskId: string): Promise<void> {\n await this.taskApi.delete({ id: taskId, type: 'delete' });\n this._tasks.update((list) => list.filter((t) => t.id !== taskId));\n if (this._selectedTask()?.id === taskId) this._selectedTask.set(null);\n }\n\n private handleBoardEvent(event: IBoardSocketEvent): void {\n switch (event.type) {\n case 'task:created': {\n const created = event.payload as ITask;\n this._tasks.update((list) => {\n if (list.some((t) => t.id === created.id)) return list;\n return [...list, created];\n });\n break;\n }\n\n case 'task:updated':\n case 'task:moved': {\n const updated = event.payload as ITask;\n this._tasks.update((list) =>\n list.map((t) => (t.id === updated.id ? { ...t, ...updated } : t)),\n );\n if (this._selectedTask()?.id === updated.id) {\n this._selectedTask.update((t) => (t ? { ...t, ...updated } : null));\n }\n break;\n }\n\n case 'task:deleted': {\n const deleted = event.payload as { id: string };\n this._tasks.update((list) => list.filter((t) => t.id !== deleted.id));\n if (this._selectedTask()?.id === deleted.id) this._selectedTask.set(null);\n break;\n }\n\n case 'list:created':\n this._lists.update((list) => [...list, event.payload as ITaskList]);\n break;\n\n case 'list:updated': {\n const updatedList = event.payload as ITaskList;\n this._lists.update((list) =>\n list.map((l) => (l.id === updatedList.id ? { ...l, ...updatedList } : l)),\n );\n break;\n }\n\n case 'list:deleted': {\n const deletedList = event.payload as { id: string };\n this._lists.update((list) => list.filter((l) => l.id !== deletedList.id));\n break;\n }\n\n case 'list:reordered': {\n const { orderedIds } = event.payload as { orderedIds: string[] };\n const posMap = new Map(orderedIds.map((id, i) => [id, i * 100]));\n this._lists.update((list) =>\n list\n .map((l) => (posMap.has(l.id) ? { ...l, position: posMap.get(l.id)! } : l))\n .sort((a, b) => a.position - b.position),\n );\n break;\n }\n }\n }\n}\n","export const MEMBER_COLOR_PALETTE = [\n '#6366f1',\n '#8b5cf6',\n '#ec4899',\n '#ef4444',\n '#f97316',\n '#eab308',\n '#22c55e',\n '#14b8a6',\n '#3b82f6',\n '#06b6d4',\n];\n\nexport const BOARD_COLOR_PALETTE = [\n ...MEMBER_COLOR_PALETTE,\n '#64748b',\n];\n\nexport function taskPrioritySeverity(\n priority: string,\n): 'success' | 'info' | 'warn' | 'danger' | 'secondary' {\n const map: Record<string, 'success' | 'info' | 'warn' | 'danger' | 'secondary'> = {\n LOW: 'secondary',\n MEDIUM: 'info',\n HIGH: 'warn',\n URGENT: 'danger',\n };\n return map[priority] ?? 'info';\n}\n\nexport function memberInitials(name: string | null | undefined): string {\n if (!name) return '?';\n return name\n .split(' ')\n .slice(0, 2)\n .map((n) => n[0]?.toUpperCase() ?? '')\n .join('');\n}\n\nexport function isTaskOverdue(dueDate: string): boolean {\n return new Date(dueDate) < new Date();\n}\n\nexport function memberColorFromId(userId: string): string {\n let hash = 0;\n for (let i = 0; i < userId.length; i++)\n hash = userId.charCodeAt(i) + ((hash << 5) - hash);\n return MEMBER_COLOR_PALETTE[Math.abs(hash) % MEMBER_COLOR_PALETTE.length];\n}\n","import { DatePipe } from '@angular/common';\nimport { Component, computed, input, output } from '@angular/core';\nimport { TranslatePipe } from '@flusys/ng-shared';\nimport { AvatarComponent, TagComponent, TooltipDirective, UiIconComponent } from '@flusys/ng-ui';\nimport { ITask } from '../../interfaces/task.interface';\nimport {\n isTaskOverdue,\n memberColorFromId,\n memberInitials,\n taskPrioritySeverity,\n} from '../../utils/task-utils';\n\n@Component({\n selector: 'tm-task-card',\n imports: [DatePipe, TranslatePipe, TooltipDirective, AvatarComponent, TagComponent, UiIconComponent],\n template: `\n <div\n class=\"task-card group relative rounded-border border border-surface p-3 cursor-pointer shadow-sm hover:shadow-md transition-shadow\"\n (click)=\"cardClick.emit(task())\"\n >\n <div class=\"absolute top-2 right-2 hidden group-hover:flex gap-0.5\">\n <button\n class=\"w-6 h-6 flex items-center justify-center rounded text-muted-color hover:text-primary-500 hover:bg-surface-hover transition-colors\"\n [fTooltip]=\"'shared.edit' | translate\"\n tooltipPosition=\"top\"\n (click)=\"$event.stopPropagation(); editClick.emit(task())\"\n >\n <ui-icon name=\"pencil\" class=\"text-xs\"></ui-icon>\n </button>\n <button\n class=\"w-6 h-6 flex items-center justify-center rounded text-muted-color hover:text-red-500 hover:bg-surface-hover transition-colors\"\n [fTooltip]=\"'shared.delete' | translate\"\n tooltipPosition=\"top\"\n (click)=\"$event.stopPropagation(); deleteClick.emit(task())\"\n >\n <ui-icon name=\"trash\" class=\"text-xs\"></ui-icon>\n </button>\n </div>\n\n @if (task().labels && task().labels!.length > 0) {\n <div class=\"flex flex-wrap gap-1 mb-2\">\n @for (label of task().labels; track label.id) {\n <span\n class=\"inline-block h-1.5 rounded-full w-8\"\n [style.background-color]=\"label.color\"\n [fTooltip]=\"label.name\"\n ></span>\n }\n </div>\n }\n\n <p class=\"text-sm font-semibold line-clamp-2 leading-snug pr-14\">\n {{ task().title }}\n </p>\n\n <div class=\"flex items-center justify-between gap-2 mt-auto pt-2\">\n <f-tag\n [value]=\"task().priority\"\n [severity]=\"prioritySeverity(task().priority)\"\n class=\"text-xs\"\n />\n\n @if (task().dueDate) {\n <span\n class=\"text-xs text-muted-color\"\n [class.text-red-500]=\"isOverdue(task().dueDate!)\"\n >\n {{ task().dueDate | date: 'MMM d' }}\n </span>\n }\n\n @if (visibleAssignees().length > 0) {\n <div class=\"flex items-center -space-x-1.5\">\n @for (a of visibleAssignees(); track a.userId) {\n <f-avatar\n shape=\"circle\"\n size=\"small\"\n [label]=\"initials(a.userName)\"\n [color]=\"memberColor(a.userId)\"\n styleClass=\"!ring-surface-card flex-shrink-0\"\n [fTooltip]=\"a.userName ?? ''\"\n />\n }\n @if (overflowCount() > 0) {\n <f-avatar\n shape=\"circle\"\n size=\"small\"\n [label]=\"'+' + overflowCount()\"\n styleClass=\"!bg-surface-200 dark:!bg-surface-700 !text-surface-600 dark:!text-surface-300 !ring-surface-card flex-shrink-0\"\n />\n }\n </div>\n }\n </div>\n </div>\n `,\n})\nexport class TaskCardComponent {\n readonly task = input.required<ITask>();\n readonly cardClick = output<ITask>();\n readonly editClick = output<ITask>();\n readonly deleteClick = output<ITask>();\n\n private readonly MAX_VISIBLE = 3;\n\n readonly visibleAssignees = computed(() =>\n (this.task().assignees ?? []).slice(0, this.MAX_VISIBLE),\n );\n\n readonly overflowCount = computed(() =>\n Math.max(0, (this.task().assignees ?? []).length - this.MAX_VISIBLE),\n );\n\n protected readonly prioritySeverity = taskPrioritySeverity;\n protected readonly initials = memberInitials;\n protected readonly isOverdue = isTaskOverdue;\n protected readonly memberColor = memberColorFromId;\n}\n","import {\n Component,\n effect,\n inject,\n input,\n model,\n output,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport { TranslatePipe } from '@flusys/ng-shared';\nimport {\n DatePickerComponent,\n DialogComponent,\n FButtonDirective,\n InputTextDirective,\n MultiSelectComponent,\n SelectComponent,\n TextareaDirective,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport {\n ICreateTaskDto,\n ITask,\n ITaskBoardMember,\n ITaskLabel,\n IUpdateTaskDto,\n TaskPriority,\n} from '../../interfaces/task.interface';\nimport { TaskApiService } from '../../services/task-api.service';\n\nconst PRIORITY_OPTIONS = [\n { labelKey: 'task.priority.LOW', value: 'LOW' },\n { labelKey: 'task.priority.MEDIUM', value: 'MEDIUM' },\n { labelKey: 'task.priority.HIGH', value: 'HIGH' },\n { labelKey: 'task.priority.URGENT', value: 'URGENT' },\n];\n\n@Component({\n selector: 'tm-task-form-dialog',\n imports: [\n DatePickerComponent,\n DialogComponent,\n FButtonDirective,\n InputTextDirective,\n MultiSelectComponent,\n SelectComponent,\n TextareaDirective,\n UiIconComponent,\n FormsModule,\n FormField,\n TranslatePipe,\n ],\n template: `\n <f-dialog\n [header]=\"\n (task() ? 'task.form.title.edit' : 'task.form.title.create') | translate\n \"\n [(visible)]=\"visible\"\n [modal]=\"true\"\n [style]=\"{ width: '540px' }\"\n (onHide)=\"onClose()\"\n >\n <div class=\"flex flex-col gap-4 py-3\">\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-sm font-medium\"\n >{{ 'task.form.title.label' | translate }}\n <span class=\"text-red-500\">*</span></label\n >\n <input\n fInputText\n [formField]=\"taskForm.title\"\n [placeholder]=\"'task.form.title.placeholder' | translate\"\n />\n </div>\n\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-sm font-medium\">{{\n 'shared.description' | translate\n }}</label>\n <textarea\n fTextarea\n [formField]=\"taskForm.description\"\n rows=\"3\"\n [placeholder]=\"'task.form.description.placeholder' | translate\"\n ></textarea>\n </div>\n\n <div class=\"grid grid-cols-2 gap-4\">\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-sm font-medium\">{{\n 'task.form.priority.label' | translate\n }}</label>\n <f-select\n [formField]=\"taskForm.priority\"\n [options]=\"priorityOptions\"\n optionLabel=\"labelKey\"\n optionValue=\"value\"\n [placeholder]=\"'task.form.priority.placeholder' | translate\"\n >\n <ng-template #selectedItem let-opt>\n {{ opt.labelKey | translate }}\n </ng-template>\n <ng-template #item let-opt>\n {{ opt.labelKey | translate }}\n </ng-template>\n </f-select>\n </div>\n\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-sm font-medium\">{{\n 'task.form.due.date.label' | translate\n }}</label>\n <f-datepicker\n [ngModel]=\"dueDate()\"\n (ngModelChange)=\"dueDate.set($event)\"\n [showClear]=\"true\"\n [placeholder]=\"'task.form.due.date.placeholder' | translate\"\n />\n </div>\n </div>\n\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-sm font-medium\">{{\n 'task.form.assignee.label' | translate\n }}</label>\n <f-multiselect\n [ngModel]=\"selectedAssigneeIds()\"\n (ngModelChange)=\"selectedAssigneeIds.set($event)\"\n [options]=\"members()\"\n optionLabel=\"userName\"\n optionValue=\"userId\"\n [selectedObjects]=\"task()?.assignees ?? []\"\n [placeholder]=\"'task.form.assignee.placeholder' | translate\"\n [showClear]=\"true\"\n />\n </div>\n\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-sm font-medium\">{{\n 'task.form.labels.label' | translate\n }}</label>\n <f-multiselect\n [ngModel]=\"selectedLabelIds()\"\n (ngModelChange)=\"selectedLabelIds.set($event)\"\n [options]=\"labels()\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [placeholder]=\"'task.form.labels.placeholder' | translate\"\n />\n </div>\n </div>\n\n <ng-template #footer>\n <div class=\"flex justify-end gap-2 pt-1\">\n <button fButton severity=\"secondary\" (click)=\"onClose()\">\n <span pButtonLabel>{{ 'shared.cancel' | translate }}</span>\n </button>\n <button fButton (click)=\"onSave()\" [disabled]=\"isSaving()\">\n @if (isSaving()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ 'shared.save' | translate }}</span>\n </button>\n </div>\n </ng-template>\n </f-dialog>\n `,\n})\nexport class TaskFormDialogComponent {\n private readonly taskApi = inject(TaskApiService);\n\n readonly visible = model(false);\n readonly task = input<ITask | null>(null);\n readonly boardId = input.required<string>();\n readonly listId = input.required<string>();\n readonly members = input<ITaskBoardMember[]>([]);\n readonly labels = input<ITaskLabel[]>([]);\n readonly saved = output<ITask>();\n\n readonly isSaving = signal(false);\n readonly priorityOptions = PRIORITY_OPTIONS;\n\n readonly formModel = signal({\n title: '',\n description: '',\n priority: 'MEDIUM' as TaskPriority,\n });\n readonly taskForm = form(this.formModel, (f) => {\n required(f.title);\n });\n\n readonly dueDate = signal<Date | null>(null);\n readonly selectedAssigneeIds = signal<string[]>([]);\n readonly selectedLabelIds = signal<string[]>([]);\n\n constructor() {\n effect(() => {\n const t = this.task();\n if (t) {\n this.formModel.set({\n title: t.title,\n description: t.description ?? '',\n priority: t.priority,\n });\n this.dueDate.set(t.dueDate ? new Date(t.dueDate) : null);\n this.selectedAssigneeIds.set(t.assignees?.map((a) => a.userId) ?? []);\n this.selectedLabelIds.set(t.labelIds ?? []);\n } else {\n this.reset();\n }\n });\n }\n\n async onSave(): Promise<void> {\n const { title, description, priority } = this.formModel();\n if (!title.trim()) return;\n this.isSaving.set(true);\n try {\n const dueDate = this.dueDate();\n const dueDateStr = dueDate ? dueDate.toISOString().slice(0, 10) : undefined;\n const existing = this.task();\n const assigneeIds = this.selectedAssigneeIds();\n const labelIds = this.selectedLabelIds();\n let result;\n\n if (existing) {\n const dto: IUpdateTaskDto = {\n id: existing.id,\n title,\n description: description || undefined,\n priority,\n dueDate: dueDateStr,\n assigneeIds,\n labelIds,\n };\n result = await this.taskApi.update(dto);\n } else {\n const dto: ICreateTaskDto = {\n boardId: this.boardId(),\n listId: this.listId(),\n title,\n description: description || undefined,\n priority,\n dueDate: dueDateStr,\n assigneeIds,\n labelIds,\n };\n result = await this.taskApi.insert(dto);\n }\n\n if (result.data) this.saved.emit(result.data);\n this.visible.set(false);\n } finally {\n this.isSaving.set(false);\n }\n }\n\n onClose(): void {\n this.visible.set(false);\n this.reset();\n }\n\n private reset(): void {\n this.formModel.set({ title: '', description: '', priority: 'MEDIUM' });\n this.dueDate.set(null);\n this.selectedAssigneeIds.set([]);\n this.selectedLabelIds.set([]);\n }\n}\n","import { DatePipe } from '@angular/common';\nimport {\n Component,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { TranslatePipe } from '@flusys/ng-shared';\nimport {\n AvatarComponent,\n DrawerComponent,\n FButtonDirective,\n TagComponent,\n TextareaDirective,\n TooltipDirective,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport { ITask, ITaskComment } from '../../interfaces/task.interface';\nimport { TaskCommentApiService } from '../../services/task-api.service';\nimport { TaskBoardStateService } from '../../services/task-board-state.service';\nimport { memberInitials, taskPrioritySeverity } from '../../utils/task-utils';\n\n@Component({\n selector: 'tm-task-detail-panel',\n imports: [\n AvatarComponent,\n DrawerComponent,\n FButtonDirective,\n TagComponent,\n TextareaDirective,\n TooltipDirective,\n UiIconComponent,\n DatePipe,\n FormsModule,\n TranslatePipe,\n ],\n template: `\n <f-drawer\n [visible]=\"!!task()\"\n position=\"right\"\n [style]=\"{ width: '500px' }\"\n [header]=\"task()?.title ?? ''\"\n (onHide)=\"closePanel.emit()\"\n >\n @if (task(); as t) {\n <div class=\"flex flex-col gap-6 h-full overflow-y-auto pb-4\">\n <div class=\"flex items-center justify-end gap-1\">\n <button\n fButton\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [fTooltip]=\"'task.detail.edit' | translate\"\n tooltipPosition=\"left\"\n (click)=\"editTask.emit(t)\"\n >\n <ui-icon pButtonIcon name=\"pencil\"></ui-icon>\n </button>\n <button\n fButton\n severity=\"danger\"\n size=\"small\"\n [text]=\"true\"\n [fTooltip]=\"'task.detail.delete' | translate\"\n tooltipPosition=\"left\"\n (click)=\"deleteTask(t.id)\"\n [disabled]=\"isDeleting()\"\n >\n @if (isDeleting()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n } @else {\n <ui-icon pButtonIcon name=\"trash\"></ui-icon>\n }\n </button>\n </div>\n\n <div class=\"flex items-center gap-3\">\n <f-tag\n [value]=\"t.priority\"\n [severity]=\"prioritySeverity(t.priority)\"\n />\n @if (t.dueDate) {\n <span class=\"text-sm text-muted-color\">\n {{ 'task.detail.due.label' | translate }}:\n {{ t.dueDate | date: 'mediumDate' }}\n </span>\n }\n </div>\n\n @if (assigneeMembers().length > 0) {\n <div>\n <h4 class=\"text-sm font-semibold mb-2\">\n {{ 'task.detail.assignees.label' | translate }}\n </h4>\n <div class=\"flex flex-wrap gap-2\">\n @for (member of assigneeMembers(); track member.userId) {\n <div class=\"flex items-center gap-2 px-2 py-1 rounded-full \">\n <f-avatar\n shape=\"circle\"\n size=\"small\"\n [label]=\"initials(member.userName)\"\n styleClass=\"!bg-primary-100 dark:!bg-primary-900 !text-primary-700 dark:!text-primary-300\"\n />\n <span class=\"text-sm\">{{ member.userName }}</span>\n </div>\n }\n </div>\n </div>\n }\n\n <div>\n <h4 class=\"text-sm font-semibold mb-2\">\n {{ 'shared.description' | translate }}\n </h4>\n <p class=\"text-sm text-color whitespace-pre-wrap\">\n {{\n t.description || ('task.detail.description.empty' | translate)\n }}\n </p>\n </div>\n\n <div class=\"flex flex-col gap-1\">\n <h4 class=\"text-sm font-semibold mb-1\">\n {{ 'task.detail.comments.label' | translate }} ({{\n rootComments().length\n }})\n </h4>\n\n @for (comment of rootComments(); track comment.id) {\n <div\n class=\"group flex flex-col gap-1 py-2 border-b border-surface last:border-0\"\n >\n <div class=\"flex items-center justify-between\">\n <span class=\"text-xs text-muted-color\">{{\n comment.createdAt | date: 'MMM d, y, h:mm a'\n }}</span>\n <button\n fButton\n size=\"small\"\n [text]=\"true\"\n severity=\"secondary\"\n class=\"opacity-0 group-hover:opacity-100 transition-opacity !py-0.5 !px-1.5 text-xs\"\n (click)=\"toggleReply(comment.id)\"\n >\n <ui-icon pButtonIcon name=\"reply\"></ui-icon>\n <span pButtonLabel>{{ 'task.comment.reply' | translate }}</span>\n </button>\n </div>\n <p class=\"text-sm\">{{ comment.content }}</p>\n\n @if (repliesFor(comment.id).length > 0) {\n <div\n class=\"mt-1 pl-3 border-l-2 border-surface flex flex-col gap-2\"\n >\n @for (reply of repliesFor(comment.id); track reply.id) {\n <div class=\"flex flex-col gap-0.5\">\n <span class=\"text-xs text-muted-color\">{{\n reply.createdAt | date: 'MMM d, y, h:mm a'\n }}</span>\n <p class=\"text-sm\">{{ reply.content }}</p>\n </div>\n }\n </div>\n }\n\n @if (replyingToId() === comment.id) {\n <div\n class=\"mt-2 pl-3 border-l-2 border-primary-300 dark:border-primary-700 flex gap-2\"\n >\n <textarea\n fTextarea\n [ngModel]=\"replyText()\"\n (ngModelChange)=\"replyText.set($event)\"\n rows=\"2\"\n [placeholder]=\"\n 'task.comment.reply.placeholder' | translate\n \"\n class=\"flex-1 resize-none text-sm\"\n autoResize=\"true\"\n ></textarea>\n <div class=\"flex flex-col gap-1\">\n <button\n fButton\n size=\"small\"\n [disabled]=\"!replyText().trim() || isSendingReply()\"\n (click)=\"submitReply(t.id, comment.id)\"\n >\n @if (isSendingReply()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n } @else {\n <ui-icon pButtonIcon name=\"send\"></ui-icon>\n }\n </button>\n <button\n fButton\n size=\"small\"\n severity=\"secondary\"\n [text]=\"true\"\n (click)=\"cancelReply()\"\n >\n <ui-icon pButtonIcon name=\"times\"></ui-icon>\n </button>\n </div>\n </div>\n }\n </div>\n }\n\n @if (rootComments().length === 0) {\n <p class=\"text-sm text-muted-color py-2\">\n {{ 'task.detail.comments.empty' | translate }}\n </p>\n }\n\n <div class=\"flex gap-2 mt-3\">\n <textarea\n fTextarea\n [ngModel]=\"newComment()\"\n (ngModelChange)=\"newComment.set($event)\"\n rows=\"2\"\n [placeholder]=\"'task.detail.comment.placeholder' | translate\"\n class=\"flex-1 resize-none\"\n ></textarea>\n <button\n fButton\n [disabled]=\"!newComment().trim() || isSendingComment()\"\n (click)=\"addComment(t.id)\"\n >\n @if (isSendingComment()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n } @else {\n <ui-icon pButtonIcon name=\"send\"></ui-icon>\n }\n </button>\n </div>\n </div>\n </div>\n }\n </f-drawer>\n `,\n})\nexport class TaskDetailPanelComponent {\n private readonly commentApi = inject(TaskCommentApiService);\n private readonly state = inject(TaskBoardStateService);\n\n readonly task = input<ITask | null>(null);\n\n readonly closePanel = output<void>();\n readonly editTask = output<ITask>();\n\n readonly comments = signal<ITaskComment[]>([]);\n readonly isSendingComment = signal(false);\n readonly isSendingReply = signal(false);\n readonly replyingToId = signal<string | null>(null);\n readonly isDeleting = signal(false);\n\n readonly newComment = signal('');\n readonly replyText = signal('');\n\n readonly assigneeMembers = computed(() => this.task()?.assignees ?? []);\n\n readonly rootComments = computed(() =>\n this.comments().filter((c) => !c.parentCommentId),\n );\n\n repliesFor(parentId: string): ITaskComment[] {\n return this.comments().filter((c) => c.parentCommentId === parentId);\n }\n\n constructor() {\n effect(() => {\n const t = this.task();\n if (t) this.loadComments(t.id);\n else {\n this.comments.set([]);\n this.replyingToId.set(null);\n }\n });\n }\n\n toggleReply(commentId: string): void {\n if (this.replyingToId() === commentId) {\n this.cancelReply();\n } else {\n this.replyingToId.set(commentId);\n this.replyText.set('');\n }\n }\n\n cancelReply(): void {\n this.replyingToId.set(null);\n this.replyText.set('');\n }\n\n async deleteTask(taskId: string): Promise<void> {\n this.isDeleting.set(true);\n try {\n await this.state.deleteTask(taskId);\n this.closePanel.emit();\n } finally {\n this.isDeleting.set(false);\n }\n }\n\n protected readonly prioritySeverity = taskPrioritySeverity;\n protected readonly initials = memberInitials;\n\n private async loadComments(taskId: string): Promise<void> {\n const res = await this.commentApi.getAll({ filter: { taskId } });\n this.comments.set(res.data ?? []);\n }\n\n async addComment(taskId: string): Promise<void> {\n if (!this.newComment().trim()) return;\n this.isSendingComment.set(true);\n try {\n const res = await this.commentApi.insert({\n taskId,\n content: this.newComment(),\n });\n if (res.data) this.comments.update((list) => [...list, res.data!]);\n this.newComment.set('');\n } finally {\n this.isSendingComment.set(false);\n }\n }\n\n async submitReply(taskId: string, parentCommentId: string): Promise<void> {\n if (!this.replyText().trim()) return;\n this.isSendingReply.set(true);\n try {\n const res = await this.commentApi.insert({\n taskId,\n content: this.replyText(),\n parentCommentId,\n });\n if (res.data) this.comments.update((list) => [...list, res.data!]);\n this.cancelReply();\n } finally {\n this.isSendingReply.set(false);\n }\n }\n}\n","export const TASK_MANAGER_MESSAGES = {\n // Board API messages (keys must match NestJS message-keys.ts)\n 'task.board.not.found': 'Board not found',\n 'task.board.create.success': 'Board created successfully',\n 'task.board.create.many.success': 'Boards created successfully',\n 'task.board.get.success': 'Board retrieved successfully',\n 'task.board.get.all.success': 'Boards retrieved successfully',\n 'task.board.update.success': 'Board updated successfully',\n 'task.board.update.many.success': 'Boards updated successfully',\n 'task.board.delete.success': 'Board deleted successfully',\n 'task.board.restore.success': 'Board restored successfully',\n 'task.board.member.added': 'Member added to board',\n 'task.board.member.removed': 'Member removed from board',\n 'task.board.member.not.found': 'Board member not found',\n 'task.board.member.already.exists': 'User is already a board member',\n 'task.board.member.get.all.success': 'Board members retrieved successfully',\n\n 'task.list.not.found': 'List not found',\n 'task.list.create.success': 'List created successfully',\n 'task.list.create.many.success': 'Lists created successfully',\n 'task.list.get.success': 'List retrieved successfully',\n 'task.list.get.all.success': 'Lists retrieved successfully',\n 'task.list.update.success': 'List updated successfully',\n 'task.list.update.many.success': 'Lists updated successfully',\n 'task.list.delete.success': 'List deleted successfully',\n 'task.list.restore.success': 'List restored successfully',\n 'task.list.reorder.success': 'Lists reordered successfully',\n\n 'task.not.found': 'Task not found',\n 'task.create.success': 'Task created successfully',\n 'task.create.many.success': 'Tasks created successfully',\n 'task.get.success': 'Task retrieved successfully',\n 'task.get.all.success': 'Tasks retrieved successfully',\n 'task.update.success': 'Task updated successfully',\n 'task.update.many.success': 'Tasks updated successfully',\n 'task.delete.success': 'Task deleted successfully',\n 'task.restore.success': 'Task restored successfully',\n 'task.move.success': 'Task moved successfully',\n 'task.assign.success': 'Task assigned successfully',\n 'task.assignee.not.board.member': 'Assignee is not a board member',\n\n 'task.label.not.found': 'Label not found',\n 'task.label.create.success': 'Label created successfully',\n 'task.label.create.many.success': 'Labels created successfully',\n 'task.label.get.success': 'Label retrieved successfully',\n 'task.label.get.all.success': 'Labels retrieved successfully',\n 'task.label.update.success': 'Label updated successfully',\n 'task.label.update.many.success': 'Labels updated successfully',\n 'task.label.delete.success': 'Label deleted successfully',\n 'task.label.restore.success': 'Label restored successfully',\n\n 'task.comment.not.found': 'Comment not found',\n 'task.comment.create.success': 'Comment added successfully',\n 'task.comment.create.many.success': 'Comments added successfully',\n 'task.comment.get.success': 'Comment retrieved successfully',\n 'task.comment.get.all.success': 'Comments retrieved successfully',\n 'task.comment.update.success': 'Comment updated successfully',\n 'task.comment.update.many.success': 'Comments updated successfully',\n 'task.comment.delete.success': 'Comment deleted successfully',\n 'task.comment.restore.success': 'Comment restored successfully',\n 'task.comment.forbidden': \"Cannot edit another user's comment\",\n\n 'task.manager.boards.title': 'Task Boards',\n 'task.manager.boards.subtitle': 'Manage and organize your project boards',\n 'task.manager.board.new': 'New Board',\n 'task.manager.board.name.placeholder': 'e.g. Product Backlog',\n 'task.manager.board.description.placeholder': 'Optional description',\n 'task.manager.board.color.label': 'Board Color',\n 'task.manager.board.empty': 'No boards yet',\n 'task.manager.board.empty.hint': 'Create your first board to get started',\n 'task.manager.board.members': 'Members',\n 'task.manager.board.lists': 'Lists',\n 'task.manager.board.tasks': 'Tasks',\n\n 'task.manager.board.add.list': 'Add List',\n 'task.manager.board.add.task': 'Add task',\n 'task.manager.board.drop.tasks.here': 'Drop tasks here',\n 'task.manager.board.list.empty':\n 'No lists yet. Click \"Add List\" to create one.',\n 'task.manager.list.new': 'New List',\n 'task.manager.list.name.label': 'List Name',\n 'task.manager.list.name.placeholder': 'e.g. In Progress',\n 'task.manager.list.rename': 'Rename List',\n\n 'task.manager.board.manage.members': 'Members',\n 'task.manager.member.manage.title': 'Manage Members',\n 'task.manager.member.add': 'Add Member',\n 'task.manager.member.no.members': 'No members yet.',\n 'task.manager.member.user.label': 'User',\n 'task.manager.member.user.placeholder': 'Search by name or email',\n 'task.manager.member.role.label': 'Role',\n 'task.manager.member.role.placeholder': 'Select role',\n 'task.manager.member.role.owner': 'Owner',\n 'task.manager.member.role.admin': 'Admin',\n 'task.manager.member.role.member': 'Member',\n 'task.manager.member.role.viewer': 'Viewer',\n\n 'task.manager.board.manage.labels': 'Labels',\n 'task.manager.label.manage.title': 'Manage Labels',\n 'task.manager.label.name.label': 'Label Name',\n 'task.manager.label.name.placeholder': 'e.g. Bug, Feature',\n 'task.manager.label.color.label': 'Color',\n 'task.manager.label.add': 'Add Label',\n 'task.manager.label.no.labels': 'No labels yet.',\n\n 'task.manager.board.edit': 'Edit Board',\n 'task.manager.board.name.label': 'Board Name',\n 'task.manager.board.description.label': 'Description',\n\n 'task.manager.view.board': 'Board',\n 'task.manager.view.list': 'List',\n\n 'task.manager.table.title': 'Title',\n 'task.manager.table.list': 'List',\n 'task.manager.table.priority': 'Priority',\n 'task.manager.table.assignee': 'Assignee',\n 'task.manager.table.due.date': 'Due Date',\n 'task.manager.table.empty': 'No tasks yet.',\n\n 'task.form.title.create': 'New Task',\n 'task.form.title.edit': 'Edit Task',\n 'task.form.title.label': 'Title',\n 'task.form.title.placeholder': 'Task title',\n 'task.form.description.placeholder': 'Add a description...',\n 'task.form.priority.label': 'Priority',\n 'task.form.priority.placeholder': 'Select priority',\n 'task.form.due.date.label': 'Due Date',\n 'task.form.due.date.placeholder': 'Pick a date',\n 'task.form.assignee.label': 'Assignee',\n 'task.form.assignee.placeholder': 'Assign to board member',\n 'task.form.labels.label': 'Labels',\n 'task.form.labels.placeholder': 'Select labels',\n\n 'task.priority.LOW': 'Low',\n 'task.priority.MEDIUM': 'Medium',\n 'task.priority.HIGH': 'High',\n 'task.priority.URGENT': 'Urgent',\n\n 'task.detail.description.empty': 'No description',\n 'task.detail.comments.label': 'Comments',\n 'task.detail.comments.empty': 'No comments yet',\n 'task.detail.comment.placeholder': 'Add a comment...',\n 'task.detail.due.label': 'Due',\n 'task.detail.assignees.label': 'Assignees',\n 'task.detail.edit': 'Edit task',\n 'task.detail.delete': 'Delete task',\n 'task.comment.reply': 'Reply',\n 'task.comment.reply.placeholder': 'Write a reply...',\n} as const;\n","import { Routes } from '@angular/router';\nimport { resolveTranslationModule, SHARED_MESSAGES } from '@flusys/ng-shared';\nimport { TASK_MANAGER_MESSAGES } from '../constants/messages';\n\nexport const TASK_MANAGER_ROUTES: Routes = [\n {\n path: '',\n resolve: {\n translations: resolveTranslationModule({\n modules: ['task-manager'],\n fallbackMessages: { ...TASK_MANAGER_MESSAGES, ...SHARED_MESSAGES },\n }),\n },\n loadComponent: () =>\n import('../pages/board-list-page/board-list-page.component').then(\n (m) => m.BoardListPageComponent,\n ),\n },\n {\n path: 'board/:boardId',\n resolve: {\n translations: resolveTranslationModule({\n modules: ['task-manager'],\n fallbackMessages: { ...TASK_MANAGER_MESSAGES, ...SHARED_MESSAGES },\n }),\n },\n loadComponent: () =>\n import('../pages/board-view-page/board-view-page.component').then(\n (m) => m.BoardViewPageComponent,\n ),\n },\n];\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"flusys-ng-task-manager.mjs","names":[],"sources":["../../../projects/ng-task-manager/services/task-board-api.service.ts","../../../projects/ng-task-manager/services/task-api.service.ts","../../../projects/ng-task-manager/services/task-board-socket.service.ts","../../../projects/ng-task-manager/services/task-board-state.service.ts","../../../projects/ng-task-manager/utils/task-utils.ts","../../../projects/ng-task-manager/components/task-card/task-card.component.ts","../../../projects/ng-task-manager/components/task-form-dialog/task-form-dialog.component.ts","../../../projects/ng-task-manager/components/task-detail-panel/task-detail-panel.component.ts","../../../projects/ng-task-manager/constants/messages.ts","../../../projects/ng-task-manager/routes/task-manager.routes.ts"],"sourcesContent":["import { Service } from '@angular/core';\nimport {\n ApiResourceService,\n IListResponse,\n IMessageResponse,\n ISingleResponse,\n} from '@flusys/ng-shared';\nimport { firstValueFrom } from 'rxjs';\nimport {\n ITaskBoard,\n ITaskBoardMember,\n IUpdateTaskBoardDto,\n} from '../interfaces/task.interface';\n\n@Service()\nexport class TaskBoardApiService extends ApiResourceService<\n IUpdateTaskBoardDto,\n ITaskBoard\n> {\n constructor() {\n super('board', 'taskManager');\n }\n\n getMembers(boardId: string): Promise<IListResponse<ITaskBoardMember>> {\n return firstValueFrom(\n this.http.post<IListResponse<ITaskBoardMember>>(\n `${this.baseUrl}/get-members`,\n { boardId },\n ),\n );\n }\n\n addMember(\n boardId: string,\n userId: string,\n role = 'MEMBER',\n ): Promise<ISingleResponse<ITaskBoardMember>> {\n return firstValueFrom(\n this.http.post<ISingleResponse<ITaskBoardMember>>(\n `${this.baseUrl}/add-member`,\n { boardId, userId, role },\n ),\n );\n }\n\n removeMember(boardId: string, userId: string): Promise<IMessageResponse> {\n return firstValueFrom(\n this.http.post<IMessageResponse>(`${this.baseUrl}/remove-member`, {\n boardId,\n userId,\n }),\n );\n }\n}\n","import { Service } from '@angular/core';\nimport { ApiResourceService, IMessageResponse, ISingleResponse } from '@flusys/ng-shared';\nimport { firstValueFrom } from 'rxjs';\nimport {\n ICreateTaskCommentDto,\n ICreateTaskLabelDto,\n ICreateTaskListDto,\n ITask,\n ITaskComment,\n ITaskLabel,\n ITaskList,\n IMoveTaskDto,\n IReorderTaskListsDto,\n IUpdateTaskListDto,\n IUpdateTaskDto,\n} from '../interfaces/task.interface';\n\n@Service()\nexport class TaskApiService extends ApiResourceService<IUpdateTaskDto, ITask> {\n constructor() {\n super('task', 'taskManager');\n }\n\n moveTask(dto: IMoveTaskDto): Promise<ISingleResponse<ITask>> {\n return firstValueFrom(\n this.http.post<ISingleResponse<ITask>>(`${this.baseUrl}/move`, dto),\n );\n }\n}\n\n@Service()\nexport class TaskListApiService extends ApiResourceService<ICreateTaskListDto, ITaskList> {\n constructor() {\n super('list', 'taskManager');\n }\n\n updateList(dto: IUpdateTaskListDto): Promise<ISingleResponse<ITaskList>> {\n return firstValueFrom(\n this.http.post<ISingleResponse<ITaskList>>(`${this.baseUrl}/update`, dto),\n );\n }\n\n reorderLists(dto: IReorderTaskListsDto): Promise<IMessageResponse> {\n return firstValueFrom(\n this.http.post<IMessageResponse>(`${this.baseUrl}/reorder`, dto),\n );\n }\n}\n\n@Service()\nexport class TaskLabelApiService extends ApiResourceService<ICreateTaskLabelDto, ITaskLabel> {\n constructor() {\n super('label', 'taskManager');\n }\n}\n\n@Service()\nexport class TaskCommentApiService extends ApiResourceService<ICreateTaskCommentDto, ITaskComment> {\n constructor() {\n super('comment', 'taskManager');\n }\n}\n","import { inject, signal, Service } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { io, Socket } from 'socket.io-client';\nimport { APP_CONFIG } from '@flusys/ng-core';\nimport { IBoardSocketEvent } from '../interfaces/task.interface';\n\n@Service()\nexport class TaskBoardSocketService {\n private socket: Socket | null = null;\n private readonly appConfig = inject(APP_CONFIG);\n\n private readonly _isConnected = signal(false);\n readonly isConnected = this._isConnected.asReadonly();\n\n private readonly boardEvent$ = new Subject<IBoardSocketEvent>();\n readonly onBoardEvent = this.boardEvent$.asObservable();\n\n private readonly joinedBoardIds = new Set<string>();\n\n connect(accessToken: string): void {\n if (this.socket?.connected) return;\n this.teardown();\n\n const baseUrl = this.getBaseUrl();\n const socket = io(`${baseUrl}/task-boards`, {\n auth: { token: accessToken },\n transports: ['websocket', 'polling'],\n reconnection: true,\n reconnectionAttempts: 5,\n reconnectionDelay: 1000,\n });\n this.socket = socket;\n\n socket.on('connect', () => {\n this._isConnected.set(true);\n this.joinedBoardIds.forEach((boardId) => socket.emit('board:join', { boardId }));\n });\n socket.on('disconnect', (reason: string) => {\n this._isConnected.set(false);\n if (reason === 'io server disconnect') socket.connect();\n });\n socket.on('connect_error', () => this._isConnected.set(false));\n socket.on('board:event', (event: IBoardSocketEvent | null | undefined) => {\n if (event && typeof event.type === 'string' && typeof event.boardId === 'string') {\n this.boardEvent$.next(event);\n }\n });\n }\n\n joinBoard(boardId: string): void {\n this.joinedBoardIds.add(boardId);\n if (this.socket?.connected) this.socket.emit('board:join', { boardId });\n }\n\n leaveBoard(boardId: string): void {\n this.joinedBoardIds.delete(boardId);\n if (this.socket?.connected) this.socket.emit('board:leave', { boardId });\n }\n\n disconnect(): void {\n this.teardown();\n this.joinedBoardIds.clear();\n this._isConnected.set(false);\n }\n\n private teardown(): void {\n if (!this.socket) return;\n this.socket.removeAllListeners();\n this.socket.disconnect();\n this.socket = null;\n }\n\n private getBaseUrl(): string {\n const services = this.appConfig.services as Record<string, { socketUrl?: string }> | undefined;\n return services?.['taskManager']?.socketUrl ?? this.appConfig.apiBaseUrl;\n }\n}\n","import { computed, DestroyRef, inject, signal, Service } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { IBoardSocketEvent, ITask, ITaskBoard, ITaskBoardMember, ITaskLabel, ITaskList, IUpdateTaskBoardDto } from '../interfaces/task.interface';\nimport { TaskApiService, TaskLabelApiService, TaskListApiService } from './task-api.service';\nimport { TaskBoardApiService } from './task-board-api.service';\nimport { TaskBoardSocketService } from './task-board-socket.service';\n\n@Service()\nexport class TaskBoardStateService {\n private readonly boardApi = inject(TaskBoardApiService);\n private readonly taskApi = inject(TaskApiService);\n private readonly listApi = inject(TaskListApiService);\n private readonly labelApi = inject(TaskLabelApiService);\n private readonly socketService = inject(TaskBoardSocketService);\n private readonly destroyRef = inject(DestroyRef);\n\n private readonly _boards = signal<ITaskBoard[]>([]);\n private readonly _activeBoard = signal<ITaskBoard | null>(null);\n private readonly _lists = signal<ITaskList[]>([]);\n private readonly _tasks = signal<ITask[]>([]);\n private readonly _labels = signal<ITaskLabel[]>([]);\n private readonly _members = signal<ITaskBoardMember[]>([]);\n private readonly _selectedTask = signal<ITask | null>(null);\n private readonly _isLoading = signal(false);\n private readonly _isBoardLoading = signal(false);\n private openRequestId = 0;\n\n readonly boards = this._boards.asReadonly();\n readonly activeBoard = this._activeBoard.asReadonly();\n readonly lists = this._lists.asReadonly();\n readonly tasks = this._tasks.asReadonly();\n readonly labels = this._labels.asReadonly();\n readonly members = this._members.asReadonly();\n readonly selectedTask = this._selectedTask.asReadonly();\n readonly isLoading = this._isLoading.asReadonly();\n readonly isBoardLoading = this._isBoardLoading.asReadonly();\n\n readonly tasksByList = computed(() => {\n const map = new Map<string, ITask[]>();\n for (const task of this._tasks()) {\n const list = map.get(task.listId) ?? [];\n list.push(task);\n map.set(task.listId, list);\n }\n return map;\n });\n\n readonly listsWithTasks = computed(() =>\n this._lists()\n .slice()\n .sort((a, b) => a.position - b.position)\n .map((list) => ({\n ...list,\n tasks: (this.tasksByList().get(list.id) ?? []).slice().sort((a, b) => a.position - b.position),\n })),\n );\n\n readonly hasActiveBoard = computed(() => this._activeBoard() !== null);\n readonly isSocketConnected = this.socketService.isConnected;\n\n constructor() {\n this.socketService.onBoardEvent\n .pipe(takeUntilDestroyed(this.destroyRef))\n .subscribe((event) => this.handleBoardEvent(event));\n }\n\n async loadBoards(): Promise<void> {\n this._isLoading.set(true);\n try {\n const res = await this.boardApi.getAll({ sort: { createdAt: 'DESC' } });\n this._boards.set(res.data ?? []);\n } finally {\n this._isLoading.set(false);\n }\n }\n\n async openBoard(boardId: string): Promise<void> {\n const request = ++this.openRequestId;\n this._isBoardLoading.set(true);\n try {\n const prevBoard = this._activeBoard();\n if (prevBoard && prevBoard.id !== boardId) this.socketService.leaveBoard(prevBoard.id);\n\n const [boardRes, listsRes, tasksRes, labelsRes, membersRes] = await Promise.all([\n this.boardApi.findById(boardId),\n this.listApi.getAll({ filter: { boardId, isActive: true }, sort: { position: 'ASC' } }),\n this.taskApi.getAll({ filter: { boardId }, sort: { position: 'ASC' } }),\n this.labelApi.getAll({ filter: { boardId } }),\n this.boardApi.getMembers(boardId),\n ]);\n if (request !== this.openRequestId) return;\n\n this._activeBoard.set(boardRes.data ?? null);\n this._lists.set(listsRes.data ?? []);\n this._tasks.set(tasksRes.data ?? []);\n this._labels.set(labelsRes.data ?? []);\n this._members.set(membersRes.data ?? []);\n\n this.socketService.joinBoard(boardId);\n } catch (error) {\n if (request === this.openRequestId) this.resetBoardState();\n throw error;\n } finally {\n if (request === this.openRequestId) this._isBoardLoading.set(false);\n }\n }\n\n closeBoard(): void {\n this.openRequestId++;\n const board = this._activeBoard();\n if (board) this.socketService.leaveBoard(board.id);\n this.resetBoardState();\n this._isBoardLoading.set(false);\n }\n\n private resetBoardState(): void {\n this._activeBoard.set(null);\n this._lists.set([]);\n this._tasks.set([]);\n this._labels.set([]);\n this._members.set([]);\n this._selectedTask.set(null);\n }\n\n selectTask(task: ITask | null): void {\n this._selectedTask.set(task);\n }\n\n async addLabel(boardId: string, name: string, color: string): Promise<void> {\n await this.labelApi.insert({ boardId, name, color });\n const res = await this.labelApi.getAll({ filter: { boardId } });\n this._labels.set(res.data ?? []);\n }\n\n async deleteLabel(labelId: string): Promise<void> {\n await this.labelApi.delete({ id: labelId, type: 'delete' });\n this._labels.update((list) => list.filter((l) => l.id !== labelId));\n }\n\n async addMember(userId: string, role = 'MEMBER'): Promise<void> {\n const board = this._activeBoard();\n if (!board) return;\n const res = await this.boardApi.addMember(board.id, userId, role);\n if (res.data) this._members.update((list) => [...list, res.data!]);\n }\n\n async removeMember(userId: string): Promise<void> {\n const board = this._activeBoard();\n if (!board) return;\n await this.boardApi.removeMember(board.id, userId);\n this._members.update((list) => list.filter((m) => m.userId !== userId));\n }\n\n async reorderLists(boardId: string, orderedIds: string[]): Promise<void> {\n const previousPositions = new Map(this._lists().map((l) => [l.id, l.position]));\n this.applyListOrder(orderedIds);\n try {\n await this.listApi.reorderLists({ boardId, orderedIds });\n } catch (error) {\n this._lists.update((list) =>\n list\n .map((l) => (previousPositions.has(l.id) ? { ...l, position: previousPositions.get(l.id)! } : l))\n .sort((a, b) => a.position - b.position),\n );\n throw error;\n }\n }\n\n async moveTask(taskId: string, targetListId: string, targetIndex: number): Promise<void> {\n const task = this._tasks().find((t) => t.id === taskId);\n if (!task) return;\n\n const siblings = this._tasks()\n .filter((t) => t.listId === targetListId && t.id !== taskId)\n .sort((a, b) => a.position - b.position);\n const index = Math.min(Math.max(Math.trunc(targetIndex) || 0, 0), siblings.length);\n const position = positionBetween(siblings[index - 1]?.position, siblings[index]?.position);\n const original = { listId: task.listId, position: task.position };\n\n this._tasks.update((list) =>\n list.map((t) => (t.id === taskId ? { ...t, listId: targetListId, position } : t)),\n );\n try {\n await this.taskApi.moveTask({ taskId, targetListId, position });\n } catch (error) {\n this._tasks.update((list) => list.map((t) => (t.id === taskId ? { ...t, ...original } : t)));\n throw error;\n }\n }\n\n async renameList(listId: string, name: string): Promise<void> {\n await this.listApi.updateList({ id: listId, name });\n this._lists.update((list) => list.map((l) => (l.id === listId ? { ...l, name } : l)));\n }\n\n async updateBoard(dto: IUpdateTaskBoardDto): Promise<void> {\n await this.boardApi.update(dto);\n const id = dto.id;\n if (!id) return;\n this._activeBoard.update((b) => (b?.id === id ? { ...b, ...dto } : b));\n this._boards.update((list) => list.map((b) => (b.id === id ? { ...b, ...dto } : b)));\n }\n\n addTaskOptimistic(task: ITask): void {\n this._tasks.update((list) => {\n if (list.some((t) => t.id === task.id)) {\n return list.map((t) => (t.id === task.id ? { ...t, ...task } : t));\n }\n return [...list, task];\n });\n }\n\n async deleteTask(taskId: string): Promise<void> {\n await this.taskApi.delete({ id: taskId, type: 'delete' });\n this._tasks.update((list) => list.filter((t) => t.id !== taskId));\n if (this._selectedTask()?.id === taskId) this._selectedTask.set(null);\n }\n\n private applyListOrder(orderedIds: string[]): void {\n const posMap = new Map(orderedIds.map((id, i) => [id, i * 100]));\n this._lists.update((list) =>\n list\n .map((l) => (posMap.has(l.id) ? { ...l, position: posMap.get(l.id)! } : l))\n .sort((a, b) => a.position - b.position),\n );\n }\n\n private handleBoardEvent(event: IBoardSocketEvent): void {\n const activeBoardId = this._activeBoard()?.id;\n if (!activeBoardId || event.boardId !== activeBoardId) return;\n\n if (event.type === 'list:reordered') {\n const orderedIds = (event.payload as { orderedIds?: unknown } | null)?.orderedIds;\n if (Array.isArray(orderedIds)) this.applyListOrder(orderedIds.filter((id): id is string => typeof id === 'string'));\n return;\n }\n if (!hasId(event.payload)) return;\n\n switch (event.type) {\n case 'task:created': {\n const created = event.payload as ITask;\n this._tasks.update((list) => {\n if (list.some((t) => t.id === created.id)) return list;\n return [...list, created];\n });\n break;\n }\n\n case 'task:updated':\n case 'task:moved': {\n const updated = event.payload as ITask;\n this._tasks.update((list) =>\n list.map((t) => (t.id === updated.id ? { ...t, ...updated } : t)),\n );\n if (this._selectedTask()?.id === updated.id) {\n this._selectedTask.update((t) => (t ? { ...t, ...updated } : null));\n }\n break;\n }\n\n case 'task:deleted': {\n const deleted = event.payload as { id: string };\n this._tasks.update((list) => list.filter((t) => t.id !== deleted.id));\n if (this._selectedTask()?.id === deleted.id) this._selectedTask.set(null);\n break;\n }\n\n case 'list:created': {\n const created = event.payload as ITaskList;\n this._lists.update((list) => (list.some((l) => l.id === created.id) ? list : [...list, created]));\n break;\n }\n\n case 'list:updated': {\n const updatedList = event.payload as ITaskList;\n this._lists.update((list) =>\n list.map((l) => (l.id === updatedList.id ? { ...l, ...updatedList } : l)),\n );\n break;\n }\n\n case 'list:deleted': {\n const deletedList = event.payload as { id: string };\n this._lists.update((list) => list.filter((l) => l.id !== deletedList.id));\n break;\n }\n\n }\n }\n}\n\nconst MAX_POSITION = 2_147_483_647;\n\nfunction positionBetween(before: number | undefined, after: number | undefined): number {\n if (before === undefined && after === undefined) return 0;\n if (before === undefined) return Math.max(0, Math.floor(after! / 2));\n if (after === undefined) return Math.min(MAX_POSITION, before + 100);\n return Math.floor((before + after) / 2);\n}\n\nfunction hasId(payload: unknown): payload is { id: string } {\n return typeof payload === 'object' && payload !== null && typeof (payload as { id?: unknown }).id === 'string';\n}\n","export const MEMBER_COLOR_PALETTE = [\n '#6366f1',\n '#8b5cf6',\n '#ec4899',\n '#ef4444',\n '#f97316',\n '#eab308',\n '#22c55e',\n '#14b8a6',\n '#3b82f6',\n '#06b6d4',\n];\n\nexport const BOARD_COLOR_PALETTE = [\n ...MEMBER_COLOR_PALETTE,\n '#64748b',\n];\n\nexport function taskPrioritySeverity(\n priority: string,\n): 'success' | 'info' | 'warn' | 'danger' | 'secondary' {\n const map: Record<string, 'success' | 'info' | 'warn' | 'danger' | 'secondary'> = {\n LOW: 'secondary',\n MEDIUM: 'info',\n HIGH: 'warn',\n URGENT: 'danger',\n };\n return map[priority] ?? 'info';\n}\n\nexport function memberInitials(name: string | null | undefined): string {\n if (!name) return '?';\n return name\n .split(' ')\n .slice(0, 2)\n .map((n) => n[0]?.toUpperCase() ?? '')\n .join('');\n}\n\nconst DATE_ONLY_PATTERN = /^(\\d{4})-(\\d{2})-(\\d{2})/;\n\nexport function toDateOnlyString(date: Date): string {\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${date.getFullYear()}-${month}-${day}`;\n}\n\nexport function parseDateOnly(value: string | null | undefined): Date | null {\n const match = value ? DATE_ONLY_PATTERN.exec(value) : null;\n if (!match) return null;\n return new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]), 12, 0, 0);\n}\n\nexport function isTaskOverdue(dueDate: string | null | undefined): boolean {\n if (!dueDate || !DATE_ONLY_PATTERN.test(dueDate)) return false;\n return dueDate.slice(0, 10) < toDateOnlyString(new Date());\n}\n\nexport function memberColorFromId(userId: string): string {\n let hash = 0;\n for (let i = 0; i < userId.length; i++)\n hash = userId.charCodeAt(i) + ((hash << 5) - hash);\n return MEMBER_COLOR_PALETTE[Math.abs(hash) % MEMBER_COLOR_PALETTE.length];\n}\n","import { DatePipe } from '@angular/common';\nimport { Component, computed, input, output } from '@angular/core';\nimport { TranslatePipe } from '@flusys/ng-shared';\nimport { AvatarComponent, TagComponent, TooltipDirective, UiIconComponent } from '@flusys/ng-ui';\nimport { ITask } from '../../interfaces/task.interface';\nimport {\n isTaskOverdue,\n memberColorFromId,\n memberInitials,\n taskPrioritySeverity,\n} from '../../utils/task-utils';\n\n@Component({\n selector: 'tm-task-card',\n imports: [DatePipe, TranslatePipe, TooltipDirective, AvatarComponent, TagComponent, UiIconComponent],\n template: `\n <div\n class=\"task-card group relative rounded-border border border-surface p-3 cursor-pointer shadow-sm hover:shadow-md transition-shadow\"\n (click)=\"cardClick.emit(task())\"\n >\n <div class=\"absolute top-2 right-2 hidden group-hover:flex gap-0.5\">\n <button\n class=\"w-6 h-6 flex items-center justify-center rounded text-muted-color hover:text-primary-500 hover:bg-surface-hover transition-colors\"\n [fTooltip]=\"'shared.edit' | translate\"\n tooltipPosition=\"top\"\n (click)=\"$event.stopPropagation(); editClick.emit(task())\"\n >\n <ui-icon name=\"pencil\" class=\"text-xs\"></ui-icon>\n </button>\n <button\n class=\"w-6 h-6 flex items-center justify-center rounded text-muted-color hover:text-red-500 hover:bg-surface-hover transition-colors\"\n [fTooltip]=\"'shared.delete' | translate\"\n tooltipPosition=\"top\"\n (click)=\"$event.stopPropagation(); deleteClick.emit(task())\"\n >\n <ui-icon name=\"trash\" class=\"text-xs\"></ui-icon>\n </button>\n </div>\n\n @if (task().labels && task().labels!.length > 0) {\n <div class=\"flex flex-wrap gap-1 mb-2\">\n @for (label of task().labels; track label.id) {\n <span\n class=\"inline-block h-1.5 rounded-full w-8\"\n [style.background-color]=\"label.color\"\n [fTooltip]=\"label.name\"\n ></span>\n }\n </div>\n }\n\n <p class=\"text-sm font-semibold line-clamp-2 leading-snug pr-14\">\n {{ task().title }}\n </p>\n\n <div class=\"flex items-center justify-between gap-2 mt-auto pt-2\">\n <f-tag\n [value]=\"('task.priority.' + task().priority) | translate\"\n [severity]=\"prioritySeverity(task().priority)\"\n class=\"text-xs\"\n />\n\n @if (task().dueDate) {\n <span\n class=\"text-xs text-muted-color\"\n [class.text-red-500]=\"isOverdue(task().dueDate!)\"\n >\n {{ task().dueDate | date: 'MMM d' }}\n </span>\n }\n\n @if (visibleAssignees().length > 0) {\n <div class=\"flex items-center -space-x-1.5\">\n @for (a of visibleAssignees(); track a.userId) {\n <f-avatar\n shape=\"circle\"\n size=\"small\"\n [label]=\"initials(a.userName)\"\n [color]=\"memberColor(a.userId)\"\n styleClass=\"!ring-surface-card flex-shrink-0\"\n [fTooltip]=\"a.userName ?? ''\"\n />\n }\n @if (overflowCount() > 0) {\n <f-avatar\n shape=\"circle\"\n size=\"small\"\n [label]=\"'+' + overflowCount()\"\n styleClass=\"!bg-surface-200 dark:!bg-surface-700 !text-surface-600 dark:!text-surface-300 !ring-surface-card flex-shrink-0\"\n />\n }\n </div>\n }\n </div>\n </div>\n `,\n})\nexport class TaskCardComponent {\n readonly task = input.required<ITask>();\n readonly cardClick = output<ITask>();\n readonly editClick = output<ITask>();\n readonly deleteClick = output<ITask>();\n\n private readonly MAX_VISIBLE = 3;\n\n readonly visibleAssignees = computed(() =>\n (this.task().assignees ?? []).slice(0, this.MAX_VISIBLE),\n );\n\n readonly overflowCount = computed(() =>\n Math.max(0, (this.task().assignees ?? []).length - this.MAX_VISIBLE),\n );\n\n protected readonly prioritySeverity = taskPrioritySeverity;\n protected readonly initials = memberInitials;\n protected readonly isOverdue = isTaskOverdue;\n protected readonly memberColor = memberColorFromId;\n}\n","import {\n Component,\n effect,\n inject,\n input,\n model,\n output,\n signal,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { form, FormField, required } from '@angular/forms/signals';\nimport { TranslatePipe } from '@flusys/ng-shared';\nimport {\n DatePickerComponent,\n DialogComponent,\n FButtonDirective,\n InputTextDirective,\n MultiSelectComponent,\n SelectComponent,\n TextareaDirective,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport {\n ICreateTaskDto,\n ITask,\n ITaskBoardMember,\n ITaskLabel,\n IUpdateTaskDto,\n TaskPriority,\n} from '../../interfaces/task.interface';\nimport { TaskApiService } from '../../services/task-api.service';\nimport { parseDateOnly, toDateOnlyString } from '../../utils/task-utils';\n\nconst PRIORITY_OPTIONS = [\n { labelKey: 'task.priority.LOW', value: 'LOW' },\n { labelKey: 'task.priority.MEDIUM', value: 'MEDIUM' },\n { labelKey: 'task.priority.HIGH', value: 'HIGH' },\n { labelKey: 'task.priority.URGENT', value: 'URGENT' },\n];\n\n@Component({\n selector: 'tm-task-form-dialog',\n imports: [\n DatePickerComponent,\n DialogComponent,\n FButtonDirective,\n InputTextDirective,\n MultiSelectComponent,\n SelectComponent,\n TextareaDirective,\n UiIconComponent,\n FormsModule,\n FormField,\n TranslatePipe,\n ],\n template: `\n <f-dialog\n [header]=\"\n (task() ? 'task.form.title.edit' : 'task.form.title.create') | translate\n \"\n [(visible)]=\"visible\"\n [modal]=\"true\"\n [style]=\"{ width: '540px' }\"\n (onHide)=\"onClose()\"\n >\n <div class=\"flex flex-col gap-4 py-3\">\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-sm font-medium\"\n >{{ 'task.form.title.label' | translate }}\n <span class=\"text-red-500\">*</span></label\n >\n <input\n fInputText\n [formField]=\"taskForm.title\"\n [placeholder]=\"'task.form.title.placeholder' | translate\"\n />\n </div>\n\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-sm font-medium\">{{\n 'shared.description' | translate\n }}</label>\n <textarea\n fTextarea\n [formField]=\"taskForm.description\"\n rows=\"3\"\n [placeholder]=\"'task.form.description.placeholder' | translate\"\n ></textarea>\n </div>\n\n <div class=\"grid grid-cols-2 gap-4\">\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-sm font-medium\">{{\n 'task.form.priority.label' | translate\n }}</label>\n <f-select\n [formField]=\"taskForm.priority\"\n [options]=\"priorityOptions\"\n optionLabel=\"labelKey\"\n optionValue=\"value\"\n [placeholder]=\"'task.form.priority.placeholder' | translate\"\n >\n <ng-template #selectedItem let-opt>\n {{ opt.labelKey | translate }}\n </ng-template>\n <ng-template #item let-opt>\n {{ opt.labelKey | translate }}\n </ng-template>\n </f-select>\n </div>\n\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-sm font-medium\">{{\n 'task.form.due.date.label' | translate\n }}</label>\n <f-datepicker\n [ngModel]=\"dueDate()\"\n (ngModelChange)=\"dueDate.set($event)\"\n [showClear]=\"true\"\n [placeholder]=\"'task.form.due.date.placeholder' | translate\"\n />\n </div>\n </div>\n\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-sm font-medium\">{{\n 'task.form.assignee.label' | translate\n }}</label>\n <f-multiselect\n [ngModel]=\"selectedAssigneeIds()\"\n (ngModelChange)=\"selectedAssigneeIds.set($event)\"\n [options]=\"members()\"\n optionLabel=\"userName\"\n optionValue=\"userId\"\n [selectedObjects]=\"task()?.assignees ?? []\"\n [placeholder]=\"'task.form.assignee.placeholder' | translate\"\n [showClear]=\"true\"\n />\n </div>\n\n <div class=\"flex flex-col gap-1\">\n <label class=\"text-sm font-medium\">{{\n 'task.form.labels.label' | translate\n }}</label>\n <f-multiselect\n [ngModel]=\"selectedLabelIds()\"\n (ngModelChange)=\"selectedLabelIds.set($event)\"\n [options]=\"labels()\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [placeholder]=\"'task.form.labels.placeholder' | translate\"\n />\n </div>\n </div>\n\n <ng-template #footer>\n <div class=\"flex justify-end gap-2 pt-1\">\n <button fButton severity=\"secondary\" (click)=\"onClose()\">\n <span pButtonLabel>{{ 'shared.cancel' | translate }}</span>\n </button>\n <button fButton (click)=\"onSave()\" [disabled]=\"isSaving()\">\n @if (isSaving()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n }\n <span pButtonLabel>{{ 'shared.save' | translate }}</span>\n </button>\n </div>\n </ng-template>\n </f-dialog>\n `,\n})\nexport class TaskFormDialogComponent {\n private readonly taskApi = inject(TaskApiService);\n\n readonly visible = model(false);\n readonly task = input<ITask | null>(null);\n readonly boardId = input.required<string>();\n readonly listId = input.required<string>();\n readonly members = input<ITaskBoardMember[]>([]);\n readonly labels = input<ITaskLabel[]>([]);\n readonly saved = output<ITask>();\n\n readonly isSaving = signal(false);\n readonly priorityOptions = PRIORITY_OPTIONS;\n\n readonly formModel = signal({\n title: '',\n description: '',\n priority: 'MEDIUM' as TaskPriority,\n });\n readonly taskForm = form(this.formModel, (f) => {\n required(f.title);\n });\n\n readonly dueDate = signal<Date | null>(null);\n readonly selectedAssigneeIds = signal<string[]>([]);\n readonly selectedLabelIds = signal<string[]>([]);\n\n constructor() {\n effect(() => {\n const t = this.task();\n if (t) {\n this.formModel.set({\n title: t.title,\n description: t.description ?? '',\n priority: t.priority,\n });\n this.dueDate.set(parseDateOnly(t.dueDate));\n this.selectedAssigneeIds.set(t.assignees?.map((a) => a.userId) ?? []);\n this.selectedLabelIds.set(t.labelIds ?? []);\n } else {\n this.reset();\n }\n });\n }\n\n async onSave(): Promise<void> {\n const { title, description, priority } = this.formModel();\n if (!title.trim()) return;\n this.isSaving.set(true);\n try {\n const dueDate = this.dueDate();\n const dueDateStr = dueDate ? toDateOnlyString(dueDate) : null;\n const existing = this.task();\n const assigneeIds = this.selectedAssigneeIds();\n const labelIds = this.selectedLabelIds();\n let result;\n\n if (existing) {\n const dto: IUpdateTaskDto = {\n id: existing.id,\n title,\n description: description || undefined,\n priority,\n dueDate: dueDateStr,\n assigneeIds,\n labelIds,\n };\n result = await this.taskApi.update(dto);\n } else {\n const dto: ICreateTaskDto = {\n boardId: this.boardId(),\n listId: this.listId(),\n title,\n description: description || undefined,\n priority,\n dueDate: dueDateStr ?? undefined,\n assigneeIds,\n labelIds,\n };\n result = await this.taskApi.insert(dto);\n }\n\n if (result.data) this.saved.emit(result.data);\n this.visible.set(false);\n } finally {\n this.isSaving.set(false);\n }\n }\n\n onClose(): void {\n this.visible.set(false);\n this.reset();\n }\n\n private reset(): void {\n this.formModel.set({ title: '', description: '', priority: 'MEDIUM' });\n this.dueDate.set(null);\n this.selectedAssigneeIds.set([]);\n this.selectedLabelIds.set([]);\n }\n}\n","import { DatePipe } from '@angular/common';\nimport {\n Component,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n untracked,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { TranslatePipe } from '@flusys/ng-shared';\nimport {\n AvatarComponent,\n DrawerComponent,\n FButtonDirective,\n TagComponent,\n TextareaDirective,\n TooltipDirective,\n UiIconComponent,\n} from '@flusys/ng-ui';\nimport { ITask, ITaskComment } from '../../interfaces/task.interface';\nimport { TaskCommentApiService } from '../../services/task-api.service';\nimport { TaskBoardStateService } from '../../services/task-board-state.service';\nimport { memberInitials, taskPrioritySeverity } from '../../utils/task-utils';\n\n@Component({\n selector: 'tm-task-detail-panel',\n imports: [\n AvatarComponent,\n DrawerComponent,\n FButtonDirective,\n TagComponent,\n TextareaDirective,\n TooltipDirective,\n UiIconComponent,\n DatePipe,\n FormsModule,\n TranslatePipe,\n ],\n template: `\n <f-drawer\n [visible]=\"!!task()\"\n position=\"right\"\n [style]=\"{ width: '500px' }\"\n [header]=\"task()?.title ?? ''\"\n (onHide)=\"closePanel.emit()\"\n >\n @if (task(); as t) {\n <div class=\"flex flex-col gap-6 h-full overflow-y-auto pb-4\">\n <div class=\"flex items-center justify-end gap-1\">\n <button\n fButton\n severity=\"secondary\"\n size=\"small\"\n [text]=\"true\"\n [fTooltip]=\"'task.detail.edit' | translate\"\n tooltipPosition=\"left\"\n (click)=\"editTask.emit(t)\"\n >\n <ui-icon pButtonIcon name=\"pencil\"></ui-icon>\n </button>\n <button\n fButton\n severity=\"danger\"\n size=\"small\"\n [text]=\"true\"\n [fTooltip]=\"'task.detail.delete' | translate\"\n tooltipPosition=\"left\"\n (click)=\"deleteTask(t.id)\"\n [disabled]=\"isDeleting()\"\n >\n @if (isDeleting()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n } @else {\n <ui-icon pButtonIcon name=\"trash\"></ui-icon>\n }\n </button>\n </div>\n\n <div class=\"flex items-center gap-3\">\n <f-tag\n [value]=\"('task.priority.' + t.priority) | translate\"\n [severity]=\"prioritySeverity(t.priority)\"\n />\n @if (t.dueDate) {\n <span class=\"text-sm text-muted-color\">\n {{ 'task.detail.due.label' | translate }}:\n {{ t.dueDate | date: 'mediumDate' }}\n </span>\n }\n </div>\n\n @if (assigneeMembers().length > 0) {\n <div>\n <h4 class=\"text-sm font-semibold mb-2\">\n {{ 'task.detail.assignees.label' | translate }}\n </h4>\n <div class=\"flex flex-wrap gap-2\">\n @for (member of assigneeMembers(); track member.userId) {\n <div class=\"flex items-center gap-2 px-2 py-1 rounded-full \">\n <f-avatar\n shape=\"circle\"\n size=\"small\"\n [label]=\"initials(member.userName)\"\n styleClass=\"!bg-primary-100 dark:!bg-primary-900 !text-primary-700 dark:!text-primary-300\"\n />\n <span class=\"text-sm\">{{ member.userName }}</span>\n </div>\n }\n </div>\n </div>\n }\n\n <div>\n <h4 class=\"text-sm font-semibold mb-2\">\n {{ 'shared.description' | translate }}\n </h4>\n <p class=\"text-sm text-color whitespace-pre-wrap\">\n {{\n t.description || ('task.detail.description.empty' | translate)\n }}\n </p>\n </div>\n\n <div class=\"flex flex-col gap-1\">\n <h4 class=\"text-sm font-semibold mb-1\">\n {{ 'task.detail.comments.label' | translate }} ({{\n rootComments().length\n }})\n </h4>\n\n @for (comment of rootComments(); track comment.id) {\n <div\n class=\"group flex flex-col gap-1 py-2 border-b border-surface last:border-0\"\n >\n <div class=\"flex items-center justify-between\">\n <span class=\"text-xs text-muted-color\">{{\n comment.createdAt | date: 'MMM d, y, h:mm a'\n }}</span>\n <button\n fButton\n size=\"small\"\n [text]=\"true\"\n severity=\"secondary\"\n class=\"opacity-0 group-hover:opacity-100 transition-opacity !py-0.5 !px-1.5 text-xs\"\n (click)=\"toggleReply(comment.id)\"\n >\n <ui-icon pButtonIcon name=\"reply\"></ui-icon>\n <span pButtonLabel>{{ 'task.comment.reply' | translate }}</span>\n </button>\n </div>\n <p class=\"text-sm\">{{ comment.content }}</p>\n\n @if (repliesFor(comment.id).length > 0) {\n <div\n class=\"mt-1 pl-3 border-l-2 border-surface flex flex-col gap-2\"\n >\n @for (reply of repliesFor(comment.id); track reply.id) {\n <div class=\"flex flex-col gap-0.5\">\n <span class=\"text-xs text-muted-color\">{{\n reply.createdAt | date: 'MMM d, y, h:mm a'\n }}</span>\n <p class=\"text-sm\">{{ reply.content }}</p>\n </div>\n }\n </div>\n }\n\n @if (replyingToId() === comment.id) {\n <div\n class=\"mt-2 pl-3 border-l-2 border-primary-300 dark:border-primary-700 flex gap-2\"\n >\n <textarea\n fTextarea\n [ngModel]=\"replyText()\"\n (ngModelChange)=\"replyText.set($event)\"\n rows=\"2\"\n [placeholder]=\"\n 'task.comment.reply.placeholder' | translate\n \"\n class=\"flex-1 resize-none text-sm\"\n autoResize=\"true\"\n ></textarea>\n <div class=\"flex flex-col gap-1\">\n <button\n fButton\n size=\"small\"\n [disabled]=\"!replyText().trim() || isSendingReply()\"\n (click)=\"submitReply(t.id, comment.id)\"\n >\n @if (isSendingReply()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n } @else {\n <ui-icon pButtonIcon name=\"send\"></ui-icon>\n }\n </button>\n <button\n fButton\n size=\"small\"\n severity=\"secondary\"\n [text]=\"true\"\n (click)=\"cancelReply()\"\n >\n <ui-icon pButtonIcon name=\"times\"></ui-icon>\n </button>\n </div>\n </div>\n }\n </div>\n }\n\n @if (rootComments().length === 0) {\n <p class=\"text-sm text-muted-color py-2\">\n {{ 'task.detail.comments.empty' | translate }}\n </p>\n }\n\n <div class=\"flex gap-2 mt-3\">\n <textarea\n fTextarea\n [ngModel]=\"newComment()\"\n (ngModelChange)=\"newComment.set($event)\"\n rows=\"2\"\n [placeholder]=\"'task.detail.comment.placeholder' | translate\"\n class=\"flex-1 resize-none\"\n ></textarea>\n <button\n fButton\n [disabled]=\"!newComment().trim() || isSendingComment()\"\n (click)=\"addComment(t.id)\"\n >\n @if (isSendingComment()) {\n <ui-icon pButtonIcon name=\"spinner\" [spin]=\"true\"></ui-icon>\n } @else {\n <ui-icon pButtonIcon name=\"send\"></ui-icon>\n }\n </button>\n </div>\n </div>\n </div>\n }\n </f-drawer>\n `,\n})\nexport class TaskDetailPanelComponent {\n private readonly commentApi = inject(TaskCommentApiService);\n private readonly state = inject(TaskBoardStateService);\n\n readonly task = input<ITask | null>(null);\n\n readonly closePanel = output<void>();\n readonly editTask = output<ITask>();\n\n readonly comments = signal<ITaskComment[]>([]);\n readonly isSendingComment = signal(false);\n readonly isSendingReply = signal(false);\n readonly replyingToId = signal<string | null>(null);\n readonly isDeleting = signal(false);\n\n readonly newComment = signal('');\n readonly replyText = signal('');\n\n readonly assigneeMembers = computed(() => this.task()?.assignees ?? []);\n\n readonly rootComments = computed(() =>\n this.comments().filter((c) => !c.parentCommentId),\n );\n\n repliesFor(parentId: string): ITaskComment[] {\n return this.comments().filter((c) => c.parentCommentId === parentId);\n }\n\n private readonly taskId = computed(() => this.task()?.id ?? null);\n\n constructor() {\n effect(() => {\n const id = this.taskId();\n untracked(() => {\n this.comments.set([]);\n this.cancelReply();\n if (id) void this.loadComments(id);\n });\n });\n }\n\n toggleReply(commentId: string): void {\n if (this.replyingToId() === commentId) {\n this.cancelReply();\n } else {\n this.replyingToId.set(commentId);\n this.replyText.set('');\n }\n }\n\n cancelReply(): void {\n this.replyingToId.set(null);\n this.replyText.set('');\n }\n\n async deleteTask(taskId: string): Promise<void> {\n this.isDeleting.set(true);\n try {\n await this.state.deleteTask(taskId);\n this.closePanel.emit();\n } finally {\n this.isDeleting.set(false);\n }\n }\n\n protected readonly prioritySeverity = taskPrioritySeverity;\n protected readonly initials = memberInitials;\n\n private async loadComments(taskId: string): Promise<void> {\n let comments: ITaskComment[] = [];\n try {\n const res = await this.commentApi.getAll({ filter: { taskId } });\n comments = res.data ?? [];\n } catch {\n comments = [];\n }\n if (this.task()?.id === taskId) this.comments.set(comments);\n }\n\n async addComment(taskId: string): Promise<void> {\n if (!this.newComment().trim()) return;\n this.isSendingComment.set(true);\n try {\n const res = await this.commentApi.insert({\n taskId,\n content: this.newComment(),\n });\n if (res.data) this.comments.update((list) => [...list, res.data!]);\n this.newComment.set('');\n } finally {\n this.isSendingComment.set(false);\n }\n }\n\n async submitReply(taskId: string, parentCommentId: string): Promise<void> {\n if (!this.replyText().trim()) return;\n this.isSendingReply.set(true);\n try {\n const res = await this.commentApi.insert({\n taskId,\n content: this.replyText(),\n parentCommentId,\n });\n if (res.data) this.comments.update((list) => [...list, res.data!]);\n this.cancelReply();\n } finally {\n this.isSendingReply.set(false);\n }\n }\n}\n","export const TASK_MANAGER_MESSAGES = {\n // Board API messages (keys must match NestJS message-keys.ts)\n 'task.board.not.found': 'Board not found',\n 'task.board.create.success': 'Board created successfully',\n 'task.board.create.many.success': 'Boards created successfully',\n 'task.board.get.success': 'Board retrieved successfully',\n 'task.board.get.all.success': 'Boards retrieved successfully',\n 'task.board.update.success': 'Board updated successfully',\n 'task.board.update.many.success': 'Boards updated successfully',\n 'task.board.delete.success': 'Board deleted successfully',\n 'task.board.restore.success': 'Board restored successfully',\n 'task.board.member.added': 'Member added to board',\n 'task.board.member.removed': 'Member removed from board',\n 'task.board.member.not.found': 'Board member not found',\n 'task.board.member.already.exists': 'User is already a board member',\n 'task.board.member.get.all.success': 'Board members retrieved successfully',\n\n 'task.list.not.found': 'List not found',\n 'task.list.create.success': 'List created successfully',\n 'task.list.create.many.success': 'Lists created successfully',\n 'task.list.get.success': 'List retrieved successfully',\n 'task.list.get.all.success': 'Lists retrieved successfully',\n 'task.list.update.success': 'List updated successfully',\n 'task.list.update.many.success': 'Lists updated successfully',\n 'task.list.delete.success': 'List deleted successfully',\n 'task.list.restore.success': 'List restored successfully',\n 'task.list.reorder.success': 'Lists reordered successfully',\n\n 'task.not.found': 'Task not found',\n 'task.create.success': 'Task created successfully',\n 'task.create.many.success': 'Tasks created successfully',\n 'task.get.success': 'Task retrieved successfully',\n 'task.get.all.success': 'Tasks retrieved successfully',\n 'task.update.success': 'Task updated successfully',\n 'task.update.many.success': 'Tasks updated successfully',\n 'task.delete.success': 'Task deleted successfully',\n 'task.restore.success': 'Task restored successfully',\n 'task.move.success': 'Task moved successfully',\n 'task.assign.success': 'Task assigned successfully',\n 'task.assignee.not.board.member': 'Assignee is not a board member',\n\n 'task.label.not.found': 'Label not found',\n 'task.label.create.success': 'Label created successfully',\n 'task.label.create.many.success': 'Labels created successfully',\n 'task.label.get.success': 'Label retrieved successfully',\n 'task.label.get.all.success': 'Labels retrieved successfully',\n 'task.label.update.success': 'Label updated successfully',\n 'task.label.update.many.success': 'Labels updated successfully',\n 'task.label.delete.success': 'Label deleted successfully',\n 'task.label.restore.success': 'Label restored successfully',\n\n 'task.comment.not.found': 'Comment not found',\n 'task.comment.create.success': 'Comment added successfully',\n 'task.comment.create.many.success': 'Comments added successfully',\n 'task.comment.get.success': 'Comment retrieved successfully',\n 'task.comment.get.all.success': 'Comments retrieved successfully',\n 'task.comment.update.success': 'Comment updated successfully',\n 'task.comment.update.many.success': 'Comments updated successfully',\n 'task.comment.delete.success': 'Comment deleted successfully',\n 'task.comment.restore.success': 'Comment restored successfully',\n 'task.comment.forbidden': \"Cannot edit another user's comment\",\n\n 'task.manager.boards.title': 'Task Boards',\n 'task.manager.boards.subtitle': 'Manage and organize your project boards',\n 'task.manager.board.new': 'New Board',\n 'task.manager.board.name.placeholder': 'e.g. Product Backlog',\n 'task.manager.board.description.placeholder': 'Optional description',\n 'task.manager.board.color.label': 'Board Color',\n 'task.manager.board.empty': 'No boards yet',\n 'task.manager.board.empty.hint': 'Create your first board to get started',\n 'task.manager.board.members': 'Members',\n 'task.manager.board.lists': 'Lists',\n 'task.manager.board.tasks': 'Tasks',\n\n 'task.manager.board.add.list': 'Add List',\n 'task.manager.board.add.task': 'Add task',\n 'task.manager.board.drop.tasks.here': 'Drop tasks here',\n 'task.manager.board.list.empty':\n 'No lists yet. Click \"Add List\" to create one.',\n 'task.manager.list.new': 'New List',\n 'task.manager.list.name.label': 'List Name',\n 'task.manager.list.name.placeholder': 'e.g. In Progress',\n 'task.manager.list.rename': 'Rename List',\n\n 'task.manager.board.manage.members': 'Members',\n 'task.manager.member.manage.title': 'Manage Members',\n 'task.manager.member.add': 'Add Member',\n 'task.manager.member.no.members': 'No members yet.',\n 'task.manager.member.user.label': 'User',\n 'task.manager.member.user.placeholder': 'Search by name or email',\n 'task.manager.member.role.label': 'Role',\n 'task.manager.member.role.placeholder': 'Select role',\n 'task.manager.member.role.owner': 'Owner',\n 'task.manager.member.role.admin': 'Admin',\n 'task.manager.member.role.member': 'Member',\n 'task.manager.member.role.viewer': 'Viewer',\n\n 'task.manager.board.manage.labels': 'Labels',\n 'task.manager.label.manage.title': 'Manage Labels',\n 'task.manager.label.name.label': 'Label Name',\n 'task.manager.label.name.placeholder': 'e.g. Bug, Feature',\n 'task.manager.label.color.label': 'Color',\n 'task.manager.label.add': 'Add Label',\n 'task.manager.label.no.labels': 'No labels yet.',\n\n 'task.manager.board.edit': 'Edit Board',\n 'task.manager.board.name.label': 'Board Name',\n 'task.manager.board.description.label': 'Description',\n\n 'task.manager.view.board': 'Board',\n 'task.manager.view.list': 'List',\n\n 'task.manager.table.title': 'Title',\n 'task.manager.table.list': 'List',\n 'task.manager.table.priority': 'Priority',\n 'task.manager.table.assignee': 'Assignee',\n 'task.manager.table.due.date': 'Due Date',\n 'task.manager.table.empty': 'No tasks yet.',\n\n 'task.form.title.create': 'New Task',\n 'task.form.title.edit': 'Edit Task',\n 'task.form.title.label': 'Title',\n 'task.form.title.placeholder': 'Task title',\n 'task.form.description.placeholder': 'Add a description...',\n 'task.form.priority.label': 'Priority',\n 'task.form.priority.placeholder': 'Select priority',\n 'task.form.due.date.label': 'Due Date',\n 'task.form.due.date.placeholder': 'Pick a date',\n 'task.form.assignee.label': 'Assignee',\n 'task.form.assignee.placeholder': 'Assign to board member',\n 'task.form.labels.label': 'Labels',\n 'task.form.labels.placeholder': 'Select labels',\n\n 'task.priority.LOW': 'Low',\n 'task.priority.MEDIUM': 'Medium',\n 'task.priority.HIGH': 'High',\n 'task.priority.URGENT': 'Urgent',\n\n 'task.detail.description.empty': 'No description',\n 'task.detail.comments.label': 'Comments',\n 'task.detail.comments.empty': 'No comments yet',\n 'task.detail.comment.placeholder': 'Add a comment...',\n 'task.detail.due.label': 'Due',\n 'task.detail.assignees.label': 'Assignees',\n 'task.detail.edit': 'Edit task',\n 'task.detail.delete': 'Delete task',\n 'task.comment.reply': 'Reply',\n 'task.comment.reply.placeholder': 'Write a reply...',\n} as const;\n","import { Routes } from '@angular/router';\nimport { resolveTranslationModule, SHARED_MESSAGES } from '@flusys/ng-shared';\nimport { TASK_MANAGER_MESSAGES } from '../constants/messages';\n\nexport const TASK_MANAGER_ROUTES: Routes = [\n {\n path: '',\n resolve: {\n translations: resolveTranslationModule({\n modules: ['task-manager'],\n fallbackMessages: { ...TASK_MANAGER_MESSAGES, ...SHARED_MESSAGES },\n }),\n },\n loadComponent: () =>\n import('../pages/board-list-page/board-list-page.component').then(\n (m) => m.BoardListPageComponent,\n ),\n },\n {\n path: 'board/:boardId',\n resolve: {\n translations: resolveTranslationModule({\n modules: ['task-manager'],\n fallbackMessages: { ...TASK_MANAGER_MESSAGES, ...SHARED_MESSAGES },\n }),\n },\n loadComponent: () =>\n import('../pages/board-view-page/board-view-page.component').then(\n (m) => m.BoardViewPageComponent,\n ),\n },\n];\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flusys/ng-task-manager",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.2.0",
|
|
4
4
|
"description": "Task management module with dynamic boards, lists, and real-time collaboration",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"peerDependencies": {
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"@angular/core": ">=22.0.0",
|
|
10
10
|
"@angular/forms": ">=22.0.0",
|
|
11
11
|
"@angular/router": ">=22.0.0",
|
|
12
|
-
"@flusys/ng-core": ">=9.
|
|
13
|
-
"@flusys/ng-shared": ">=9.
|
|
14
|
-
"@flusys/ng-ui": ">=9.
|
|
12
|
+
"@flusys/ng-core": ">=9.2.0",
|
|
13
|
+
"@flusys/ng-shared": ">=9.2.0",
|
|
14
|
+
"@flusys/ng-ui": ">=9.2.0",
|
|
15
15
|
"socket.io-client": ">=4.0.0",
|
|
16
16
|
"rxjs": "^7.8.0"
|
|
17
17
|
},
|
|
@@ -190,10 +190,12 @@ export declare class TaskBoardSocketService {
|
|
|
190
190
|
readonly isConnected: import("@angular/core").Signal<boolean>;
|
|
191
191
|
private readonly boardEvent$;
|
|
192
192
|
readonly onBoardEvent: import("rxjs").Observable<IBoardSocketEvent>;
|
|
193
|
+
private readonly joinedBoardIds;
|
|
193
194
|
connect(accessToken: string): void;
|
|
194
195
|
joinBoard(boardId: string): void;
|
|
195
196
|
leaveBoard(boardId: string): void;
|
|
196
197
|
disconnect(): void;
|
|
198
|
+
private teardown;
|
|
197
199
|
private getBaseUrl;
|
|
198
200
|
static ɵfac: i0.ɵɵFactoryDeclaration<TaskBoardSocketService, never>;
|
|
199
201
|
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
@@ -214,6 +216,7 @@ export declare class TaskBoardStateService {
|
|
|
214
216
|
private readonly _selectedTask;
|
|
215
217
|
private readonly _isLoading;
|
|
216
218
|
private readonly _isBoardLoading;
|
|
219
|
+
private openRequestId;
|
|
217
220
|
readonly boards: import("@angular/core").Signal<ITaskBoard[]>;
|
|
218
221
|
readonly activeBoard: import("@angular/core").Signal<ITaskBoard | null>;
|
|
219
222
|
readonly lists: import("@angular/core").Signal<ITaskList[]>;
|
|
@@ -242,16 +245,19 @@ export declare class TaskBoardStateService {
|
|
|
242
245
|
loadBoards(): Promise<void>;
|
|
243
246
|
openBoard(boardId: string): Promise<void>;
|
|
244
247
|
closeBoard(): void;
|
|
248
|
+
private resetBoardState;
|
|
245
249
|
selectTask(task: ITask | null): void;
|
|
246
250
|
addLabel(boardId: string, name: string, color: string): Promise<void>;
|
|
247
251
|
deleteLabel(labelId: string): Promise<void>;
|
|
248
252
|
addMember(userId: string, role?: string): Promise<void>;
|
|
249
253
|
removeMember(userId: string): Promise<void>;
|
|
250
254
|
reorderLists(boardId: string, orderedIds: string[]): Promise<void>;
|
|
255
|
+
moveTask(taskId: string, targetListId: string, targetIndex: number): Promise<void>;
|
|
251
256
|
renameList(listId: string, name: string): Promise<void>;
|
|
252
257
|
updateBoard(dto: IUpdateTaskBoardDto): Promise<void>;
|
|
253
258
|
addTaskOptimistic(task: ITask): void;
|
|
254
259
|
deleteTask(taskId: string): Promise<void>;
|
|
260
|
+
private applyListOrder;
|
|
255
261
|
private handleBoardEvent;
|
|
256
262
|
static ɵfac: i0.ɵɵFactoryDeclaration<TaskBoardStateService, never>;
|
|
257
263
|
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
@@ -260,7 +266,9 @@ export declare const MEMBER_COLOR_PALETTE: string[];
|
|
|
260
266
|
export declare const BOARD_COLOR_PALETTE: string[];
|
|
261
267
|
export declare function taskPrioritySeverity(priority: string): 'success' | 'info' | 'warn' | 'danger' | 'secondary';
|
|
262
268
|
export declare function memberInitials(name: string | null | undefined): string;
|
|
263
|
-
export declare function
|
|
269
|
+
export declare function toDateOnlyString(date: Date): string;
|
|
270
|
+
export declare function parseDateOnly(value: string | null | undefined): Date | null;
|
|
271
|
+
export declare function isTaskOverdue(dueDate: string | null | undefined): boolean;
|
|
264
272
|
export declare function memberColorFromId(userId: string): string;
|
|
265
273
|
export declare class TaskCardComponent {
|
|
266
274
|
readonly task: import("@angular/core").InputSignal<ITask>;
|
|
@@ -371,6 +379,7 @@ export declare class TaskDetailPanelComponent {
|
|
|
371
379
|
readonly assigneeMembers: import("@angular/core").Signal<import("@flusys/ng-task-manager").ITaskAssignee[]>;
|
|
372
380
|
readonly rootComments: import("@angular/core").Signal<ITaskComment[]>;
|
|
373
381
|
repliesFor(parentId: string): ITaskComment[];
|
|
382
|
+
private readonly taskId;
|
|
374
383
|
constructor();
|
|
375
384
|
toggleReply(commentId: string): void;
|
|
376
385
|
cancelReply(): void;
|