Files
web-cad/frontend/src/services/blockEditorService.ts
T

95 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Task CAD-5 Block-Editor-Service.
*
* openBlockForEdit legt markierte KOPIEN der Block-Elemente ins
* Dokument (Original unangetastet); saveBlockEdit schreibt die
* bearbeiteten Kopien als neue Blockdefinition zurueck und
* raeumt die Edit-Kopien auf; discardBlockEdit verwirft alles.
* Marker: BLOCK_EDIT_MARKER (properties-Flag + __blockEdit-IDs).
*/
import type { CADElement, BlockDefinition } from '../types/cad.types';
import type { CADDocument } from '../kernel/document/CADDocument';
/** Marker-Flag in properties der Edit-Kopien. */
export const BLOCK_EDIT_MARKER = '__blockEdit';
/** Aktive Edit-Sitzung (Service-State). */
let editSession: { blockId: string; copyIds: string[] } | null = null;
/**
* Oeffnet einen Block zur Bearbeitung: Kopien aller Elemente mit
* Edit-Marker werden ins Dokument gelegt (Original bleibt).
* @returns true wenn geoeffnet, false bei unbekannter ID oder
* bereits offener Sitzung.
*/
export function openBlockForEdit(doc: CADDocument, blockId: string): boolean {
if (editSession) return false;
const block = doc.getBlock(blockId);
if (!block) return false;
const copyIds: string[] = [];
doc.transact(() => {
for (const el of block.elements) {
const copy: CADElement = {
...el,
id: `__blockEdit_${blockId}_${copyIds.length}`,
properties: {
...(el.properties as Record<string, unknown>),
[BLOCK_EDIT_MARKER]: true,
},
} as unknown as CADElement;
doc.addElement(copy);
copyIds.push(copy.id);
}
});
editSession = { blockId, copyIds };
return true;
}
/**
* Speichert die Bearbeitung: die markierten Kopien werden als
* neue Elementliste in die Blockdefinition geschrieben (Marker
* entfernt); Edit-Kopien werden aus dem Dokument geloescht.
* @returns blockId der gespeicherten Definition oder null.
*/
export function saveBlockEdit(doc: CADDocument): string | null {
if (!editSession) return null;
const { blockId, copyIds } = editSession;
const elements: CADElement[] = [];
for (const id of copyIds) {
const el = doc.getElement(id);
if (!el) continue;
const { [BLOCK_EDIT_MARKER]: _marker, ...cleanProps } =
el.properties as Record<string, unknown>;
elements.push({ ...el, id: uid('blk'), properties: cleanProps } as unknown as CADElement);
}
const block = doc.getBlock(blockId);
if (block) {
doc.addBlock({ ...block, elements });
}
doc.deleteElements(copyIds);
editSession = null;
return blockId;
}
/**
* Verwirft die Bearbeitung: Edit-Kopien werden geloescht, die
* Blockdefinition bleibt unveraendert.
* @returns true wenn verworfen, false ohne offene Sitzung.
*/
export function discardBlockEdit(doc: CADDocument): boolean {
if (!editSession) return false;
doc.deleteElements(editSession.copyIds);
editSession = null;
return true;
}
/** Ist gerade eine Block-Bearbeitung offen? */
export function isBlockEditOpen(): boolean {
return editSession !== null;
}
let uidCounter = 0;
function uid(prefix: string): string {
return `${prefix}_${Date.now().toString(36)}_${uidCounter++}_${Math.random().toString(36).slice(2, 8)}`;
}