refactor: userpreferences are now in the DB
This commit is contained in:
@@ -1,31 +1,5 @@
|
||||
import { TaskPriority, TaskStatus } from '@/lib/types';
|
||||
|
||||
// Types pour les préférences utilisateur
|
||||
export interface KanbanFilters {
|
||||
search?: string;
|
||||
tags?: string[];
|
||||
priorities?: TaskPriority[];
|
||||
showCompleted?: boolean;
|
||||
sortBy?: string;
|
||||
}
|
||||
|
||||
export interface ViewPreferences {
|
||||
compactView: boolean;
|
||||
swimlanesByTags: boolean;
|
||||
swimlanesMode?: 'tags' | 'priority';
|
||||
showObjectives: boolean;
|
||||
showFilters: boolean;
|
||||
}
|
||||
|
||||
export interface ColumnVisibility {
|
||||
hiddenStatuses: TaskStatus[];
|
||||
}
|
||||
|
||||
export interface UserPreferences {
|
||||
kanbanFilters: KanbanFilters;
|
||||
viewPreferences: ViewPreferences;
|
||||
columnVisibility: ColumnVisibility;
|
||||
}
|
||||
import { TaskStatus, KanbanFilters, ViewPreferences, ColumnVisibility, UserPreferences } from '@/lib/types';
|
||||
import { prisma } from './database';
|
||||
|
||||
// Valeurs par défaut
|
||||
const DEFAULT_PREFERENCES: UserPreferences = {
|
||||
@@ -33,186 +7,217 @@ const DEFAULT_PREFERENCES: UserPreferences = {
|
||||
search: '',
|
||||
tags: [],
|
||||
priorities: [],
|
||||
showCompleted: true
|
||||
showCompleted: true,
|
||||
sortBy: ''
|
||||
},
|
||||
viewPreferences: {
|
||||
compactView: false,
|
||||
swimlanesByTags: false,
|
||||
swimlanesMode: 'tags',
|
||||
showObjectives: true,
|
||||
showFilters: true
|
||||
showFilters: true,
|
||||
objectivesCollapsed: false,
|
||||
theme: 'dark'
|
||||
},
|
||||
columnVisibility: {
|
||||
hiddenStatuses: []
|
||||
}
|
||||
};
|
||||
|
||||
// Clés pour le localStorage
|
||||
const STORAGE_KEYS = {
|
||||
KANBAN_FILTERS: 'towercontrol_kanban_filters',
|
||||
VIEW_PREFERENCES: 'towercontrol_view_preferences',
|
||||
COLUMN_VISIBILITY: 'towercontrol_column_visibility'
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Service pour gérer les préférences utilisateur dans le localStorage
|
||||
* Service pour gérer les préférences utilisateur en base de données
|
||||
*/
|
||||
export const userPreferencesService = {
|
||||
class UserPreferencesService {
|
||||
private readonly USER_ID = 'default'; // Pour l'instant, un seul utilisateur
|
||||
|
||||
/**
|
||||
* Récupère ou crée l'entrée user preferences (avec upsert pour éviter les doublons)
|
||||
*/
|
||||
private async getOrCreateUserPreferences() {
|
||||
// Utiliser upsert pour éviter les conditions de course
|
||||
const userPrefs = await prisma.userPreferences.upsert({
|
||||
where: { id: 'default' }, // ID fixe pour l'utilisateur unique
|
||||
update: {}, // Ne rien mettre à jour si existe
|
||||
create: {
|
||||
id: 'default',
|
||||
kanbanFilters: DEFAULT_PREFERENCES.kanbanFilters,
|
||||
viewPreferences: DEFAULT_PREFERENCES.viewPreferences,
|
||||
columnVisibility: DEFAULT_PREFERENCES.columnVisibility,
|
||||
}
|
||||
});
|
||||
|
||||
return userPrefs;
|
||||
}
|
||||
|
||||
// === FILTRES KANBAN ===
|
||||
|
||||
/**
|
||||
* Sauvegarde les filtres Kanban
|
||||
*/
|
||||
saveKanbanFilters(filters: KanbanFilters): void {
|
||||
async saveKanbanFilters(filters: KanbanFilters): Promise<void> {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEYS.KANBAN_FILTERS, JSON.stringify(filters));
|
||||
const userPrefs = await this.getOrCreateUserPreferences();
|
||||
await prisma.userPreferences.update({
|
||||
where: { id: userPrefs.id },
|
||||
data: { kanbanFilters: filters }
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn('Erreur lors de la sauvegarde des filtres Kanban:', error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère les filtres Kanban
|
||||
*/
|
||||
getKanbanFilters(): KanbanFilters {
|
||||
async getKanbanFilters(): Promise<KanbanFilters> {
|
||||
try {
|
||||
const stored = localStorage.getItem(STORAGE_KEYS.KANBAN_FILTERS);
|
||||
if (stored) {
|
||||
return { ...DEFAULT_PREFERENCES.kanbanFilters, ...JSON.parse(stored) };
|
||||
}
|
||||
const userPrefs = await this.getOrCreateUserPreferences();
|
||||
const filters = userPrefs.kanbanFilters as KanbanFilters | null;
|
||||
return { ...DEFAULT_PREFERENCES.kanbanFilters, ...(filters || {}) };
|
||||
} catch (error) {
|
||||
console.warn('Erreur lors de la récupération des filtres Kanban:', error);
|
||||
return DEFAULT_PREFERENCES.kanbanFilters;
|
||||
}
|
||||
return DEFAULT_PREFERENCES.kanbanFilters;
|
||||
},
|
||||
}
|
||||
|
||||
// === PRÉFÉRENCES DE VUE ===
|
||||
|
||||
/**
|
||||
* Sauvegarde les préférences de vue
|
||||
*/
|
||||
saveViewPreferences(preferences: ViewPreferences): void {
|
||||
async saveViewPreferences(preferences: ViewPreferences): Promise<void> {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEYS.VIEW_PREFERENCES, JSON.stringify(preferences));
|
||||
const userPrefs = await this.getOrCreateUserPreferences();
|
||||
await prisma.userPreferences.update({
|
||||
where: { id: userPrefs.id },
|
||||
data: { viewPreferences: preferences }
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn('Erreur lors de la sauvegarde des préférences de vue:', error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère les préférences de vue
|
||||
*/
|
||||
getViewPreferences(): ViewPreferences {
|
||||
async getViewPreferences(): Promise<ViewPreferences> {
|
||||
try {
|
||||
const stored = localStorage.getItem(STORAGE_KEYS.VIEW_PREFERENCES);
|
||||
if (stored) {
|
||||
return { ...DEFAULT_PREFERENCES.viewPreferences, ...JSON.parse(stored) };
|
||||
}
|
||||
const userPrefs = await this.getOrCreateUserPreferences();
|
||||
const preferences = userPrefs.viewPreferences as ViewPreferences | null;
|
||||
return { ...DEFAULT_PREFERENCES.viewPreferences, ...(preferences || {}) };
|
||||
} catch (error) {
|
||||
console.warn('Erreur lors de la récupération des préférences de vue:', error);
|
||||
return DEFAULT_PREFERENCES.viewPreferences;
|
||||
}
|
||||
return DEFAULT_PREFERENCES.viewPreferences;
|
||||
},
|
||||
}
|
||||
|
||||
// === VISIBILITÉ DES COLONNES ===
|
||||
|
||||
/**
|
||||
* Sauvegarde la visibilité des colonnes
|
||||
*/
|
||||
saveColumnVisibility(visibility: ColumnVisibility): void {
|
||||
async saveColumnVisibility(visibility: ColumnVisibility): Promise<void> {
|
||||
try {
|
||||
localStorage.setItem(STORAGE_KEYS.COLUMN_VISIBILITY, JSON.stringify(visibility));
|
||||
const userPrefs = await this.getOrCreateUserPreferences();
|
||||
await prisma.userPreferences.update({
|
||||
where: { id: userPrefs.id },
|
||||
data: { columnVisibility: visibility }
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn('Erreur lors de la sauvegarde de la visibilité des colonnes:', error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère la visibilité des colonnes
|
||||
*/
|
||||
getColumnVisibility(): ColumnVisibility {
|
||||
async getColumnVisibility(): Promise<ColumnVisibility> {
|
||||
try {
|
||||
const stored = localStorage.getItem(STORAGE_KEYS.COLUMN_VISIBILITY);
|
||||
if (stored) {
|
||||
return { ...DEFAULT_PREFERENCES.columnVisibility, ...JSON.parse(stored) };
|
||||
}
|
||||
const userPrefs = await this.getOrCreateUserPreferences();
|
||||
const visibility = userPrefs.columnVisibility as ColumnVisibility | null;
|
||||
return { ...DEFAULT_PREFERENCES.columnVisibility, ...(visibility || {}) };
|
||||
} catch (error) {
|
||||
console.warn('Erreur lors de la récupération de la visibilité des colonnes:', error);
|
||||
return DEFAULT_PREFERENCES.columnVisibility;
|
||||
}
|
||||
return DEFAULT_PREFERENCES.columnVisibility;
|
||||
},
|
||||
}
|
||||
|
||||
// === MÉTHODES GLOBALES ===
|
||||
|
||||
/**
|
||||
* Récupère toutes les préférences utilisateur
|
||||
*/
|
||||
getAllPreferences(): UserPreferences {
|
||||
async getAllPreferences(): Promise<UserPreferences> {
|
||||
const [kanbanFilters, viewPreferences, columnVisibility] = await Promise.all([
|
||||
this.getKanbanFilters(),
|
||||
this.getViewPreferences(),
|
||||
this.getColumnVisibility()
|
||||
]);
|
||||
|
||||
return {
|
||||
kanbanFilters: this.getKanbanFilters(),
|
||||
viewPreferences: this.getViewPreferences(),
|
||||
columnVisibility: this.getColumnVisibility()
|
||||
kanbanFilters,
|
||||
viewPreferences,
|
||||
columnVisibility
|
||||
};
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Sauvegarde toutes les préférences utilisateur
|
||||
*/
|
||||
saveAllPreferences(preferences: UserPreferences): void {
|
||||
this.saveKanbanFilters(preferences.kanbanFilters);
|
||||
this.saveViewPreferences(preferences.viewPreferences);
|
||||
this.saveColumnVisibility(preferences.columnVisibility);
|
||||
},
|
||||
async saveAllPreferences(preferences: UserPreferences): Promise<void> {
|
||||
await Promise.all([
|
||||
this.saveKanbanFilters(preferences.kanbanFilters),
|
||||
this.saveViewPreferences(preferences.viewPreferences),
|
||||
this.saveColumnVisibility(preferences.columnVisibility)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remet à zéro toutes les préférences
|
||||
*/
|
||||
resetAllPreferences(): void {
|
||||
async resetAllPreferences(): Promise<void> {
|
||||
try {
|
||||
Object.values(STORAGE_KEYS).forEach(key => {
|
||||
localStorage.removeItem(key);
|
||||
const userPrefs = await this.getOrCreateUserPreferences();
|
||||
await prisma.userPreferences.update({
|
||||
where: { id: userPrefs.id },
|
||||
data: {
|
||||
kanbanFilters: DEFAULT_PREFERENCES.kanbanFilters,
|
||||
viewPreferences: DEFAULT_PREFERENCES.viewPreferences,
|
||||
columnVisibility: DEFAULT_PREFERENCES.columnVisibility,
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn('Erreur lors de la remise à zéro des préférences:', error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Vérifie si le localStorage est disponible
|
||||
*/
|
||||
isStorageAvailable(): boolean {
|
||||
try {
|
||||
const test = '__storage_test__';
|
||||
localStorage.setItem(test, test);
|
||||
localStorage.removeItem(test);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// === MÉTHODES UTILITAIRES ===
|
||||
|
||||
/**
|
||||
* Met à jour partiellement les filtres Kanban
|
||||
*/
|
||||
updateKanbanFilters(updates: Partial<KanbanFilters>): void {
|
||||
const current = this.getKanbanFilters();
|
||||
this.saveKanbanFilters({ ...current, ...updates });
|
||||
},
|
||||
async updateKanbanFilters(updates: Partial<KanbanFilters>): Promise<void> {
|
||||
const current = await this.getKanbanFilters();
|
||||
await this.saveKanbanFilters({ ...current, ...updates });
|
||||
}
|
||||
|
||||
/**
|
||||
* Met à jour partiellement les préférences de vue
|
||||
*/
|
||||
updateViewPreferences(updates: Partial<ViewPreferences>): void {
|
||||
const current = this.getViewPreferences();
|
||||
this.saveViewPreferences({ ...current, ...updates });
|
||||
},
|
||||
async updateViewPreferences(updates: Partial<ViewPreferences>): Promise<void> {
|
||||
const current = await this.getViewPreferences();
|
||||
await this.saveViewPreferences({ ...current, ...updates });
|
||||
}
|
||||
|
||||
/**
|
||||
* Met à jour la visibilité d'une colonne spécifique
|
||||
*/
|
||||
toggleColumnVisibility(status: TaskStatus): void {
|
||||
const current = this.getColumnVisibility();
|
||||
async toggleColumnVisibility(status: TaskStatus): Promise<void> {
|
||||
const current = await this.getColumnVisibility();
|
||||
const hiddenStatuses = new Set(current.hiddenStatuses);
|
||||
|
||||
if (hiddenStatuses.has(status)) {
|
||||
@@ -221,8 +226,11 @@ export const userPreferencesService = {
|
||||
hiddenStatuses.add(status);
|
||||
}
|
||||
|
||||
this.saveColumnVisibility({
|
||||
await this.saveColumnVisibility({
|
||||
hiddenStatuses: Array.from(hiddenStatuses)
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Export de l'instance singleton
|
||||
export const userPreferencesService = new UserPreferencesService();
|
||||
|
||||
Reference in New Issue
Block a user