feat(sidebar): register flowchart panel + rail button + thin fs IPC

- Add data-panel=flowchart rail button in src/index.html after daily-notes

- Append .flowchart-* panel CSS selectors to src/styles-sidebar.css

- Add flowchartIO IPC bridge and registerPanel('flowchart') in src/renderer.js

- Add get-user-data-path / read-text-file / write-text-file IPC in src/main.js

- Path validation: sandbox inside app.getPath('userData')

- read-text-file returns null on ENOENT (file doesn't exist)

Amit Haridas
This commit is contained in:
2026-09-14 21:52:32 +05:30
parent a6dc54cedc
commit b0dcf57daf
4 changed files with 179 additions and 0 deletions
+42
View File
@@ -154,6 +154,14 @@ if (typeof window !== 'undefined' && !window.electronAPI) {
};
}
// Lazy-loaded: filesystem helpers used by the flowchart panel for
// <userData>/flowchart-session.json auto-save.
const flowchartIO = {
getUserDataPath: () => ipcRenderer.invoke('get-user-data-path'),
readFile: (p) => ipcRenderer.invoke('read-text-file', p),
writeFile: (p, content) => ipcRenderer.invoke('write-text-file', { path: p, content }),
};
// Use window.ModalManager if already set by script tag, otherwise require it.
// This prevents "Identifier 'ModalManager' has already been declared" when
// both the script tag in index.html and CommonJS require() declare it.
@@ -2406,6 +2414,40 @@ document.addEventListener('DOMContentLoaded', async () => {
}),
});
// Flow Chart Editor panel — visual Mermaid flowchart builder.
// Persists to <userData>/flowchart-session.json via injected IPC helpers.
// Reuses tabManager.insertAtCursor for the "Insert at Cursor" button.
const { renderFlowChartPanel } = require('./sidebar/flowchart-panel');
// Reuse the existing Mermaid render path used by the preview pane
// (src/renderer.js:1106-1142). Lazily loads mermaid on first use.
const renderFlowChartMermaid = (source, targetEl) => {
targetEl.innerHTML = '';
const div = document.createElement('div');
div.className = 'mermaid';
div.textContent = source;
targetEl.appendChild(div);
if (!window.mermaid) {
const mermaidModule = require('mermaid');
window.mermaid = mermaidModule.default || mermaidModule;
}
const theme = document.body.className.includes('theme-dark') ? 'dark' : 'default';
window.mermaid.initialize({ startOnLoad: false, theme, securityLevel: 'loose' });
window.mermaid
.run({ nodes: [div] })
.catch((err) => console.warn('flowchart preview render failed:', err));
};
sidebarManager.registerPanel('flowchart', {
title: 'Flow Chart',
render: (container) =>
renderFlowChartPanel(container, {
getUserDataPath: flowchartIO.getUserDataPath,
readFile: flowchartIO.readFile,
writeFile: flowchartIO.writeFile,
insertAtCursor: (text) => tabManager.insertAtCursor(text),
renderMermaid: renderFlowChartMermaid,
}),
});
// Wiki-link navigation: open the target note (creating it on demand after
// confirmation). Delegated on document so it works in every tab's preview.
document.addEventListener('click', (event) => {