From 4228ab78d84457cba1f11914a28fa98c09b73af3 Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Wed, 30 Sep 2026 21:27:11 +0530 Subject: [PATCH] feat(flowchart): undo/redo toolbar buttons + history counter (C3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The flowchart editor had Ctrl+Z / Ctrl+Shift+Z keyboard shortcuts but no discoverable buttons. New History section in the side panel: - Undo / Redo buttons wired to _store.undo() / _store.redo() - Counter chip showing ↶/↷ availability - Buttons auto-disable when stacks are empty (via _store.canUndo() + canRedo() evaluated on every store subscription) The store already exposed undo/redo/canUndo/canRedo — this commit only adds the UI surface. Amit Haridas --- src/flowchart-generator.html | 19 +++++++++++++++++++ src/renderer/flowchart-bundle.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/flowchart-generator.html b/src/flowchart-generator.html index 923d51e..738272d 100644 --- a/src/flowchart-generator.html +++ b/src/flowchart-generator.html @@ -217,6 +217,18 @@ flex-wrap: wrap; margin-bottom: 12px; } + .fc-history-row { + display: flex; + gap: 8px; + align-items: center; + margin-bottom: 12px; + } + .fc-history-count { + margin-left: auto; + font-size: 11px; + color: var(--fc-border); + font-variant-numeric: tabular-nums; + } .fc-ul { list-style: none; padding: 0; @@ -323,6 +335,13 @@ Save to File button alongside Insert at Cursor. -->
+

History

+
+ + + 0 +
+

Add Node

diff --git a/src/renderer/flowchart-bundle.js b/src/renderer/flowchart-bundle.js index f92419a..a284b0f 100644 --- a/src/renderer/flowchart-bundle.js +++ b/src/renderer/flowchart-bundle.js @@ -834,6 +834,9 @@ btnInsert: document.getElementById('fc-btn-insert'), btnSave: document.getElementById('fc-btn-save'), btnReset: document.getElementById('fc-btn-reset'), + btnUndo: document.getElementById('fc-btn-undo'), + btnRedo: document.getElementById('fc-btn-redo'), + historyCount: document.getElementById('fc-history-count'), status: document.getElementById('fc-status'), // v4.11.0 — node-list panel (button-driven UI). Every mutation goes // through controls in this panel; the canvas is purely visual. @@ -1405,6 +1408,8 @@ debouncedPersist(); // Keep the node-list panel in sync with every mutation. rerenderNodeList(); + // v4.13.0 — keep the undo/redo buttons enabled-state in sync. + updateHistoryUI(); }); // Hydrate from disk (defensively — corrupt JSON is caught by the store). @@ -1464,6 +1469,33 @@ }); } + // v4.13.0 — toolbar undo/redo buttons + history counter. Both wired + // here so they share state with the existing keyboard shortcuts. + if (els.btnUndo) { + els.btnUndo.addEventListener('click', () => { + if (!_store) return; + _store.undo(); + }); + } + if (els.btnRedo) { + els.btnRedo.addEventListener('click', () => { + if (!_store) return; + _store.redo(); + }); + } + function updateHistoryUI() { + if (els.historyCount) { + // The store exposes canUndo()/canRedo(); show the stack depth as + // a vague "edit count" so the user has feedback that their work + // is being captured. + const u = _store.canUndo() ? 1 : 0; + const r = _store.canRedo() ? 1 : 0; + els.historyCount.textContent = `${u}↶ / ${r}↷`; + } + if (els.btnUndo) els.btnUndo.disabled = !_store.canUndo(); + if (els.btnRedo) els.btnRedo.disabled = !_store.canRedo(); + } + // Keyboard shortcuts — Ctrl/Cmd+Z / Ctrl/Cmd+Shift+Z. Delete / Backspace // are intentionally NOT wired (v4.11.0 — there is no canvas selection // state anymore; use the × buttons in the node-list panel instead).