task(A4.11): documentService singleton + global v2 undo/redo shortcuts

This commit is contained in:
Agent Zero
2026-08-27 07:14:41 +02:00
parent e76b3efe20
commit 25e721d3d3
3 changed files with 123 additions and 0 deletions
+24
View File
@@ -16,6 +16,7 @@ import { InteractionDispatcher } from '../interaction/dispatcher';
import { logger } from '../utils/logger';
import { CADDocument } from '../kernel/document/CADDocument';
import { YjsDocument } from '../crdt/YjsDocument';
import { setActiveDocument, getActiveDocument } from '../kernel/document/documentService';
import { pluginRegistry } from '../plugins';
const CanvasArea: React.FC<CanvasAreaProps> = ({
@@ -62,6 +63,8 @@ const CanvasArea: React.FC<CanvasAreaProps> = ({
color: '#ffffff', lineType: 'solid', transparency: 0, sortOrder: 0, parentId: null,
} as never);
const v2Doc = new CADDocument(ydoc);
// App-Level-Zugriffspunkt für HistoryPanel/Tastenkürzel (Task A4.11):
setActiveDocument(v2Doc);
// Committete V2-Elemente fließen über den etablierten Kanal in UI/State:
v2Doc.onChanged(() => {
for (const el of v2Doc.getAllElements()) {
@@ -112,6 +115,7 @@ const CanvasArea: React.FC<CanvasAreaProps> = ({
interaction.detach();
dispatcherRef.current?.destroy();
dispatcherRef.current = null;
setActiveDocument(null);
zoomPanRef.current = null;
renderEngineRef.current = null;
interactionRef.current = null;
@@ -283,6 +287,26 @@ const CanvasArea: React.FC<CanvasAreaProps> = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [activeTool]);
// Task A4.11: Globale Undo/Redo-Shortcuts wirken nur auf das V2-Dokument,
// wenn es registriert ist (= Flag aktiv). Legacy-History bleibt unberührt.
useEffect(() => {
const onKey = (e: KeyboardEvent) => {
if (!(e.ctrlKey || e.metaKey)) return;
const doc = getActiveDocument();
if (!doc) return; // Flag aus → Legacy-Verhalten unangetastet
const key = e.key.toLowerCase();
if (key === 'z' && !e.shiftKey) {
e.preventDefault();
if (doc.undo()) logger.info('V2 undo');
} else if (key === 'y' || (key === 'z' && e.shiftKey)) {
e.preventDefault();
if (doc.redo()) logger.info('V2 redo');
}
};
window.addEventListener('keydown', onKey);
return () => window.removeEventListener('keydown', onKey);
}, []);
// Sync selected template to interaction engine
useEffect(() => {
const interaction = interactionRef.current;