79 lines
2.4 KiB
TypeScript
79 lines
2.4 KiB
TypeScript
import { useState, useCallback, useEffect } from 'react';
|
|
import { LayoutDefinition } from '../../../services/contracts/metadata';
|
|
|
|
export function useFormBuilderHistory() {
|
|
const [currentLayout, setCurrentLayout] = useState<LayoutDefinition | null>(null);
|
|
const [isDirty, setIsDirty] = useState(false);
|
|
const [history, setHistory] = useState<LayoutDefinition[]>([]);
|
|
const [historyIndex, setHistoryIndex] = useState(-1);
|
|
|
|
const initHistory = useCallback((layout: LayoutDefinition) => {
|
|
setCurrentLayout(layout);
|
|
setHistory([layout]);
|
|
setHistoryIndex(0);
|
|
setIsDirty(false);
|
|
}, []);
|
|
|
|
const pushState = useCallback((newLayout: LayoutDefinition) => {
|
|
setHistory((prev) => {
|
|
const slice = prev.slice(0, historyIndex + 1);
|
|
const updated = [...slice, newLayout];
|
|
if (updated.length > 50) updated.shift();
|
|
return updated;
|
|
});
|
|
setHistoryIndex((prev) => Math.min(prev + 1, 49));
|
|
setCurrentLayout(newLayout);
|
|
setIsDirty(true);
|
|
}, [historyIndex]);
|
|
|
|
const handleUndo = useCallback(() => {
|
|
if (historyIndex > 0) {
|
|
const targetIndex = historyIndex - 1;
|
|
setHistoryIndex(targetIndex);
|
|
setCurrentLayout(history[targetIndex]);
|
|
setIsDirty(true);
|
|
}
|
|
}, [historyIndex, history]);
|
|
|
|
const handleRedo = useCallback(() => {
|
|
if (historyIndex < history.length - 1) {
|
|
const targetIndex = historyIndex + 1;
|
|
setHistoryIndex(targetIndex);
|
|
setCurrentLayout(history[targetIndex]);
|
|
setIsDirty(true);
|
|
}
|
|
}, [historyIndex, history]);
|
|
|
|
// Keyboard shortcut listener for Ctrl+Z and Ctrl+Y
|
|
useEffect(() => {
|
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
if ((e.ctrlKey || e.metaKey) && e.key === 'z' && !e.shiftKey) {
|
|
e.preventDefault();
|
|
handleUndo();
|
|
} else if (
|
|
((e.ctrlKey || e.metaKey) && e.key === 'y') ||
|
|
((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'z')
|
|
) {
|
|
e.preventDefault();
|
|
handleRedo();
|
|
}
|
|
};
|
|
window.addEventListener('keydown', handleKeyDown);
|
|
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
}, [handleUndo, handleRedo]);
|
|
|
|
return {
|
|
currentLayout,
|
|
setCurrentLayout,
|
|
isDirty,
|
|
setIsDirty,
|
|
history,
|
|
historyIndex,
|
|
pushState,
|
|
handleUndo,
|
|
handleRedo,
|
|
initHistory,
|
|
canUndo: historyIndex > 0,
|
|
canRedo: historyIndex < history.length - 1,
|
|
};
|
|
}
|