Files
IdeA/frontend/src/adapters/uiPreferences.ts
Blomios 79f06c26d9 feat(tickets): persistance des filtres tickets entre redémarrages (#29)
Introduit le port UiPreferencesGateway et son adapter uiPreferences,
avec le module ticketFilterPersistence qui sauvegarde/restaure les
filtres (recherche, statut, sprint, agents) via useTickets,
useTicketSearch et useProjectAgents. Couvert par tests unitaires et
un test d'intégration.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 07:45:50 +02:00

66 lines
1.7 KiB
TypeScript

/**
* `localStorage`-backed {@link UiPreferencesGateway} (ticket #29).
*
* The only place that touches `window.localStorage`; features go through the
* port via DI. Everything is best-effort: a missing / private-mode / quota-full
* storage, or a corrupt JSON entry, degrades silently to "no preference" rather
* than throwing into the UI (persisted UI filters must never break the app).
*/
import type { UiPreferencesGateway } from "@/ports";
/** Returns the `Storage` if usable in this environment, else `null`. */
function storage(): Storage | null {
try {
return typeof window !== "undefined" ? window.localStorage : null;
} catch {
// Accessing `localStorage` can throw (sandboxed / disabled cookies).
return null;
}
}
export class LocalStorageUiPreferencesGateway implements UiPreferencesGateway {
read(key: string): unknown {
const store = storage();
if (!store) return null;
let raw: string | null;
try {
raw = store.getItem(key);
} catch {
return null;
}
if (raw === null) return null;
try {
return JSON.parse(raw);
} catch {
// Corrupt entry — drop it so we stop tripping over it, return default.
try {
store.removeItem(key);
} catch {
/* ignore */
}
return null;
}
}
write(key: string, value: unknown): void {
const store = storage();
if (!store) return;
try {
store.setItem(key, JSON.stringify(value));
} catch {
/* quota / serialisation failure — persistence is best-effort */
}
}
remove(key: string): void {
const store = storage();
if (!store) return;
try {
store.removeItem(key);
} catch {
/* ignore */
}
}
}