import { afterNextRender, ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core'; import { TaskStore } from '../../data-access/store/task-store'; import { Task, TaskState } from '../../data-access/models/task.model'; import { TaskDetailSidebar } from '../../ui/task-detail-sidebar/task-detail-sidebar'; import { TaskCreateSidebar } from '../../ui/task-create-sidebar/task-create-sidebar'; import { TaskBoardColumn } from '../../ui/task-board-column/task-board-column'; import { Pagination } from '@shared/ui/pagination/pagination'; export type ViewMode = 'table' | 'board' | 'timeline'; @Component({ selector: 'emi-task-list-page', imports: [TaskDetailSidebar, TaskCreateSidebar, TaskBoardColumn, Pagination], templateUrl: './task-list-page.html', styleUrl: './task-list-page.css', changeDetection: ChangeDetectionStrategy.OnPush, }) export class TaskListPage { private readonly store = inject(TaskStore); readonly PAGE_SIZE = 5; constructor() { afterNextRender(() => { this.store.loadTasks(); }); } readonly tasks = this.store.filteredTasks; readonly loading = this.store.loading; readonly selectedTask = this.store.selectedTask; readonly transitioningState = this.store.transitioningState; readonly showCreateSidebar = signal(false); readonly activeView = signal('table'); readonly currentPage = signal(1); private readonly stateProgress: Record = { new: 0, active: 50, resolved: 100, closed: 100, }; private readonly stateLabels: Record = { new: 'New', active: 'Active', resolved: 'Resolved', closed: 'Closed', }; readonly totalPages = computed(() => { return Math.max(1, Math.ceil(this.tasks().length / this.PAGE_SIZE)); }); readonly paginatedTasks = computed(() => { const start = (this.currentPage() - 1) * this.PAGE_SIZE; return this.tasks().slice(start, start + this.PAGE_SIZE); }); readonly completionPercent = computed(() => { const all = this.tasks(); if (all.length === 0) return 0; const totalProgress = all.reduce((sum, t) => sum + this.getStateProgress(t), 0); return Math.round(totalProgress / all.length); }); readonly completedCount = computed(() => this.tasks().filter(t => this.isFinalized(t)).length ); readonly activeCount = computed(() => this.tasks().filter(t => this.getState(t) === 'active').length ); readonly newCount = computed(() => this.tasks().filter(t => this.getState(t) === 'new').length ); readonly tasksByState = computed(() => { const grouped: Record = { new: [], active: [], resolved: [], closed: [], }; for (const task of this.tasks()) { const state = this.getState(task); grouped[state].push(task); } return grouped; }); readonly tasksByDate = computed(() => { const sorted = [...this.tasks()].sort((a, b) => new Date(a.dueDate).getTime() - new Date(b.dueDate).getTime() ); const grouped: Record = {}; for (const task of sorted) { const date = task.dueDate; if (!grouped[date]) { grouped[date] = []; } grouped[date].push(task); } return grouped; }); readonly dueDates = computed(() => Object.keys(this.tasksByDate())); onPageChange(page: number): void { this.currentPage.set(page); } onViewChange(view: ViewMode): void { this.activeView.set(view); } getState(task: Task): TaskState { const history = task.stateHistory; return history[history.length - 1]?.state ?? 'new'; } getStateLabel(task: Task): string { return this.stateLabels[this.getState(task)]; } getStateProgress(task: Task): number { return this.stateProgress[this.getState(task)]; } isFinalized(task: Task): boolean { const state = this.getState(task); return state === 'resolved' || state === 'closed'; } isSelected(task: Task): boolean { return this.selectedTask()?.id === task.id; } onViewTask(task: Task): void { this.showCreateSidebar.set(false); this.store.setSelectedTask(task); } onCloseDetailSidebar(): void { this.store.setSelectedTask(null); } onChangeState(state: TaskState): void { const task = this.selectedTask(); if (task) { this.store.transitionTask(task.id, state); } } onDeleteTask(task: Task): void { this.store.deleteTask(task.id); this.store.setSelectedTask(null); } onAddNote(content: string): void { const task = this.selectedTask(); if (task) { this.store.addNote(task.id, content); } } onDeleteNote(index: number): void { const task = this.selectedTask(); if (task) { this.store.deleteNote(task.id, index); } } onOpenCreateSidebar(): void { this.store.setSelectedTask(null); this.showCreateSidebar.set(true); } onCloseCreateSidebar(): void { this.showCreateSidebar.set(false); } onTaskCreated(): void { this.showCreateSidebar.set(false); } onBoardViewTask(task: Task): void { this.onViewTask(task); } onBoardEditTask(task: Task): void { this.onViewTask(task); } onBoardDeleteTask(task: Task): void { this.onDeleteTask(task); } }