83 lines
2.4 KiB
TypeScript
83 lines
2.4 KiB
TypeScript
import { Injectable } from '@angular/core';
|
|
import { Observable, delay, of, throwError } from 'rxjs';
|
|
import { Task, TaskPriority } from './task.model';
|
|
|
|
const NETWORK_DELAY_MS = 250;
|
|
|
|
@Injectable({ providedIn: 'root' })
|
|
export class TasksApiService {
|
|
private tasks: Task[] = [
|
|
{
|
|
id: 'task-1',
|
|
title: 'Review signal store conventions',
|
|
completed: true,
|
|
priority: 'high',
|
|
updatedAt: '2026-03-08T08:00:00.000Z',
|
|
},
|
|
{
|
|
id: 'task-2',
|
|
title: 'Document persistence boundaries',
|
|
completed: false,
|
|
priority: 'medium',
|
|
updatedAt: '2026-03-08T08:02:00.000Z',
|
|
},
|
|
{
|
|
id: 'task-3',
|
|
title: 'Prepare lazy-loaded feature shell',
|
|
completed: false,
|
|
priority: 'low',
|
|
updatedAt: '2026-03-08T08:05:00.000Z',
|
|
},
|
|
];
|
|
|
|
getTasks(): Observable<Task[]> {
|
|
return of(this.tasks).pipe(delay(NETWORK_DELAY_MS));
|
|
}
|
|
|
|
createTask(title: string, priority: TaskPriority): Observable<Task> {
|
|
const trimmedTitle = title.trim();
|
|
|
|
if (!trimmedTitle) {
|
|
return throwError(() => new Error('Task title cannot be empty.'));
|
|
}
|
|
|
|
const task: Task = {
|
|
id: crypto.randomUUID(),
|
|
title: trimmedTitle,
|
|
completed: false,
|
|
priority,
|
|
updatedAt: new Date().toISOString(),
|
|
};
|
|
|
|
this.tasks = [task, ...this.tasks];
|
|
|
|
return of(task).pipe(delay(NETWORK_DELAY_MS));
|
|
}
|
|
|
|
toggleTask(taskId: string): Observable<Task> {
|
|
const task = this.tasks.find((item) => item.id === taskId);
|
|
|
|
if (!task) {
|
|
return throwError(() => new Error('Task not found.'));
|
|
}
|
|
|
|
const updatedTask: Task = {
|
|
...task,
|
|
completed: !task.completed,
|
|
updatedAt: new Date().toISOString(),
|
|
};
|
|
|
|
this.tasks = this.tasks.map((item) => (item.id === taskId ? updatedTask : item));
|
|
|
|
return of(updatedTask).pipe(delay(NETWORK_DELAY_MS));
|
|
}
|
|
|
|
archiveCompleted(): Observable<string[]> {
|
|
const archivedIds = this.tasks.filter((task) => task.completed).map((task) => task.id);
|
|
|
|
this.tasks = this.tasks.filter((task) => !task.completed);
|
|
|
|
return of(archivedIds).pipe(delay(NETWORK_DELAY_MS));
|
|
}
|
|
}
|