task(E1): seating-row/block drag interaction with live preview and options

This commit is contained in:
Agent Zero
2026-08-27 22:46:51 +02:00
parent b875012afd
commit 86b1e0b8db
2 changed files with 208 additions and 17 deletions
+70 -2
View File
@@ -370,14 +370,16 @@ describe('A4.9 pilot: event tools', () => {
const ctx = makeCtx({ doc });
const block = eventToolsV2Plugin.tools!.find((t) => t.manifest.id === 'seating-block')!;
block.handlers.down!(pe(0, 0), ctx); // Legacy-Default: rows=3, cols=8
// E1: Drag-Interaktion (down + up) mit Distanz 200×100, spacing 50
block.handlers.down!(pe(0, 0), ctx);
block.handlers.up!(pe(200, 100), ctx); // 4 cols × 2 rows = 8 Stühle
const all = doc.getAllElements();
expect(all.length).toBeGreaterThan(1); // Multi-Element-Satz
expect(all.every((e) => e.type === 'chair')).toBe(true);
// BUG-1-Regressionsschutz: alle Reihen im Block haben eigene rowIds
const rowIds = new Set(all.map((e) => e.properties.rowId));
expect(rowIds.size).toBeGreaterThanOrEqual(3);
expect(rowIds.size).toBe(2); // Drag 100mm bei spacing 50 → 2 Reihen
// Kern-Akzeptanz: EIN undo entfernt den GANZEN Block
expect(doc.undo()).toBe(true);
@@ -390,7 +392,9 @@ describe('A4.9 pilot: event tools', () => {
const ctx = makeCtx({ doc });
const row = eventToolsV2Plugin.tools!.find((t) => t.manifest.id === 'seating-row')!;
// E1: Drag-Interaktion (down + up statt nur down)
row.handlers.down!(pe(0, 0), ctx);
row.handlers.up!(pe(200, 0), ctx); // Länge 200, spacing 50 → 4 Stühle
const all = doc.getAllElements();
expect(all.length).toBeGreaterThanOrEqual(2);
const rowIds = new Set(all.map((e) => e.properties.rowId));
@@ -922,3 +926,67 @@ describe('C3fin interaktiv: handle-drag on select tool', () => {
expect(selIds).toEqual(['r3']);
});
});
describe('E1: seating-row drag', () => {
it('berechnet count aus Laenge und committet in EINER Transaktion', () => {
const { ydoc } = createInMemoryDoc();
const doc = new CADDocument(ydoc);
const ctx = makeCtx({ doc, options: { spacing: 50 } });
const row = eventToolsV2Plugin.tools!.find((t) => t.manifest.id === 'seating-row')!;
// Start bei (0,0), Ende bei (300,0): Länge 300, spacing 50 → 6 Stühle
row.handlers.down!(pe(0, 0), ctx);
row.handlers.move!(pe(150, 0), ctx); // Live-Preview
expect(ctx.previews.length).toBe(1);
row.handlers.up!(pe(300, 0), ctx);
const all = doc.getAllElements();
expect(all.length).toBe(6);
expect(all.every((e) => e.type === 'chair')).toBe(true);
// Eine rowId für alle:
const rowIds = new Set(all.map((e) => e.properties.rowId));
expect(rowIds.size).toBe(1);
// EIN Undo entfernt die ganze Reihe:
expect(doc.undo()).toBe(true);
expect(doc.getAllElements().length).toBe(0);
});
it('cancel verwirft die laufende Reihe', () => {
const { ydoc } = createInMemoryDoc();
const doc = new CADDocument(ydoc);
const ctx = makeCtx({ doc });
const row = eventToolsV2Plugin.tools!.find((t) => t.manifest.id === 'seating-row')!;
row.handlers.down!(pe(0, 0), ctx);
row.handlers.cancel!(ctx);
row.handlers.up!(pe(100, 0), ctx); // nach cancel: kein dragStart
expect(doc.getAllElements().length).toBe(0);
});
});
describe('E1: seating-block drag', () => {
it('berechnet rows×cols aus Distanz und committet Multi-Element-Set', () => {
const { ydoc } = createInMemoryDoc();
const doc = new CADDocument(ydoc);
const ctx = makeCtx({ doc, options: { colSpacing: 50, rowSpacing: 50 } });
const block = eventToolsV2Plugin.tools!.find((t) => t.manifest.id === 'seating-block')!;
// Start (0,0), Ende (150,100): w=150/50=3 cols, h=100/50=2 rows → 6 Stühle
block.handlers.down!(pe(0, 0), ctx);
block.handlers.up!(pe(150, 100), ctx);
const all = doc.getAllElements();
expect(all.length).toBe(6);
expect(all.every((e) => e.type === 'chair')).toBe(true);
// BUG-1-Regressionsschutz: rowIds pro Reihe eindeutig
const rowIds = new Set(all.map((e) => e.properties.rowId));
expect(rowIds.size).toBe(2);
// EIN Undo entfernt den ganzen Block:
expect(doc.undo()).toBe(true);
expect(doc.getAllElements().length).toBe(0);
});
});