flowstudio 0.0.30 → 0.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/ai_creator.d.ts +1 -1
- package/dist/ai_creator.js +24 -128
- package/dist/ai_creator.js.map +1 -1
- package/dist/api_calls.d.ts +2 -0
- package/dist/api_calls.js +147 -0
- package/dist/api_calls.js.map +1 -0
- package/dist/app_analytics.d.ts +1 -1
- package/dist/app_analytics.js +75 -69
- package/dist/app_analytics.js.map +1 -1
- package/dist/app_details.d.ts +1 -1
- package/dist/app_details.js +25 -24
- package/dist/app_details.js.map +1 -1
- package/dist/app_layout.d.ts +2 -2
- package/dist/app_layout.js +4 -4
- package/dist/app_layout.js.map +1 -1
- package/dist/app_settings.d.ts +1 -1
- package/dist/app_settings.js +76 -8
- package/dist/app_settings.js.map +1 -1
- package/dist/bottom_left_panel.d.ts +1 -0
- package/dist/bottom_left_panel.js +8 -0
- package/dist/bottom_left_panel.js.map +1 -0
- package/dist/code.d.ts +1 -1
- package/dist/code.js +6 -2
- package/dist/code.js.map +1 -1
- package/dist/components/ftable.d.ts +13 -0
- package/dist/components/ftable.js +65 -0
- package/dist/components/ftable.js.map +1 -0
- package/dist/components/gsheet/index.d.ts +1 -0
- package/dist/components/gsheet/index.js +21 -0
- package/dist/components/gsheet/index.js.map +1 -0
- package/dist/components/mention_input/index.d.ts +18 -1
- package/dist/components/mention_input/index.js +203 -111
- package/dist/components/mention_input/index.js.map +1 -1
- package/dist/components/paginator_table.d.ts +1 -1
- package/dist/components/paginator_table.js +2 -2
- package/dist/components/paginator_table.js.map +1 -1
- package/dist/components/sheet/index.d.ts +1 -1
- package/dist/components/sheet/index.js +4 -2
- package/dist/components/sheet/index.js.map +1 -1
- package/dist/components/ui/alert.d.ts +8 -0
- package/dist/components/ui/alert.js +23 -0
- package/dist/components/ui/alert.js.map +1 -0
- package/dist/components/ui/badge.d.ts +9 -0
- package/dist/components/ui/badge.js +21 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/button.d.ts +11 -0
- package/dist/components/ui/button.js +35 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/card.d.ts +8 -0
- package/dist/components/ui/card.js +17 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +19 -0
- package/dist/components/ui/dialog.js +33 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +27 -0
- package/dist/components/ui/dropdown-menu.js +46 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/form.d.ts +24 -0
- package/dist/components/ui/form.js +61 -0
- package/dist/components/ui/form.js.map +1 -0
- package/dist/components/ui/input-group.d.ts +16 -0
- package/dist/components/ui/input-group.js +65 -0
- package/dist/components/ui/input-group.js.map +1 -0
- package/dist/components/ui/input.d.ts +5 -0
- package/dist/components/ui/input.js +9 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/label.d.ts +5 -0
- package/dist/components/ui/label.js +10 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/popover.d.ts +7 -0
- package/dist/components/ui/popover.js +23 -0
- package/dist/components/ui/popover.js.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +5 -0
- package/dist/components/ui/scroll-area.js +12 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/select.d.ts +13 -0
- package/dist/components/ui/select.js +37 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/separator.d.ts +4 -0
- package/dist/components/ui/separator.js +8 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/sheet.d.ts +13 -0
- package/dist/components/ui/sheet.js +93 -0
- package/dist/components/ui/sheet.js.map +1 -0
- package/dist/components/ui/skeleton.d.ts +2 -0
- package/dist/components/ui/skeleton.js +7 -0
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/components/ui/sonner.d.ts +3 -0
- package/dist/components/ui/sonner.js +42 -0
- package/dist/components/ui/sonner.js.map +1 -0
- package/dist/components/ui/spinner.d.ts +7 -0
- package/dist/components/ui/spinner.js +17 -0
- package/dist/components/ui/spinner.js.map +1 -0
- package/dist/components/ui/switch.d.ts +4 -0
- package/dist/components/ui/switch.js +8 -0
- package/dist/components/ui/switch.js.map +1 -0
- package/dist/components/ui/table.d.ts +10 -0
- package/dist/components/ui/table.js +21 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/tabs.d.ts +7 -0
- package/dist/components/ui/tabs.js +13 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +5 -0
- package/dist/components/ui/textarea.js +9 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +7 -0
- package/dist/components/ui/tooltip.js +11 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/constants.js +5 -4
- package/dist/constants.js.map +1 -1
- package/dist/context.d.ts +1 -1
- package/dist/context.js +2 -2
- package/dist/context.js.map +1 -1
- package/dist/envs.d.ts +2 -2
- package/dist/envs.js +2 -150
- package/dist/envs.js.map +1 -1
- package/dist/functions.d.ts +2 -5
- package/dist/functions.js +2 -210
- package/dist/functions.js.map +1 -1
- package/dist/globals.css +264 -0
- package/dist/home.d.ts +1 -1
- package/dist/home.js +64 -26
- package/dist/home.js.map +1 -1
- package/dist/index.d.ts +19 -3
- package/dist/index.js +81 -22
- package/dist/index.js.map +1 -1
- package/dist/lib/pane-context.d.ts +10 -0
- package/dist/lib/pane-context.js +21 -0
- package/dist/lib/pane-context.js.map +1 -0
- package/dist/lib/toast.d.ts +12 -0
- package/dist/lib/toast.js +36 -0
- package/dist/lib/toast.js.map +1 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +6 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/new_project.d.ts +1 -1
- package/dist/new_project.js +60 -41
- package/dist/new_project.js.map +1 -1
- package/dist/node.d.ts +2 -2
- package/dist/node.js +152 -39
- package/dist/node.js.map +1 -1
- package/dist/project_widget.d.ts +2 -1
- package/dist/project_widget.js +6 -2
- package/dist/project_widget.js.map +1 -1
- package/dist/secrets.d.ts +2 -0
- package/dist/secrets.js +130 -0
- package/dist/secrets.js.map +1 -0
- package/dist/simulator.d.ts +1 -1
- package/dist/simulator.js +184 -63
- package/dist/simulator.js.map +1 -1
- package/dist/studio_pane.d.ts +1 -1
- package/dist/studio_pane.js +319 -56
- package/dist/studio_pane.js.map +1 -1
- package/dist/studio_pane_old.d.ts +1 -1
- package/dist/studio_pane_old.js +2 -3
- package/dist/studio_pane_old.js.map +1 -1
- package/dist/studio_pane_old_new.d.ts +1 -1
- package/dist/studio_pane_old_new.js +2 -3
- package/dist/studio_pane_old_new.js.map +1 -1
- package/dist/styles/globals.css +59 -0
- package/dist/styles.css +2 -0
- package/dist/top_center_panel.d.ts +1 -1
- package/dist/top_center_panel.js +4 -3
- package/dist/top_center_panel.js.map +1 -1
- package/dist/top_left_panel.d.ts +1 -1
- package/dist/top_left_panel.js +7 -41
- package/dist/top_left_panel.js.map +1 -1
- package/dist/top_right_panel.d.ts +1 -1
- package/dist/top_right_panel.js +12 -13
- package/dist/top_right_panel.js.map +1 -1
- package/dist/triggers.d.ts +2 -2
- package/dist/triggers.js +56 -37
- package/dist/triggers.js.map +1 -1
- package/dist/zustand/store.d.ts +411 -3
- package/dist/zustand/store.js +4 -0
- package/dist/zustand/store.js.map +1 -1
- package/package.json +54 -26
- package/src/globals.css +264 -0
- package/src/styles/globals.css +59 -0
- package/dist/components/combo_box/index.d.ts +0 -2
- package/dist/components/combo_box/index.js +0 -150
- package/dist/components/combo_box/index.js.map +0 -1
- package/dist/components/combo_box/style.css +0 -10
- package/dist/components/date_picker/index.d.ts +0 -1
- package/dist/components/date_picker/index.js +0 -46
- package/dist/components/date_picker/index.js.map +0 -1
- package/dist/components/date_picker/style.css +0 -204
- package/dist/components/gtable.d.ts +0 -15
- package/dist/components/gtable.js +0 -122
- package/dist/components/gtable.js.map +0 -1
- package/src/components/combo_box/style.css +0 -10
- package/src/components/date_picker/style.css +0 -204
package/dist/studio_pane.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import GNode, { FNode } from './node';
|
|
3
|
+
import { ReactFlow, useNodesState, useEdgesState, addEdge, Background, Panel, SmoothStepEdge, useReactFlow, reconnectEdge, useKeyPress } from '@xyflow/react';
|
|
4
|
+
import GNode from './node';
|
|
6
5
|
import ContextMenu from './context';
|
|
7
6
|
import { useConfigStore } from './zustand/store';
|
|
8
7
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
@@ -15,17 +14,26 @@ import TopLeftPanel from './top_left_panel';
|
|
|
15
14
|
import './studio.css';
|
|
16
15
|
import AppAnalytics from './app_analytics';
|
|
17
16
|
import flow_constants from './constants';
|
|
17
|
+
import BottomLeftPanel from './bottom_left_panel';
|
|
18
|
+
import { toast } from './lib/toast';
|
|
19
|
+
const CustomSmoothstepEdge = memo(({ data, ...props }) => {
|
|
20
|
+
return _jsx(SmoothStepEdge, { ...props, data: data, style: { strokeWidth: 2 } });
|
|
21
|
+
});
|
|
18
22
|
// Constants
|
|
19
23
|
const MAX_HISTORY_SIZE = 50;
|
|
20
|
-
const AUTO_SAVE_DELAY =
|
|
24
|
+
const AUTO_SAVE_DELAY = 3000;
|
|
21
25
|
const QUERY_STALE_TIME = 5 * 60 * 1000; // 5 minutes
|
|
22
26
|
const QUERY_CACHE_TIME = 10 * 60 * 1000; // 10 minutes
|
|
23
27
|
// Node templates for performance
|
|
24
28
|
const NODE_TEMPLATES = {
|
|
25
|
-
function: {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
},
|
|
29
|
+
// function: {
|
|
30
|
+
// type: 'fNode' as const,
|
|
31
|
+
// data: { label: '', function: '' }
|
|
32
|
+
// },
|
|
33
|
+
// gotonode: {
|
|
34
|
+
// type: 'gotoNode' as const,
|
|
35
|
+
// data: { label: '', function: '' }
|
|
36
|
+
// },
|
|
29
37
|
default: {
|
|
30
38
|
type: 'gNode',
|
|
31
39
|
data: {
|
|
@@ -40,6 +48,132 @@ const NODE_TEMPLATES = {
|
|
|
40
48
|
}
|
|
41
49
|
}
|
|
42
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Auto-arrange nodes for horizontal left-to-right flow
|
|
53
|
+
* - Nodes are arranged in levels (columns) from left to right
|
|
54
|
+
* - Within each level, nodes are ordered top-to-bottom based on their parent positions
|
|
55
|
+
* - This creates a clean hierarchical layout that respects input source ordering
|
|
56
|
+
*
|
|
57
|
+
* Nodes: any[] where each node has at least `.id` and optional `.data?.type === 'start'`
|
|
58
|
+
* Edges: any[] where each edge has `.source` and `.target` (ids)
|
|
59
|
+
*/
|
|
60
|
+
function autoArrangeNodes(nodes, edges, options = {}) {
|
|
61
|
+
if (!nodes || nodes.length === 0)
|
|
62
|
+
return nodes;
|
|
63
|
+
const { horizontalSpacing = 80, verticalSpacing = 50, nodeWidth: DEFAULT_WIDTH = 250, nodeHeight: DEFAULT_HEIGHT = 200, } = options;
|
|
64
|
+
// Use the actual rendered size when available (React Flow populates node.measured after paint)
|
|
65
|
+
const nw = (n) => { var _a, _b, _c; return (_c = (_b = (_a = n.measured) === null || _a === void 0 ? void 0 : _a.width) !== null && _b !== void 0 ? _b : n.width) !== null && _c !== void 0 ? _c : DEFAULT_WIDTH; };
|
|
66
|
+
const nh = (n) => { var _a, _b, _c; return (_c = (_b = (_a = n.measured) === null || _a === void 0 ? void 0 : _a.height) !== null && _b !== void 0 ? _b : n.height) !== null && _c !== void 0 ? _c : DEFAULT_HEIGHT; };
|
|
67
|
+
const nodeById = new Map(nodes.map((n) => [n.id, n]));
|
|
68
|
+
// ── 1. Build adjacency (deduplicate, skip self-loops) ────────────────────
|
|
69
|
+
const nodeSet = new Set(nodes.map((n) => n.id));
|
|
70
|
+
const childMap = new Map();
|
|
71
|
+
const parentMap = new Map();
|
|
72
|
+
nodes.forEach((n) => { childMap.set(n.id, []); parentMap.set(n.id, []); });
|
|
73
|
+
const seenEdge = new Set();
|
|
74
|
+
edges.forEach((e) => {
|
|
75
|
+
const key = `${e.source}|${e.target}`;
|
|
76
|
+
if (nodeSet.has(e.source) && nodeSet.has(e.target) && e.source !== e.target && !seenEdge.has(key)) {
|
|
77
|
+
seenEdge.add(key);
|
|
78
|
+
childMap.get(e.source).push(e.target);
|
|
79
|
+
parentMap.get(e.target).push(e.source);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
// ── 2. Shortest-path BFS layering ────────────────────────────────────────
|
|
83
|
+
const levelMap = new Map();
|
|
84
|
+
const visited = new Set();
|
|
85
|
+
const roots = nodes.filter((n) => { var _a, _b; return ((_b = (_a = parentMap.get(n.id)) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) === 0; });
|
|
86
|
+
const queue = (roots.length > 0 ? roots : [nodes[0]])
|
|
87
|
+
.map((n) => ({ id: n.id, level: 0 }));
|
|
88
|
+
while (queue.length > 0) {
|
|
89
|
+
const { id, level } = queue.shift();
|
|
90
|
+
if (visited.has(id))
|
|
91
|
+
continue;
|
|
92
|
+
visited.add(id);
|
|
93
|
+
levelMap.set(id, level);
|
|
94
|
+
(childMap.get(id) || []).forEach((c) => {
|
|
95
|
+
if (!visited.has(c))
|
|
96
|
+
queue.push({ id: c, level: level + 1 });
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
let extraCol = levelMap.size > 0 ? Math.max(...Array.from(levelMap.values())) + 1 : 0;
|
|
100
|
+
nodes.forEach((n) => { if (!levelMap.has(n.id))
|
|
101
|
+
levelMap.set(n.id, extraCol++); });
|
|
102
|
+
// ── 3. Group into columns ─────────────────────────────────────────────────
|
|
103
|
+
const columns = new Map();
|
|
104
|
+
levelMap.forEach((lv, id) => {
|
|
105
|
+
if (!columns.has(lv))
|
|
106
|
+
columns.set(lv, []);
|
|
107
|
+
columns.get(lv).push(id);
|
|
108
|
+
});
|
|
109
|
+
const sortedLevels = Array.from(columns.keys()).sort((a, b) => a - b);
|
|
110
|
+
// ── 4. Compute column X positions using actual node widths ────────────────
|
|
111
|
+
const colX = [];
|
|
112
|
+
let curX = 0;
|
|
113
|
+
sortedLevels.forEach((lv, colIdx) => {
|
|
114
|
+
colX[colIdx] = curX;
|
|
115
|
+
const maxW = Math.max(...(columns.get(lv).map(id => nw(nodeById.get(id)))));
|
|
116
|
+
curX += maxW + horizontalSpacing;
|
|
117
|
+
});
|
|
118
|
+
// ── 5. Place nodes — sequential Y using actual heights, centred on parents ─
|
|
119
|
+
const pos = new Map();
|
|
120
|
+
sortedLevels.forEach((lv, colIdx) => {
|
|
121
|
+
const group = columns.get(lv);
|
|
122
|
+
const x = colX[colIdx];
|
|
123
|
+
// Sort within column by average parent Y-centre (minimises edge crossings)
|
|
124
|
+
if (colIdx > 0) {
|
|
125
|
+
group.sort((a, b) => {
|
|
126
|
+
const midY = (id) => {
|
|
127
|
+
const ps = parentMap.get(id) || [];
|
|
128
|
+
if (!ps.length)
|
|
129
|
+
return 0;
|
|
130
|
+
return ps.reduce((s, p) => {
|
|
131
|
+
const pp = pos.get(p);
|
|
132
|
+
return s + (pp ? pp.y + nh(nodeById.get(p)) / 2 : 0);
|
|
133
|
+
}, 0) / ps.length;
|
|
134
|
+
};
|
|
135
|
+
return midY(a) - midY(b);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
// Total column height = sum of actual node heights + gaps between them
|
|
139
|
+
const heights = group.map((id) => nh(nodeById.get(id)));
|
|
140
|
+
const totalHeight = heights.reduce((s, h) => s + h, 0)
|
|
141
|
+
+ (group.length - 1) * verticalSpacing;
|
|
142
|
+
// Centre point: Y=0 for first column, parent mid-Y centroid for the rest
|
|
143
|
+
let colCenterY = 0;
|
|
144
|
+
if (colIdx > 0) {
|
|
145
|
+
const pys = [];
|
|
146
|
+
group.forEach((id) => {
|
|
147
|
+
;
|
|
148
|
+
(parentMap.get(id) || []).forEach((p) => {
|
|
149
|
+
const pp = pos.get(p);
|
|
150
|
+
if (pp)
|
|
151
|
+
pys.push(pp.y + nh(nodeById.get(p)) / 2);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
if (pys.length > 0)
|
|
155
|
+
colCenterY = pys.reduce((s, y) => s + y, 0) / pys.length;
|
|
156
|
+
}
|
|
157
|
+
// Place nodes sequentially from the top of the column, never with a fixed step —
|
|
158
|
+
// each node starts immediately after the actual bottom of the previous one.
|
|
159
|
+
let y = colCenterY - totalHeight / 2;
|
|
160
|
+
group.forEach((id, i) => {
|
|
161
|
+
pos.set(id, { x, y });
|
|
162
|
+
y += heights[i] + verticalSpacing;
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
// ── 6. Shift to match the canvas top-left bounding box ───────────────────
|
|
166
|
+
const originX = Math.min(...nodes.map((n) => { var _a, _b; return (_b = (_a = n.position) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : 0; }));
|
|
167
|
+
const originY = Math.min(...nodes.map((n) => { var _a, _b; return (_b = (_a = n.position) === null || _a === void 0 ? void 0 : _a.y) !== null && _b !== void 0 ? _b : 0; }));
|
|
168
|
+
const minPX = Math.min(...Array.from(pos.values()).map(p => p.x));
|
|
169
|
+
const minPY = Math.min(...Array.from(pos.values()).map(p => p.y));
|
|
170
|
+
return nodes.map((n) => {
|
|
171
|
+
const p = pos.get(n.id);
|
|
172
|
+
return p
|
|
173
|
+
? { ...n, position: { x: p.x + (originX - minPX), y: p.y + (originY - minPY) } }
|
|
174
|
+
: n;
|
|
175
|
+
});
|
|
176
|
+
}
|
|
43
177
|
// Debounce utility
|
|
44
178
|
function useDebounce(callback, delay) {
|
|
45
179
|
const timeoutRef = useRef(null);
|
|
@@ -89,15 +223,21 @@ function useFlowHistory() {
|
|
|
89
223
|
return { addToHistory, undo, redo, historyIndex, historySize: history.length };
|
|
90
224
|
}
|
|
91
225
|
// Custom hook for auto-save functionality
|
|
92
|
-
function useAutoSave(rfInstance, identifier, api_key, nodes, edges, addToHistory) {
|
|
226
|
+
function useAutoSave(rfInstance, identifier, api_key, nodes, edges, addToHistory, isDraggingRef, isConnectingRef) {
|
|
93
227
|
const [saving, setSaving] = useState(false);
|
|
94
228
|
const lastSavedStateRef = useRef('');
|
|
95
229
|
const performSave = useCallback(async () => {
|
|
96
230
|
if (!rfInstance || !identifier)
|
|
97
231
|
return;
|
|
232
|
+
const flow = rfInstance.toObject();
|
|
233
|
+
// CRITICAL: Never save empty flows unless it's intentional
|
|
234
|
+
// Prevent saving if both nodes and edges are empty (likely a race condition)
|
|
235
|
+
if (!flow.nodes || !flow.edges || (flow.nodes.length === 0 && flow.edges.length === 0)) {
|
|
236
|
+
console.warn('Prevented saving empty flow - possible race condition');
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
98
239
|
setSaving(true);
|
|
99
240
|
try {
|
|
100
|
-
const flow = rfInstance.toObject();
|
|
101
241
|
const response = await fetch(`${flow_constants.BACKEND_ENDPOINT}/projects/${identifier}`, {
|
|
102
242
|
method: 'PATCH',
|
|
103
243
|
headers: {
|
|
@@ -121,6 +261,14 @@ function useAutoSave(rfInstance, identifier, api_key, nodes, edges, addToHistory
|
|
|
121
261
|
const saveWithHistory = useCallback(() => {
|
|
122
262
|
if (!rfInstance)
|
|
123
263
|
return;
|
|
264
|
+
// Skip adding to history during drag and connection operations
|
|
265
|
+
if (isDraggingRef.current || isConnectingRef.current)
|
|
266
|
+
return;
|
|
267
|
+
// CRITICAL: Don't save if nodes/edges are undefined or both empty
|
|
268
|
+
if (!nodes || !edges || (nodes.length === 0 && edges.length === 0)) {
|
|
269
|
+
console.warn('Skipping save - empty or undefined state');
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
124
272
|
const currentState = {
|
|
125
273
|
nodes: nodes === null || nodes === void 0 ? void 0 : nodes.map(n => ({ ...n })),
|
|
126
274
|
edges: edges === null || edges === void 0 ? void 0 : edges.map(e => ({ ...e })),
|
|
@@ -160,67 +308,81 @@ function useContextMenu() {
|
|
|
160
308
|
};
|
|
161
309
|
}
|
|
162
310
|
export default function StudioPane({ api_key, projectsRefetch, identifier, providers, provider, theme }) {
|
|
311
|
+
var _a;
|
|
163
312
|
const { stateType } = useConfigStore();
|
|
313
|
+
const stateTypeRef = useRef(stateType);
|
|
314
|
+
useEffect(() => { stateTypeRef.current = stateType; }, [stateType]);
|
|
315
|
+
const [getIdentifier, setIdentifier] = useState(identifier);
|
|
316
|
+
useEffect(() => {
|
|
317
|
+
setIdentifier(identifier);
|
|
318
|
+
// Reset the loaded flag when switching projects
|
|
319
|
+
hasLoadedInitialData.current = false;
|
|
320
|
+
}, [identifier]);
|
|
164
321
|
// Optimized queries with better caching
|
|
165
322
|
const { data: project, status: projectStatus, refetch: projectRefetch } = useQuery({
|
|
166
|
-
queryKey: [`project_${
|
|
323
|
+
queryKey: [`project_${getIdentifier}`],
|
|
167
324
|
queryFn: async () => {
|
|
168
|
-
const res = await fetch(`${flow_constants.BACKEND_ENDPOINT}/projects/${
|
|
325
|
+
const res = await fetch(`${flow_constants.BACKEND_ENDPOINT}/projects/${getIdentifier}`, {
|
|
169
326
|
headers: { "X-API-KEY": `${api_key}` }
|
|
170
327
|
});
|
|
171
328
|
return res === null || res === void 0 ? void 0 : res.json();
|
|
172
329
|
},
|
|
173
|
-
enabled: !!
|
|
330
|
+
enabled: !!getIdentifier,
|
|
174
331
|
staleTime: QUERY_STALE_TIME,
|
|
175
|
-
gcTime: QUERY_CACHE_TIME
|
|
332
|
+
gcTime: QUERY_CACHE_TIME,
|
|
333
|
+
placeholderData: (previousData) => previousData
|
|
176
334
|
});
|
|
177
335
|
const { data: functions, refetch: functionsRefetch } = useQuery({
|
|
178
|
-
queryKey: [`project_${
|
|
336
|
+
queryKey: [`project_${getIdentifier}_api_calls`],
|
|
179
337
|
queryFn: async () => {
|
|
180
|
-
const res = await fetch(`${flow_constants.BACKEND_ENDPOINT}/
|
|
338
|
+
const res = await fetch(`${flow_constants.BACKEND_ENDPOINT}/api-calls?project=${getIdentifier}`, {
|
|
181
339
|
headers: { "X-API-KEY": `${api_key}` }
|
|
182
340
|
});
|
|
183
341
|
return res === null || res === void 0 ? void 0 : res.json();
|
|
184
342
|
},
|
|
185
|
-
enabled: !!
|
|
343
|
+
enabled: !!getIdentifier,
|
|
186
344
|
staleTime: QUERY_STALE_TIME,
|
|
187
|
-
gcTime: QUERY_CACHE_TIME
|
|
345
|
+
gcTime: QUERY_CACHE_TIME,
|
|
346
|
+
placeholderData: (previousData) => previousData
|
|
188
347
|
});
|
|
189
348
|
const { data: triggers, refetch: triggersRefetch } = useQuery({
|
|
190
|
-
queryKey: [`project_${
|
|
349
|
+
queryKey: [`project_${getIdentifier}_triggers`],
|
|
191
350
|
queryFn: async () => {
|
|
192
|
-
const res = await fetch(`${flow_constants.BACKEND_ENDPOINT}/triggers?project=${
|
|
351
|
+
const res = await fetch(`${flow_constants.BACKEND_ENDPOINT}/triggers?project=${getIdentifier}`, {
|
|
193
352
|
headers: { "X-API-KEY": `${api_key}` }
|
|
194
353
|
});
|
|
195
354
|
return res === null || res === void 0 ? void 0 : res.json();
|
|
196
355
|
},
|
|
197
|
-
enabled: !!
|
|
356
|
+
enabled: !!getIdentifier,
|
|
198
357
|
staleTime: QUERY_STALE_TIME,
|
|
199
|
-
gcTime: QUERY_CACHE_TIME
|
|
358
|
+
gcTime: QUERY_CACHE_TIME,
|
|
359
|
+
placeholderData: (previousData) => previousData
|
|
200
360
|
});
|
|
201
361
|
const { data: envs, refetch: envsRefetch } = useQuery({
|
|
202
|
-
queryKey: [`project_${
|
|
362
|
+
queryKey: [`project_${getIdentifier}_secrets`],
|
|
203
363
|
queryFn: async () => {
|
|
204
|
-
const res = await fetch(`${flow_constants.BACKEND_ENDPOINT}/
|
|
364
|
+
const res = await fetch(`${flow_constants.BACKEND_ENDPOINT}/secrets?project=${getIdentifier}`, {
|
|
205
365
|
headers: { "X-API-KEY": `${api_key}` }
|
|
206
366
|
});
|
|
207
367
|
return res === null || res === void 0 ? void 0 : res.json();
|
|
208
368
|
},
|
|
209
|
-
enabled: !!
|
|
369
|
+
enabled: !!getIdentifier,
|
|
210
370
|
staleTime: QUERY_STALE_TIME,
|
|
211
|
-
gcTime: QUERY_CACHE_TIME
|
|
371
|
+
gcTime: QUERY_CACHE_TIME,
|
|
372
|
+
placeholderData: (previousData) => previousData
|
|
212
373
|
});
|
|
213
374
|
const { data: sessions, status: sessionsStatus, refetch: sessionsRefetch } = useQuery({
|
|
214
|
-
queryKey: [`project_${
|
|
375
|
+
queryKey: [`project_${getIdentifier}_sessions`],
|
|
215
376
|
queryFn: async () => {
|
|
216
|
-
const res = await fetch(`${flow_constants.BACKEND_ENDPOINT}/sessions?project=${
|
|
377
|
+
const res = await fetch(`${flow_constants.BACKEND_ENDPOINT}/sessions?project=${getIdentifier}`, {
|
|
217
378
|
headers: { "X-API-KEY": `${api_key}` }
|
|
218
379
|
});
|
|
219
380
|
return res === null || res === void 0 ? void 0 : res.json();
|
|
220
381
|
},
|
|
221
|
-
enabled: !!
|
|
382
|
+
enabled: !!getIdentifier,
|
|
222
383
|
staleTime: QUERY_STALE_TIME,
|
|
223
|
-
gcTime: QUERY_CACHE_TIME
|
|
384
|
+
gcTime: QUERY_CACHE_TIME,
|
|
385
|
+
placeholderData: (previousData) => previousData
|
|
224
386
|
});
|
|
225
387
|
// Optimized session lookup - compute once, use many times
|
|
226
388
|
const sessionsByNodeId = useMemo(() => {
|
|
@@ -235,57 +397,99 @@ export default function StudioPane({ api_key, projectsRefetch, identifier, provi
|
|
|
235
397
|
}, {});
|
|
236
398
|
}, [sessions === null || sessions === void 0 ? void 0 : sessions.results]);
|
|
237
399
|
////////////////// Nodes Management (React Flow) /////////////////////////////
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
//
|
|
400
|
+
const [nodes, setNodes, onNodesChange] = useNodesState((project === null || project === void 0 ? void 0 : project.nodes) || []);
|
|
401
|
+
const [edges, setEdges, onEdgesChange] = useEdgesState((project === null || project === void 0 ? void 0 : project.edges) || []);
|
|
402
|
+
// Refs hold latest data so nodeTypes can be stable (no deps) while nodes
|
|
403
|
+
// still read current functions/sessions/envs at render time.
|
|
404
|
+
const functionsRef = useRef(undefined);
|
|
405
|
+
const sessionsByNodeIdRef = useRef({});
|
|
406
|
+
const envsRef = useRef([]);
|
|
407
|
+
functionsRef.current = functions === null || functions === void 0 ? void 0 : functions.results;
|
|
408
|
+
sessionsByNodeIdRef.current = sessionsByNodeId;
|
|
409
|
+
envsRef.current = (_a = envs === null || envs === void 0 ? void 0 : envs.results) !== null && _a !== void 0 ? _a : [];
|
|
410
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
242
411
|
const nodeTypes = useMemo(() => ({
|
|
243
412
|
gNode: (props) => (_jsx(GNode, { ...props, data: {
|
|
244
413
|
...props.data,
|
|
245
|
-
functions:
|
|
246
|
-
sessions:
|
|
414
|
+
functions: functionsRef.current,
|
|
415
|
+
sessions: sessionsByNodeIdRef.current[props.id] || [],
|
|
416
|
+
secrets: envsRef.current,
|
|
247
417
|
} })),
|
|
248
|
-
|
|
249
|
-
...props.data,
|
|
250
|
-
functions: functions === null || functions === void 0 ? void 0 : functions.results,
|
|
251
|
-
sessions: sessionsByNodeId[props.id] || []
|
|
252
|
-
} }))
|
|
253
|
-
}), [functions === null || functions === void 0 ? void 0 : functions.results, sessionsByNodeId]);
|
|
418
|
+
}), []);
|
|
254
419
|
const edgeTypes = useMemo(() => ({
|
|
255
420
|
default: memo((props) => (_jsx(CustomSmoothstepEdge, { ...props, deletable: true })))
|
|
256
421
|
}), []);
|
|
257
|
-
const [nodes, setNodes, onNodesChange] = useNodesState((project === null || project === void 0 ? void 0 : project.nodes) || []);
|
|
258
|
-
const [edges, setEdges, onEdgesChange] = useEdgesState((project === null || project === void 0 ? void 0 : project.edges) || []);
|
|
259
422
|
const [rfInstance, setRfInstance] = useState(null);
|
|
260
423
|
const { setViewport, screenToFlowPosition, getNodes, getEdges } = useReactFlow();
|
|
261
424
|
const isReconnectingRef = useRef(false);
|
|
425
|
+
const hasLoadedInitialData = useRef(false);
|
|
426
|
+
const isDraggingRef = useRef(false);
|
|
427
|
+
const isConnectingRef = useRef(false);
|
|
262
428
|
// Custom hooks
|
|
263
429
|
const { addToHistory, undo, redo, historyIndex, historySize } = useFlowHistory();
|
|
264
|
-
const { performSave, saveWithHistory, saving } = useAutoSave(rfInstance, identifier, api_key, nodes, edges, addToHistory);
|
|
430
|
+
const { performSave, saveWithHistory, saving } = useAutoSave(rfInstance, identifier, api_key, nodes, edges, addToHistory, isDraggingRef, isConnectingRef);
|
|
265
431
|
const { showContextMenu, contextMenuPosition, handleContextMenu, setShowContextMenu } = useContextMenu();
|
|
266
432
|
// Key Presses
|
|
267
|
-
const cmdAndSPressed = useKeyPress(['Meta+s', 'Strg+s']);
|
|
268
|
-
const cmdAndZPressed = useKeyPress(['Meta+z', 'Strg+z']);
|
|
269
|
-
const cmdAndYPressed = useKeyPress(['Meta+y', 'Strg+y']);
|
|
433
|
+
const cmdAndSPressed = useKeyPress(['Meta+s', 'Strg+s', 'Ctrl+s']);
|
|
434
|
+
const cmdAndZPressed = useKeyPress(['Meta+z', 'Strg+z', 'Ctrl+z']);
|
|
435
|
+
const cmdAndYPressed = useKeyPress(['Meta+y', 'Strg+y', 'Ctrl+y']);
|
|
270
436
|
////////////// onMount and Initial Load //////////////
|
|
271
437
|
useEffect(() => {
|
|
272
438
|
// Component initialization logic can go here
|
|
273
439
|
}, []);
|
|
274
440
|
useEffect(() => {
|
|
275
441
|
var _a, _b, _c;
|
|
442
|
+
// Skip resetting canvas when in live mode — live mode manages its own source
|
|
443
|
+
if (stateTypeRef.current === 'live')
|
|
444
|
+
return;
|
|
276
445
|
if (project === null || project === void 0 ? void 0 : project.flow_draft) {
|
|
277
446
|
const { x = 0, y = 0, zoom = 1 } = ((_a = project === null || project === void 0 ? void 0 : project.flow_draft) === null || _a === void 0 ? void 0 : _a.viewport) || {};
|
|
278
447
|
setNodes(((_b = project === null || project === void 0 ? void 0 : project.flow_draft) === null || _b === void 0 ? void 0 : _b.nodes) || []);
|
|
279
448
|
setEdges(((_c = project === null || project === void 0 ? void 0 : project.flow_draft) === null || _c === void 0 ? void 0 : _c.edges) || []);
|
|
280
449
|
setViewport({ x, y, zoom });
|
|
450
|
+
setTimeout(() => {
|
|
451
|
+
hasLoadedInitialData.current = true;
|
|
452
|
+
}, 500);
|
|
281
453
|
}
|
|
282
454
|
}, [project, setNodes, setEdges, setViewport]);
|
|
455
|
+
const prevStateTypeRef = useRef(stateType);
|
|
456
|
+
useEffect(() => {
|
|
457
|
+
var _a, _b, _c, _d, _e, _f;
|
|
458
|
+
const didSwitch = prevStateTypeRef.current !== stateType;
|
|
459
|
+
prevStateTypeRef.current = stateType;
|
|
460
|
+
if (stateType === 'live') {
|
|
461
|
+
hasLoadedInitialData.current = false;
|
|
462
|
+
// Use published flow if it has nodes; fall back to draft if not yet published
|
|
463
|
+
const flowSource = (((_b = (_a = project === null || project === void 0 ? void 0 : project.flow) === null || _a === void 0 ? void 0 : _a.nodes) === null || _b === void 0 ? void 0 : _b.length) > 0) ? project.flow : project === null || project === void 0 ? void 0 : project.flow_draft;
|
|
464
|
+
if (!((_c = flowSource === null || flowSource === void 0 ? void 0 : flowSource.nodes) === null || _c === void 0 ? void 0 : _c.length))
|
|
465
|
+
return;
|
|
466
|
+
const { x = 0, y = 0, zoom = 1 } = (flowSource === null || flowSource === void 0 ? void 0 : flowSource.viewport) || {};
|
|
467
|
+
setNodes((flowSource === null || flowSource === void 0 ? void 0 : flowSource.nodes) || []);
|
|
468
|
+
setEdges((flowSource === null || flowSource === void 0 ? void 0 : flowSource.edges) || []);
|
|
469
|
+
setViewport({ x, y, zoom });
|
|
470
|
+
}
|
|
471
|
+
else if (didSwitch && stateType === 'design' && (project === null || project === void 0 ? void 0 : project.flow_draft)) {
|
|
472
|
+
// Only reload draft when actually switching back — not on every project refetch
|
|
473
|
+
hasLoadedInitialData.current = false;
|
|
474
|
+
const { x = 0, y = 0, zoom = 1 } = ((_d = project === null || project === void 0 ? void 0 : project.flow_draft) === null || _d === void 0 ? void 0 : _d.viewport) || {};
|
|
475
|
+
setNodes(((_e = project === null || project === void 0 ? void 0 : project.flow_draft) === null || _e === void 0 ? void 0 : _e.nodes) || []);
|
|
476
|
+
setEdges(((_f = project === null || project === void 0 ? void 0 : project.flow_draft) === null || _f === void 0 ? void 0 : _f.edges) || []);
|
|
477
|
+
setViewport({ x, y, zoom });
|
|
478
|
+
setTimeout(() => { hasLoadedInitialData.current = true; }, 500);
|
|
479
|
+
}
|
|
480
|
+
}, [stateType, project]);
|
|
283
481
|
useEffect(() => {
|
|
284
482
|
setEdges((eds) => eds.map((edge) => ({
|
|
285
483
|
...edge,
|
|
286
|
-
animated: stateType === '
|
|
484
|
+
animated: stateType === 'live'
|
|
287
485
|
})));
|
|
288
486
|
}, [stateType, setEdges]);
|
|
487
|
+
useEffect(() => {
|
|
488
|
+
if (stateType !== 'live')
|
|
489
|
+
return;
|
|
490
|
+
const interval = setInterval(() => { sessionsRefetch(); }, 15000);
|
|
491
|
+
return () => clearInterval(interval);
|
|
492
|
+
}, [stateType, sessionsRefetch]);
|
|
289
493
|
//////////////////////////// Connections /////////////////////////////////
|
|
290
494
|
const onConnect = useCallback((connection) => {
|
|
291
495
|
setEdges((eds) => {
|
|
@@ -299,9 +503,14 @@ export default function StudioPane({ api_key, projectsRefetch, identifier, provi
|
|
|
299
503
|
});
|
|
300
504
|
}, [setEdges]);
|
|
301
505
|
const onConnectStart = useCallback(() => {
|
|
302
|
-
|
|
506
|
+
isConnectingRef.current = true;
|
|
303
507
|
}, []);
|
|
304
508
|
const onConnectEnd = useCallback((event, connectionState) => {
|
|
509
|
+
isConnectingRef.current = false;
|
|
510
|
+
// Trigger saveWithHistory after connection ends to capture final state
|
|
511
|
+
setTimeout(() => {
|
|
512
|
+
saveWithHistory();
|
|
513
|
+
}, 0);
|
|
305
514
|
if (!connectionState.isValid && !connectionState.toNode) {
|
|
306
515
|
if (!connectionState.toNode && !isReconnectingRef.current) {
|
|
307
516
|
const { clientX, clientY } = 'changedTouches' in event ? event.changedTouches[0] : event;
|
|
@@ -393,6 +602,10 @@ export default function StudioPane({ api_key, projectsRefetch, identifier, provi
|
|
|
393
602
|
setNodes(prevState.nodes);
|
|
394
603
|
setEdges(prevState.edges);
|
|
395
604
|
setViewport(prevState.viewport);
|
|
605
|
+
toast.success("Undo successful");
|
|
606
|
+
}
|
|
607
|
+
else {
|
|
608
|
+
toast.info("Nothing to undo");
|
|
396
609
|
}
|
|
397
610
|
}, [undo, setNodes, setEdges, setViewport]);
|
|
398
611
|
const handleRedo = useCallback(() => {
|
|
@@ -401,6 +614,10 @@ export default function StudioPane({ api_key, projectsRefetch, identifier, provi
|
|
|
401
614
|
setNodes(nextState.nodes);
|
|
402
615
|
setEdges(nextState.edges);
|
|
403
616
|
setViewport(nextState.viewport);
|
|
617
|
+
toast.success("Redo successful");
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
toast.info("Nothing to redo");
|
|
404
621
|
}
|
|
405
622
|
}, [redo, setNodes, setEdges, setViewport]);
|
|
406
623
|
useEffect(() => {
|
|
@@ -411,6 +628,19 @@ export default function StudioPane({ api_key, projectsRefetch, identifier, provi
|
|
|
411
628
|
handleRedo();
|
|
412
629
|
}
|
|
413
630
|
}, [cmdAndZPressed, cmdAndYPressed, handleUndo, handleRedo]);
|
|
631
|
+
////////////////// Auto Arrange Nodes /////////////////////////////
|
|
632
|
+
const handleAutoArrange = useCallback(() => {
|
|
633
|
+
// Use rfInstance.getNodes() so each node carries its actual measured dimensions
|
|
634
|
+
const liveNodes = rfInstance ? rfInstance.getNodes() : nodes;
|
|
635
|
+
const arrangedNodes = autoArrangeNodes(liveNodes, edges);
|
|
636
|
+
setNodes(arrangedNodes);
|
|
637
|
+
addToHistory({ nodes: arrangedNodes, edges, viewport: rfInstance === null || rfInstance === void 0 ? void 0 : rfInstance.getViewport() });
|
|
638
|
+
performSave();
|
|
639
|
+
// Wait for React to repaint the new positions before fitting the view
|
|
640
|
+
setTimeout(() => {
|
|
641
|
+
rfInstance === null || rfInstance === void 0 ? void 0 : rfInstance.fitView({ padding: 0.1, duration: 400 });
|
|
642
|
+
}, 50);
|
|
643
|
+
}, [nodes, edges, setNodes, addToHistory, rfInstance, performSave]);
|
|
414
644
|
////////////////// For Context Menu /////////////////////////////
|
|
415
645
|
const createNode = useCallback((type) => {
|
|
416
646
|
if ((contextMenuPosition === null || contextMenuPosition === void 0 ? void 0 : contextMenuPosition.x) != null && (contextMenuPosition === null || contextMenuPosition === void 0 ? void 0 : contextMenuPosition.y) != null) {
|
|
@@ -423,7 +653,8 @@ export default function StudioPane({ api_key, projectsRefetch, identifier, provi
|
|
|
423
653
|
while (existingLabels.has(newLabel)) {
|
|
424
654
|
newLabel = `${type}_label_${counter++}`;
|
|
425
655
|
}
|
|
426
|
-
const template = type === 'function' ? NODE_TEMPLATES.function : NODE_TEMPLATES.default;
|
|
656
|
+
// const template = type === 'function' ? NODE_TEMPLATES.function : type === 'gotonode' ? NODE_TEMPLATES.gotonode : NODE_TEMPLATES.default;
|
|
657
|
+
const template = NODE_TEMPLATES.default;
|
|
427
658
|
return [
|
|
428
659
|
...prevNodes,
|
|
429
660
|
{
|
|
@@ -433,9 +664,21 @@ export default function StudioPane({ api_key, projectsRefetch, identifier, provi
|
|
|
433
664
|
data: {
|
|
434
665
|
...template.data,
|
|
435
666
|
label: newLabel,
|
|
436
|
-
|
|
667
|
+
type,
|
|
668
|
+
...(type === 'api' ? {
|
|
669
|
+
api: '',
|
|
670
|
+
response: {
|
|
671
|
+
source: 'api_call',
|
|
672
|
+
inputs: [{ id: 1 }]
|
|
673
|
+
}
|
|
674
|
+
} : type === 'gotonode' ? {
|
|
675
|
+
node: '',
|
|
676
|
+
response: {
|
|
677
|
+
source: 'gotonode',
|
|
678
|
+
inputs: [{ id: 1 }]
|
|
679
|
+
}
|
|
680
|
+
} : {
|
|
437
681
|
message: '',
|
|
438
|
-
type,
|
|
439
682
|
response: {
|
|
440
683
|
validation: 'alpha-numeric',
|
|
441
684
|
source: 'manual',
|
|
@@ -450,10 +693,30 @@ export default function StudioPane({ api_key, projectsRefetch, identifier, provi
|
|
|
450
693
|
}, [contextMenuPosition, setNodes]);
|
|
451
694
|
//////////////////// Auto Save //////////////////
|
|
452
695
|
useEffect(() => {
|
|
453
|
-
|
|
696
|
+
// CRITICAL: Only autosave if we have valid data and identifier matches
|
|
697
|
+
// This prevents saving empty state during tab switches or initial load
|
|
698
|
+
if (stateType !== 'live' &&
|
|
699
|
+
hasLoadedInitialData.current &&
|
|
700
|
+
rfInstance &&
|
|
701
|
+
getIdentifier &&
|
|
702
|
+
identifier === getIdentifier &&
|
|
703
|
+
nodes &&
|
|
704
|
+
edges &&
|
|
705
|
+
(nodes.length > 0 || edges.length > 0)) {
|
|
454
706
|
saveWithHistory();
|
|
455
707
|
}
|
|
456
|
-
}, [nodes, edges, rfInstance, identifier, saveWithHistory]);
|
|
708
|
+
}, [nodes, edges, rfInstance, getIdentifier, identifier, saveWithHistory, stateType]);
|
|
709
|
+
///////////////// Drag Event Handlers ////////////////
|
|
710
|
+
const onNodeDragStart = useCallback(() => {
|
|
711
|
+
isDraggingRef.current = true;
|
|
712
|
+
}, []);
|
|
713
|
+
const onNodeDragStop = useCallback(() => {
|
|
714
|
+
isDraggingRef.current = false;
|
|
715
|
+
// Trigger saveWithHistory after drag ends to capture final state
|
|
716
|
+
setTimeout(() => {
|
|
717
|
+
saveWithHistory();
|
|
718
|
+
}, 0);
|
|
719
|
+
}, [saveWithHistory]);
|
|
457
720
|
///////////////// Delete Key Code ////////////////
|
|
458
721
|
const onSelectionChange = useCallback(({ nodes, edges }) => {
|
|
459
722
|
// console.log('Selected nodes:', nodes)
|
|
@@ -469,6 +732,6 @@ export default function StudioPane({ api_key, projectsRefetch, identifier, provi
|
|
|
469
732
|
window.addEventListener('keydown', handleKeyDown);
|
|
470
733
|
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
471
734
|
}, [setNodes, setEdges]);
|
|
472
|
-
return (_jsxs(
|
|
735
|
+
return (_jsxs("div", { className: 'absolute top-0 right-0 bottom-0 left-0', children: [_jsxs(ReactFlow, { nodes: nodes, edges: edges, onNodesChange: onNodesChange, onEdgesChange: onEdgesChange, onConnect: onConnect, nodeTypes: nodeTypes, edgeTypes: edgeTypes, onNodesDelete: onNodesDelete, onEdgesDelete: onEdgesDelete, onSelectionChange: onSelectionChange, onConnectEnd: onConnectEnd, onConnectStart: onConnectStart, onReconnect: onReconnect, onReconnectStart: onReconnectStart, onNodeDragStart: onNodeDragStart, onNodeDragStop: onNodeDragStop, onReconnectEnd: onReconnectEnd, onInit: setRfInstance, snapToGrid: true, fitView: true, minZoom: 0.1, maxZoom: 3, colorMode: theme, onPaneContextMenu: handleContextMenu, deleteKeyCode: null, attributionPosition: "bottom-right", children: [_jsx(Background, { gap: 12, size: 1 }), _jsx(Panel, { position: "top-center", children: _jsx(TopCenterPanel, { projectId: getIdentifier }) }), _jsx(Panel, { position: "top-left", children: _jsx(TopLeftPanel, { api_key: api_key, projectId: getIdentifier, createNode: createNode, onSave: onSave, saving: saving, rfInstance: rfInstance, redo: handleRedo, undo: handleUndo, historyIndex: historyIndex, historySize: historySize, autoArrange: handleAutoArrange }) }), _jsx(Panel, { position: "bottom-left", children: _jsx(BottomLeftPanel, { api_key: api_key, projectId: getIdentifier, createNode: createNode, onSave: onSave, saving: saving, rfInstance: rfInstance, redo: handleRedo, undo: handleUndo, historyIndex: historyIndex, autoArrange: handleAutoArrange }) }), _jsx(Panel, { position: "top-right", children: _jsx(TopRightPanel, { api_key: api_key, projectId: getIdentifier, createNode: createNode, onSave: onSave, saving: saving, rfInstance: rfInstance }) })] }), _jsx(AppAnalytics, { api_key: api_key, project: project, sessions: sessions, sessionsStatus: sessionsStatus, refetch: sessionsRefetch }), _jsx(AppSettings, { api_key: api_key, project: project, projectRefetch: projectRefetch, projectsRefetch: projectsRefetch, providers: providers, provider: provider, triggers: triggers, triggersRefetch: triggersRefetch, functions: functions, functionsRefetch: functionsRefetch, envs: envs, envsRefetch: envsRefetch }), _jsx(ContextMenu, { api_key: api_key, open: showContextMenu, setOpen: setShowContextMenu, createNode: createNode, menuPosition: contextMenuPosition })] }));
|
|
473
736
|
}
|
|
474
737
|
//# sourceMappingURL=studio_pane.js.map
|