From e51a8986864f7d1964155b5fcc52b315a18511f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20OLIVIER?= Date: Fri, 22 May 2026 18:12:55 +0200 Subject: [PATCH] Persistance dans le cache du navigateur --- src/app/issues/issues.store.ts | 112 ++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 36 deletions(-) diff --git a/src/app/issues/issues.store.ts b/src/app/issues/issues.store.ts index dac3bad..efbab24 100644 --- a/src/app/issues/issues.store.ts +++ b/src/app/issues/issues.store.ts @@ -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([ - { - 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(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)); + } }