Corrections d'ordre graphique / ergonomique :

- Lorsqu'on part de zéro : la création de dossier / page / template ce fait de manière plus fluide à la création d'un lore (par exemple création de page sans template et dossier : parcours facilité)
- Ajout d'un bouton "+" dans le header templates
- Harmonisation création / modification template

Correction de tests unitaires
This commit is contained in:
2026-04-23 11:25:58 +02:00
parent 29978058ee
commit 84ccdd53ad
20 changed files with 463 additions and 110 deletions

View File

@@ -35,7 +35,7 @@
<ng-template #emptyTemplates>
<p class="empty-hint">
Aucun template défini pour ce Lore.
<a [routerLink]="['/lore', loreId, 'templates', 'create']">Créer un template</a> d'abord.
<a [routerLink]="['/lore', loreId, 'templates', 'create']" [queryParams]="{ returnTo: 'page-create' }" (click)="saveDraft()">Créer un template</a> d'abord.
</p>
</ng-template>
</div>
@@ -43,11 +43,21 @@
<!-- Dossier de destination -->
<div class="field">
<label>Dossier de destination *</label>
<select formControlName="nodeId" [attr.disabled]="preselectedNodeId ? true : null">
<option value="" disabled>Sélectionnez un dossier</option>
<option *ngFor="let node of nodes" [value]="node.id">{{ node.name }}</option>
</select>
<p class="hint">La page sera créée dans ce dossier</p>
<ng-container *ngIf="nodes.length; else emptyFolders">
<select formControlName="nodeId" [attr.disabled]="preselectedNodeId ? true : null">
<option value="" disabled>Sélectionnez un dossier</option>
<option *ngFor="let node of nodes" [value]="node.id">{{ node.name }}</option>
</select>
<p class="hint">La page sera créée dans ce dossier</p>
</ng-container>
<ng-template #emptyFolders>
<p class="empty-hint">
Aucun dossier dans ce Lore.
<a [routerLink]="['/lore', loreId, 'nodes', 'create']" [queryParams]="{ returnTo: 'page-create' }" (click)="saveDraft()">Créer un dossier</a> d'abord.
</p>
</ng-template>
</div>
<!-- Aide contextuelle -->

View File

@@ -92,9 +92,48 @@ export class PageCreateComponent implements OnInit, OnDestroy {
if (this.preselectedNodeId) {
this.form.patchValue({ nodeId: this.preselectedNodeId });
}
this.restoreDraft();
});
}
/** Clé sessionStorage pour le brouillon — scopée au lore courant. */
private get draftKey(): string {
return `page-create-draft:${this.loreId}`;
}
/**
* Sauvegarde le titre et le template sélectionné avant un détour de navigation
* (création de template ou de dossier), pour pouvoir les restaurer au retour.
* NodeId volontairement omis : il peut référencer un dossier qui n'existait
* pas encore et serait invalide après un aller-retour.
*/
saveDraft(): void {
const draft = {
title: this.form.value.title ?? '',
selectedTemplateId: this.selectedTemplateId
};
if (!draft.title && !draft.selectedTemplateId) return;
try {
sessionStorage.setItem(this.draftKey, JSON.stringify(draft));
} catch { /* quota dépassé ou storage indisponible : on ignore */ }
}
private restoreDraft(): void {
let raw: string | null = null;
try { raw = sessionStorage.getItem(this.draftKey); } catch { return; }
if (!raw) return;
sessionStorage.removeItem(this.draftKey);
try {
const draft = JSON.parse(raw) as { title?: string; selectedTemplateId?: string | null };
if (draft.title) this.form.patchValue({ title: draft.title });
if (draft.selectedTemplateId && this.templates.some(t => t.id === draft.selectedTemplateId)) {
const tpl = this.templates.find(t => t.id === draft.selectedTemplateId)!;
this.selectTemplate(tpl);
}
} catch { /* JSON corrompu : on ignore */ }
}
selectTemplate(template: Template): void {
this.selectedTemplateId = template.id!;
// Si pas de noeud pré-choisi par l'URL, on pré-remplit avec le defaultNodeId du template.