Historique visible et restauration
FormBuilder enregistre chaque mutation du schéma dans un historique isolé par builder-id. Le panneau Historique transforme cet undo/redo interne en une timeline exploitable par l’utilisateur.
Le schéma courant, les étapes, les colonnes et les champs restent sérialisables. L’historique est une donnée runtime en mémoire et n’est pas ajouté au JSON exporté.
Activer et contrôler le panneau
<script setup lang="ts">
const historyOpen = ref(false)
const historyDepth = ref(50)
</script>
<template>
<FormBuilder
builder-id="customer-form"
v-model:history-open="historyOpen"
v-model:history-depth="historyDepth"
/>
</template>Props associées :
| Prop | Défaut | Rôle |
|---|---|---|
history-open | false | Contrôle l’ouverture du panneau. |
history-depth | 50 | Nombre maximal d’états conservés, borné entre 2 et 500. |
history-shortcuts | true | Active les raccourcis clavier undo/redo. |
La profondeur est appliquée immédiatement. Réduire la valeur supprime les états les plus anciens tout en conservant l’état courant.
Timeline et libellés métier
Chaque entrée contient :
- un identifiant stable ;
- un numéro de séquence ;
- un horodatage ;
- une action métier typée ;
- un contexte sérialisable ;
- une copie indépendante du schéma ;
- éventuellement un libellé personnalisé et une clé de fusion.
La timeline affiche par exemple :
- « Champ ajouté : email » ;
- « Colonne déplacée : coordonnées » ;
- « Étape dupliquée : Validation » ;
- « Schéma importé » ;
- « État #12 restauré ».
Les libellés sont résolus au moment de l’affichage avec la locale active. L’historique ne stocke donc pas une traduction figée.
Raccourcis clavier
Lorsque history-shortcuts vaut true :
| Raccourci | Action |
|---|---|
Ctrl+Z ou Cmd+Z | Annuler. |
Ctrl+Shift+Z ou Cmd+Shift+Z | Rétablir. |
Ctrl+Y | Rétablir. |
Le gestionnaire ignore les événements provenant d’un input, textarea, select, d’un éditeur contenteditable ou d’un élément ayant role="textbox". Un raccourci saisi dans un champ continue donc à modifier le texte du champ plutôt que le schéma du builder.
Avec plusieurs builders sur la même page, le dernier builder activé par un clic ou un focus devient propriétaire des raccourcis. Cette règle évite qu’un Ctrl+Z modifie plusieurs instances.
Annuler, rétablir et créer une branche
L’undo déplace le pointeur vers l’état précédent. Le redo le déplace vers l’état suivant.
Lorsqu’une modification est effectuée après un undo, les anciens états futurs sont supprimés. Une nouvelle branche d’historique commence à partir de l’état courant, comme dans un éditeur classique.
Les modifications rapides d’une même propriété utilisent une mergeKey et sont fusionnées pendant une courte fenêtre. Par exemple, saisir plusieurs caractères dans le libellé d’un champ ne crée pas une entrée par frappe.
Restaurer explicitement un état
Le bouton Restaurer cet état demande une confirmation. La restauration ne déplace pas silencieusement le pointeur vers une ancienne entrée : elle crée une nouvelle entrée history-restore à la fin de la timeline.
Cette conception garantit que la restauration elle-même peut être annulée.
API publique
<script setup lang="ts">
import type {
FormBuilderPublicApi,
QFormBuilderHistoryChangeEvent,
QFormBuilderHistoryNavigationEvent,
} from '@vevedh/qform-builder-layer/types'
const builder = ref<FormBuilderPublicApi | null>(null)
function restoreFirstState() {
const history = builder.value?.getHistory()
const first = history?.entries[0]
if (first) builder.value?.restoreHistoryEntry(first.id)
}
function handleHistoryChange(event: QFormBuilderHistoryChangeEvent) {
console.log(event.builderId, event.snapshot.pointer)
}
function handleUndo(event: QFormBuilderHistoryNavigationEvent) {
console.log('État actif', event.entry.sequence)
}
</script>
<template>
<FormBuilder
ref="builder"
builder-id="history-api-demo"
@history-change="handleHistoryChange"
@history-undo="handleUndo"
/>
<QBtn label="Restaurer le premier état" @click="restoreFirstState" />
</template>Méthodes exposées :
getHistory(): QFormBuilderHistorySnapshot
undo(): QFormBuilderHistoryEntry | null
redo(): QFormBuilderHistoryEntry | null
restoreHistoryEntry(entryId: string): QFormBuilderHistoryEntry | null
clearHistory(): void
setHistoryDepth(depth: number): number
openHistory(): void
closeHistory(): voidÉvénements :
history-changeaprès toute modification du pointeur, de la profondeur ou des entrées ;history-undoaprès un undo réussi ;history-redoaprès un redo réussi ;history-restoreaprès une restauration explicite.
Helpers publics
Le sous-chemin history expose le moteur pur, utile pour des tests ou une intégration avancée :
import {
appendQFormBuilderHistory,
createQFormBuilderHistoryState,
formatQFormBuilderHistoryLabel,
normalizeQFormBuilderHistoryDepth,
restoreQFormBuilderHistory,
} from '@vevedh/qform-builder-layer/history'Persistance et limites
L’historique est volontairement conservé en mémoire :
- il n’est pas écrit dans
localStoragepar l’autosave ; - il n’est pas exporté avec le schéma ;
- il n’est pas envoyé automatiquement au service NFZ
forms; - il disparaît lors du démontage définitif de l’instance.
Pour un audit durable, persistez des versions métier côté serveur dans un service Feathers/NFZ distinct. Ne confondez pas l’historique ergonomique du builder avec un journal d’audit réglementaire.
Bonnes pratiques
- Utiliser un
builder-idstable. - Conserver une profondeur de
30à100pour la majorité des formulaires. - Désactiver
history-shortcutslorsque l’application hôte possède déjà un gestionnaire global de raccourcis. - Confirmer explicitement toute restauration depuis la timeline.
- Ne jamais utiliser l’historique client comme mécanisme d’autorisation, de sauvegarde ou de preuve d’audit.