ObsiViewer/src/services/editor-state.service.ts

102 lines
2.1 KiB
TypeScript

import { Injectable, signal, computed } from '@angular/core';
/**
* Service de gestion d'état pour le mode édition Markdown
* Gère le passage entre mode lecture et mode édition
*/
export interface EditorState {
mode: 'view' | 'edit';
currentPath: string | null;
isDirty: boolean;
content: string | null;
}
@Injectable({
providedIn: 'root'
})
export class EditorStateService {
// État privé
private state = signal<EditorState>({
mode: 'view',
currentPath: null,
isDirty: false,
content: null
});
// Signaux publics (lecture seule)
readonly mode = computed(() => this.state().mode);
readonly currentPath = computed(() => this.state().currentPath);
readonly isDirty = computed(() => this.state().isDirty);
readonly content = computed(() => this.state().content);
readonly isEditMode = computed(() => this.state().mode === 'edit');
/**
* Active le mode édition pour un fichier donné
*/
enterEditMode(filePath: string, content: string): void {
this.state.set({
mode: 'edit',
currentPath: filePath,
isDirty: false,
content
});
}
/**
* Quitte le mode édition
*/
exitEditMode(): void {
this.state.set({
mode: 'view',
currentPath: null,
isDirty: false,
content: null
});
}
/**
* Marque le contenu comme modifié
*/
setDirty(isDirty: boolean): void {
this.state.update(current => ({
...current,
isDirty
}));
}
/**
* Met à jour le contenu en cours d'édition
*/
updateContent(content: string): void {
this.state.update(current => ({
...current,
content,
isDirty: true
}));
}
/**
* Réinitialise le flag dirty après sauvegarde
*/
markAsSaved(): void {
this.state.update(current => ({
...current,
isDirty: false
}));
}
/**
* Vérifie si on peut quitter sans perdre de données
*/
canExit(): boolean {
return !this.state().isDirty;
}
/**
* Force la sortie (abandon des modifications)
*/
forceExit(): void {
this.exitEditMode();
}
}