- Introduced a new dry-run endpoint for executing scripts without saving changes. - Implemented a dedicated ScriptDryRunPage for user interaction with dry-run functionality. - Enhanced ScriptsPage to support navigation to the dry-run feature. - Added LogViewer component for displaying logs during script execution. - Created ScriptEditPage for editing scripts with integrated dry-run capabilities. - Updated workflows to include new scripts for fetching and notifying data. - Improved overall user experience with better navigation and error handling.
76 lines
2.1 KiB
React
76 lines
2.1 KiB
React
import { useEffect, useId, useRef } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import mermaid from "mermaid";
|
|
import { useTheme } from "../theme.jsx";
|
|
|
|
function findNode(root, id) {
|
|
return (
|
|
root.querySelector(`#${CSS.escape(id)}`) ||
|
|
root.querySelector(`[id="${CSS.escape(id)}"]`) ||
|
|
root.querySelector(`[id*="${CSS.escape(id)}"]`)
|
|
);
|
|
}
|
|
|
|
export function MermaidDiagram({ chart, scriptIds = {} }) {
|
|
const { theme } = useTheme();
|
|
const navigate = useNavigate();
|
|
const ref = useRef(null);
|
|
const reactId = useId().replace(/:/g, "");
|
|
|
|
const scriptKey = JSON.stringify(scriptIds);
|
|
|
|
useEffect(() => {
|
|
if (!chart || !ref.current) {
|
|
if (ref.current) ref.current.innerHTML = "";
|
|
return;
|
|
}
|
|
|
|
let cancelled = false;
|
|
mermaid.initialize({
|
|
startOnLoad: false,
|
|
securityLevel: "loose",
|
|
suppressErrorRendering: true,
|
|
theme: theme === "dark" ? "dark" : "default",
|
|
});
|
|
|
|
const ids = JSON.parse(scriptKey);
|
|
const renderId = `mmd-${reactId}-${Date.now()}`;
|
|
mermaid
|
|
.render(renderId, chart)
|
|
.then(({ svg }) => {
|
|
if (cancelled || !ref.current) return;
|
|
ref.current.innerHTML = svg;
|
|
for (const [nodeId, script] of Object.entries(ids)) {
|
|
const el = findNode(ref.current, nodeId);
|
|
if (!el) continue;
|
|
el.style.cursor = "pointer";
|
|
el.setAttribute("title", script);
|
|
el.addEventListener("click", () => {
|
|
navigate(`/scripts/${encodeURIComponent(script)}/edit`);
|
|
});
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
if (cancelled || !ref.current) return;
|
|
ref.current.innerHTML = "";
|
|
const p = document.createElement("p");
|
|
p.className = "text-error text-sm";
|
|
p.textContent = "Could not render diagram";
|
|
ref.current.appendChild(p);
|
|
});
|
|
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [chart, scriptKey, theme, navigate, reactId]);
|
|
|
|
if (!chart) return null;
|
|
|
|
return (
|
|
<div
|
|
ref={ref}
|
|
className="mermaid-clickable overflow-x-auto rounded-box border border-base-300 bg-base-200 p-3"
|
|
/>
|
|
);
|
|
}
|