mirror of
https://github.com/bunny-lab-io/Borealis.git
synced 2025-09-11 04:58:41 -06:00
Merge pull request #17 from bunny-lab-io/om8fcu-codex/modify-workflow-open-behavior-and-tabs
Everything functionally passes validation. Minor issues with Navigation Sidebar to sort out from Global Timer Functionality, but not a priority at the moment.
This commit is contained in:
@@ -136,6 +136,45 @@ export default function App() {
|
||||
const handleAboutMenuClose = () => setAboutAnchorEl(null);
|
||||
const openCreditsDialog = () => { handleAboutMenuClose(); setCreditsDialogOpen(true); };
|
||||
|
||||
const handleTabRightClick = (evt, tabId) => {
|
||||
evt.preventDefault();
|
||||
setTabMenuAnchor({ x: evt.clientX, y: evt.clientY });
|
||||
setTabMenuTabId(tabId);
|
||||
};
|
||||
|
||||
const handleCloseTab = () => {
|
||||
setTabs((prev) => {
|
||||
const filtered = prev.filter((t) => t.id !== tabMenuTabId);
|
||||
if (filtered.length === 0) {
|
||||
const newTab = { id: "flow_1", tab_name: "Flow 1", nodes: [], edges: [] };
|
||||
setActiveTabId(newTab.id);
|
||||
return [newTab];
|
||||
}
|
||||
if (activeTabId === tabMenuTabId) {
|
||||
setActiveTabId(filtered[0].id);
|
||||
}
|
||||
return filtered;
|
||||
});
|
||||
setTabMenuAnchor(null);
|
||||
};
|
||||
|
||||
const handleRenameTab = () => {
|
||||
const tab = tabs.find((t) => t.id === tabMenuTabId);
|
||||
if (tab) {
|
||||
setRenameTabId(tabMenuTabId);
|
||||
setRenameValue(tab.tab_name);
|
||||
setRenameDialogOpen(true);
|
||||
}
|
||||
setTabMenuAnchor(null);
|
||||
};
|
||||
|
||||
const handleSaveRename = () => {
|
||||
setTabs((prev) =>
|
||||
prev.map((t) => (t.id === renameTabId ? { ...t, tab_name: renameValue } : t))
|
||||
);
|
||||
setRenameDialogOpen(false);
|
||||
};
|
||||
|
||||
const renderMainContent = () => {
|
||||
switch (currentPage) {
|
||||
case "devices":
|
||||
@@ -147,29 +186,35 @@ export default function App() {
|
||||
case "workflows":
|
||||
return (
|
||||
<WorkflowList
|
||||
onOpenWorkflow={(workflow) => {
|
||||
// If workflow name exists in tabs, just switch to it
|
||||
if (workflow?.name) {
|
||||
const existing = tabs.find(
|
||||
(t) => t.tab_name.toLowerCase() === workflow.name.toLowerCase()
|
||||
onOpenWorkflow={async (workflow) => {
|
||||
const newId = "flow_" + Date.now();
|
||||
if (workflow && workflow.rel_path) {
|
||||
try {
|
||||
const resp = await fetch(
|
||||
`/api/storage/load_workflow?path=${encodeURIComponent(
|
||||
workflow.rel_path
|
||||
)}`
|
||||
);
|
||||
if (existing) {
|
||||
setActiveTabId(existing.id);
|
||||
setCurrentPage("workflow-editor");
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Otherwise, create a new workflow tab
|
||||
const newId = "flow_" + (tabs.length + 1);
|
||||
setTabs((prev) => [
|
||||
...prev,
|
||||
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
|
||||
const data = await resp.json();
|
||||
setTabs([
|
||||
{
|
||||
id: newId,
|
||||
tab_name: workflow?.name || `Flow ${tabs.length + 1}`,
|
||||
nodes: [],
|
||||
edges: []
|
||||
tab_name:
|
||||
data.tab_name || workflow.name || workflow.file_name || "Workflow",
|
||||
nodes: data.nodes || [],
|
||||
edges: data.edges || []
|
||||
}
|
||||
]);
|
||||
} catch (err) {
|
||||
console.error("Failed to load workflow:", err);
|
||||
setTabs([
|
||||
{ id: newId, tab_name: workflow?.name || "Workflow", nodes: [], edges: [] }
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
setTabs([{ id: newId, tab_name: `Flow`, nodes: [], edges: [] }]);
|
||||
}
|
||||
setActiveTabId(newId);
|
||||
setCurrentPage("workflow-editor");
|
||||
}}
|
||||
@@ -196,7 +241,7 @@ export default function App() {
|
||||
activeTabId={activeTabId}
|
||||
onTabChange={setActiveTabId}
|
||||
onAddTab={() => {}}
|
||||
onTabRightClick={() => {}}
|
||||
onTabRightClick={handleTabRightClick}
|
||||
/>
|
||||
<Box sx={{ flexGrow: 1, position: "relative" }}>
|
||||
{tabs.map((tab) => (
|
||||
@@ -276,13 +321,13 @@ export default function App() {
|
||||
value={renameValue}
|
||||
onChange={setRenameValue}
|
||||
onCancel={() => setRenameDialogOpen(false)}
|
||||
onSave={() => {}}
|
||||
onSave={handleSaveRename}
|
||||
/>
|
||||
<TabContextMenu
|
||||
anchor={tabMenuAnchor}
|
||||
onClose={() => setTabMenuAnchor(null)}
|
||||
onRename={() => {}}
|
||||
onCloseTab={() => {}}
|
||||
onRename={handleRenameTab}
|
||||
onCloseTab={handleCloseTab}
|
||||
/>
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
@@ -133,7 +133,7 @@ export function TabContextMenu({ anchor, onClose, onRename, onCloseTab }) {
|
||||
}}
|
||||
>
|
||||
<MenuItem onClick={onRename}>Rename</MenuItem>
|
||||
<MenuItem onClick={onCloseTab}>Close</MenuItem>
|
||||
<MenuItem onClick={onCloseTab}>Close Workflow</MenuItem>
|
||||
</Menu>
|
||||
);
|
||||
}
|
@@ -170,6 +170,22 @@ def load_workflows():
|
||||
"workflows": results
|
||||
})
|
||||
|
||||
|
||||
@app.route("/api/storage/load_workflow", methods=["GET"])
|
||||
def load_workflow():
|
||||
"""Load a single workflow JSON by its relative path."""
|
||||
rel_path = request.args.get("path", "")
|
||||
workflows_root = os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), "..", "..", "Workflows")
|
||||
)
|
||||
abs_path = os.path.abspath(os.path.join(workflows_root, rel_path))
|
||||
|
||||
if not abs_path.startswith(workflows_root) or not os.path.isfile(abs_path):
|
||||
return jsonify({"error": "Workflow not found"}), 404
|
||||
|
||||
obj = _safe_read_json(abs_path)
|
||||
return jsonify(obj)
|
||||
|
||||
# ---------------------------------------------
|
||||
# Borealis Agent API Endpoints
|
||||
# ---------------------------------------------
|
||||
|
Reference in New Issue
Block a user