Persistance dans le cache du navigateur

This commit is contained in:
Cédric OLIVIER
2026-05-22 18:12:55 +02:00
parent 105cafe17f
commit e51a898686
+76 -36
View File
@@ -1,5 +1,7 @@
import { Injectable, signal } from '@angular/core';
const ISSUES_STORAGE_KEY = 'bonsai.issues';
export type IssueStatus = 'draft' | 'todo' | 'done' | 'in-progress';
export type IssuePriority = 'Basse' | 'Moyenne' | 'Haute';
@@ -15,43 +17,52 @@ export type IssueEntity = {
progress: number;
};
const DEFAULT_ISSUES: IssueEntity[] = [
{
id: 1,
assignee: 'Marie',
epic: 'EPIC-UI',
name: 'Bug affichage menu mobile',
dueDate: '2026-06-10',
description: 'Corriger le comportement du menu sur petits ecrans.',
priority: 'Haute',
status: 'in-progress',
progress: 35,
},
{
id: 2,
assignee: 'Nabil',
epic: 'EPIC-FORM',
name: 'Erreur validation formulaire projet',
dueDate: '2026-06-12',
description: 'Fiabiliser les regles de validation du formulaire projet.',
priority: 'Moyenne',
status: 'todo',
progress: 20,
},
{
id: 3,
assignee: 'Sonia',
epic: 'EPIC-CONTENT',
name: 'Mise a jour message de bienvenue',
dueDate: '2026-06-18',
description: 'Mettre a jour le wording d accueil selon la charte produit.',
priority: 'Basse',
status: 'done',
progress: 100,
},
];
@Injectable({ providedIn: 'root' })
export class IssuesStore {
private readonly data = signal<IssueEntity[]>([
{
id: 1,
assignee: 'Marie',
epic: 'EPIC-UI',
name: 'Bug affichage menu mobile',
dueDate: '2026-06-10',
description: 'Corriger le comportement du menu sur petits ecrans.',
priority: 'Haute',
status: 'in-progress',
progress: 35,
},
{
id: 2,
assignee: 'Nabil',
epic: 'EPIC-FORM',
name: 'Erreur validation formulaire projet',
dueDate: '2026-06-12',
description: 'Fiabiliser les regles de validation du formulaire projet.',
priority: 'Moyenne',
status: 'todo',
progress: 20,
},
{
id: 3,
assignee: 'Sonia',
epic: 'EPIC-CONTENT',
name: 'Mise a jour message de bienvenue',
dueDate: '2026-06-18',
description: 'Mettre a jour le wording d accueil selon la charte produit.',
priority: 'Basse',
status: 'done',
progress: 100,
},
]);
private readonly data = signal<IssueEntity[]>(DEFAULT_ISSUES);
constructor() {
const cachedIssues = this.readFromStorage();
if (cachedIssues) {
this.data.set(cachedIssues);
}
}
readonly issues = this.data.asReadonly();
@@ -69,13 +80,42 @@ export class IssuesStore {
const existingIndex = issues.findIndex((current) => current.id === issue.id);
if (existingIndex === -1) {
return [...issues, issue];
const created = [...issues, issue];
this.persistToStorage(created);
return created;
}
const updated = [...issues];
updated[existingIndex] = issue;
this.persistToStorage(updated);
return updated;
});
}
private readFromStorage(): IssueEntity[] | null {
if (typeof window === 'undefined') {
return null;
}
const rawIssues = window.localStorage.getItem(ISSUES_STORAGE_KEY);
if (!rawIssues) {
return null;
}
try {
const parsed = JSON.parse(rawIssues);
return Array.isArray(parsed) ? (parsed as IssueEntity[]) : null;
} catch {
return null;
}
}
private persistToStorage(issues: IssueEntity[]): void {
if (typeof window === 'undefined') {
return;
}
window.localStorage.setItem(ISSUES_STORAGE_KEY, JSON.stringify(issues));
}
}