Files
Bonsai-webapp/src/app/statuses/statuses.store.ts
T
2026-05-28 21:09:49 +02:00

67 lines
2.0 KiB
TypeScript

import { Injectable, signal } from '@angular/core';
export type StatusEntity = {
id: string;
label: string;
bg: string;
color: string;
order: number;
};
export const DEFAULT_STATUSES: StatusEntity[] = [
{ id: 'draft', label: 'BROUILLON', bg: '#e2e8f0', color: '#475569', order: 0 },
{ id: 'todo', label: 'À FAIRE', bg: '#dbeafe', color: '#1d4ed8', order: 1 },
{ id: 'in-progress', label: 'EN COURS', bg: '#ffedd5', color: '#9a3412', order: 2 },
{ id: 'done', label: 'TERMINÉ', bg: '#dcfce7', color: '#166534', order: 3 },
];
const STORAGE_KEY = 'bonsai_statuses';
@Injectable({ providedIn: 'root' })
export class StatusesStore {
private readonly data = signal<StatusEntity[]>(this.loadFromStorage());
readonly statuses = this.data.asReadonly();
getById(id: string): StatusEntity | undefined {
return this.data().find((s) => s.id === id);
}
create(status: Omit<StatusEntity, 'order'>): void {
const maxOrder = this.data().reduce((max, s) => Math.max(max, s.order), -1);
this.data.update((list) => [...list, { ...status, order: maxOrder + 1 }]);
this.saveToStorage();
}
update(id: string, changes: Partial<Pick<StatusEntity, 'label' | 'bg' | 'color'>>): void {
this.data.update((list) =>
list.map((s) => (s.id === id ? { ...s, ...changes } : s)),
);
this.saveToStorage();
}
setOrder(ordered: StatusEntity[]): void {
this.data.set(ordered.map((s, i) => ({ ...s, order: i })));
this.saveToStorage();
}
private saveToStorage(): void {
localStorage.setItem(STORAGE_KEY, JSON.stringify(this.data()));
}
private loadFromStorage(): StatusEntity[] {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (raw) {
const parsed = JSON.parse(raw) as StatusEntity[];
if (Array.isArray(parsed) && parsed.length > 0) {
return [...parsed].sort((a, b) => a.order - b.order);
}
}
} catch {
// ignore parse errors
}
return [...DEFAULT_STATUSES];
}
}