feat: enhance project structure with server and workflow management

- Introduced a new server package with Fastify for handling API requests and workflows.
- Implemented user authentication and authorization with JWT and cookie management.
- Added endpoints for managing workflows, runs, and user accounts.
- Established a dashboard for monitoring workflow status and statistics.
- Included a script sandbox for executing user-defined scripts securely.
- Updated README with setup instructions and API documentation.
- Configured database migrations for user management.
- Enhanced logging capabilities for better traceability.
This commit is contained in:
2026-08-14 14:25:37 +07:00
parent 5574d6f723
commit 023cf83cfa
48 changed files with 6127 additions and 359 deletions
@@ -0,0 +1,75 @@
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?edit=${encodeURIComponent(script)}`);
});
}
})
.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"
/>
);
}