Makros: UI (Button-Objekt, Verwaltungspanel, Symbolleiste)

Zweiter von zwei Commits (Fundament in e670f13). Neues, frei platzierbares
Button-Objekt auf der Fläche, das per Klick ein zugewiesenes Makro
ausführt (Zuweisung im Inspektor oder per Rechtsklick direkt am Button).
Neues "▶ Makros"-Panel (Liste + Formular, dritter "▶ Ausführen"-Button pro
Zeile) für Anlegen/Bearbeiten/Löschen/Testlauf ohne Canvas-Button.

Beim Live-Testen gefunden und behoben: ADDTABLE/ADDSHEET navigieren als
Nebeneffekt zur eingefügten Tabelle/zum eingefügten Blatt (richtig für
einen Symbolleisten-Klick, überraschend für einen Makro-Lauf im
Hintergrund) — runMacro() sichert und stellt jetzt aktives Blatt/Objekt/
Auswahl nach dem Lauf wieder her. Nebenbei zwei bestehende
"impliziter-Else"-Fehler behoben, die mit einer vierten Objektart zu
echten Fehlerquellen geworden wären (io/json.ts normaliseObject,
CanvasObject.vue Render-Dispatch).

Vollständig live per Playwright End-zu-Ende verifiziert: Makro über das
echte Formular angelegt, per Listen-Button und per Button-Objekt
ausgeführt, Rechtsklick-Zuweisung geprüft, ein absichtlich fehlerhaftes
Makro zeigt einen Fehler-Toast statt abzustürzen — keine Konsolenfehler.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
wkh
2026-09-09 10:07:56 +02:00
co-authored by Claude Sonnet 5
parent e670f13077
commit a59fda25b0
11 changed files with 759 additions and 30 deletions
+16
View File
@@ -1524,6 +1524,22 @@ describe('macros (document-level, explicitly-triggered write scripts)', () => {
expect(s.tablesOf(sheetId).length).toBe(before); // added then deleted -- net zero
});
it('runMacro: ADDTABLE on a DIFFERENT sheet does not yank the active sheet/selection there (found live: addTable() itself navigates, a macro must undo just that incidental side effect)', () => {
const s = fresh();
const startSheetId = s.doc.activeSheetId;
const startSelection = s.doc.selection;
const otherSheetId = s.addSheet('Ziel');
s.setActiveSheet(startSheetId); // addSheet() itself also navigates -- go back
expect(s.doc.activeSheetId).toBe(startSheetId);
const macroId = s.addMacro('M', 'ADDTABLE("Ziel"; "Neu")') as string;
expect(s.runMacro(macroId).ok).toBe(true);
expect(s.doc.activeSheetId).toBe(startSheetId); // NOT switched to "Ziel"
expect(s.doc.selection).toEqual(startSelection);
expect(s.tablesOf(otherSheetId).map((t) => t.name)).toContain('Neu'); // the mutation itself still happened
});
it('runMacro: ADDSHEET/RENAMESHEET/DELETESHEET round-trip', () => {
const s = fresh();
const before = s.doc.sheets.length;