diff --git a/Data/Server/WebUI/src/Workflow_List.jsx b/Data/Server/WebUI/src/Workflow_List.jsx index d2cd4c1..d778b6b 100644 --- a/Data/Server/WebUI/src/Workflow_List.jsx +++ b/Data/Server/WebUI/src/Workflow_List.jsx @@ -22,12 +22,37 @@ import { } from "@mui/x-tree-view"; import { RenameWorkflowDialog, RenameFolderDialog } from "./Dialogs"; -function buildTree(workflows) { +function buildTree(workflows, folders) { const map = {}; - const root = []; + const rootNode = { + id: "root", + label: "Workflows", + path: "", + isFolder: true, + children: [] + }; + map[rootNode.id] = rootNode; + + (folders || []).forEach((f) => { + const parts = (f || "").split("/"); + let children = rootNode.children; + let parentPath = ""; + parts.forEach((part) => { + const path = parentPath ? `${parentPath}/${part}` : part; + let node = children.find((n) => n.id === path); + if (!node) { + node = { id: path, label: part, path, isFolder: true, children: [] }; + children.push(node); + map[path] = node; + } + children = node.children; + parentPath = path; + }); + }); + (workflows || []).forEach((w) => { const parts = (w.rel_path || "").split("/"); - let children = root; + let children = rootNode.children; let parentPath = ""; parts.forEach((part, idx) => { const path = parentPath ? `${parentPath}/${part}` : part; @@ -56,7 +81,8 @@ function buildTree(workflows) { } }); }); - return { root, map }; + + return { root: [rootNode], map }; } export default function WorkflowList({ onOpenWorkflow }) { @@ -96,7 +122,7 @@ export default function WorkflowList({ onOpenWorkflow }) { const resp = await fetch("/api/storage/load_workflows"); if (!resp.ok) throw new Error(`HTTP ${resp.status}`); const data = await resp.json(); - const { root, map } = buildTree(data.workflows || []); + const { root, map } = buildTree(data.workflows || [], data.folders || []); setTree(root); setNodeMap(map); } catch (err) { @@ -126,6 +152,13 @@ export default function WorkflowList({ onOpenWorkflow }) { else setRenameOpen(true); }; + const handleEdit = () => { + closeMenu(); + if (selectedNode && !selectedNode.isFolder && onOpenWorkflow) { + onOpenWorkflow(selectedNode.workflow); + } + }; + const handleDeleteWorkflow = async () => { closeMenu(); if (!selectedNode) return; @@ -212,9 +245,9 @@ export default function WorkflowList({ onOpenWorkflow }) { }} > {n.isFolder ? ( - + ) : ( - + )} {n.label} - + Workflows @@ -255,10 +288,10 @@ export default function WorkflowList({ onOpenWorkflow }) { startIcon={} sx={{ mr: 1, - color: "#58a6ff", - borderColor: "#58a6ff", + color: "#0475c2", + borderColor: "#0475c2", textTransform: "none", - border: "1px solid #58a6ff", + border: "1px solid #0475c2", backgroundColor: "#1e1e1e", "&:hover": { backgroundColor: "#1b1b1b" } }} @@ -273,10 +306,10 @@ export default function WorkflowList({ onOpenWorkflow }) {