feat(project-editor): session undo/redo and modified-field tracking
Milestone 4 of the Configuration Engine sprint. - Add schema/history.util: pure undo/redo reducer (commit/undo/redo, depth cap) with full spec coverage. - Facade: debounced snapshot history (~300ms coalesce so a typing burst = one undo step); undo()/redo() route through the draft-save path so autosave never desyncs; canUndo/canRedo; history cleared on load/publish/resetDraft. modifiedFields (schema-diff vs original) + modifiedSections computeds. - save-bar: Undo/Redo buttons. Page: Ctrl/Cmd+Z / Shift+Z / Y shortcuts (skipped while a text field is focused so native text undo is preserved); beforeunload guard already present. - nav: amber modified-field dot per section (when no blocking badge). - i18n: builder.undo / builder.redo in interface + en/ru/hy. Gate: tsc --noEmit, npm test (33/33), arch:check, build all green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -535,6 +535,8 @@ export const en: Translations = {
|
||||
validationInvalidCss: 'A static page contains invalid CSS.',
|
||||
validationDuplicateRoutes: 'Two or more pages share the same route.',
|
||||
validationInvalidWidgetConfig: 'A widget is missing a required field (id, type, version, or props).',
|
||||
undo: 'Undo',
|
||||
redo: 'Redo',
|
||||
statusDraft: 'Draft',
|
||||
statusPublished: 'Published',
|
||||
unsavedChanges: 'Unsaved changes',
|
||||
|
||||
@@ -535,6 +535,8 @@ export const hy: Translations = {
|
||||
validationInvalidCss: 'Ստատիկ էջը պարունակում է անվավեր CSS։',
|
||||
validationDuplicateRoutes: 'Երկու կամ ավելի էջ ունեն նույն երթուղին։',
|
||||
validationInvalidWidgetConfig: 'Վիջեթին բացակայում է պարտադիր դաշտ (id, type, version կամ props)։',
|
||||
undo: 'Հետարկել',
|
||||
redo: 'Կրկնել',
|
||||
statusDraft: 'Սևագիր',
|
||||
statusPublished: 'Հրապարակված',
|
||||
unsavedChanges: 'Չպահված փոփոխություններ',
|
||||
|
||||
@@ -535,6 +535,8 @@ export const ru: Translations = {
|
||||
validationInvalidCss: 'Статическая страница содержит недопустимый CSS.',
|
||||
validationDuplicateRoutes: 'Две или более страницы используют один и тот же маршрут.',
|
||||
validationInvalidWidgetConfig: 'У виджета отсутствует обязательное поле (id, type, version или props).',
|
||||
undo: 'Отменить',
|
||||
redo: 'Повторить',
|
||||
statusDraft: 'Черновик',
|
||||
statusPublished: 'Опубликовано',
|
||||
unsavedChanges: 'Есть несохранённые изменения',
|
||||
|
||||
@@ -533,6 +533,8 @@ export interface Translations {
|
||||
validationInvalidCss: string;
|
||||
validationDuplicateRoutes: string;
|
||||
validationInvalidWidgetConfig: string;
|
||||
undo: string;
|
||||
redo: string;
|
||||
statusDraft: string;
|
||||
statusPublished: string;
|
||||
unsavedChanges: string;
|
||||
|
||||
Reference in New Issue
Block a user