@burdenoff/fluidgrids-fe-sdk 2026.616.1 → 2026.616.2
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/dist/{TemplateConfigurationModal-UJAGRE7X.js → TemplateConfigurationModal-FPQR7W4M.js} +3 -3
- package/dist/{TemplateConfigurationModal-UJAGRE7X.js.map → TemplateConfigurationModal-FPQR7W4M.js.map} +1 -1
- package/dist/{WorkflowBuilder-TIT4KURD.js → WorkflowBuilder-BIAKKNKM.js} +6 -6
- package/dist/{WorkflowBuilder-TIT4KURD.js.map → WorkflowBuilder-BIAKKNKM.js.map} +1 -1
- package/dist/WorkflowsList-J33J7EIF.js +8 -0
- package/dist/{WorkflowsList-CLI32VRE.js.map → WorkflowsList-J33J7EIF.js.map} +1 -1
- package/dist/{chunk-NDJSUC4W.js → chunk-7VEOUEIN.js} +21 -21
- package/dist/chunk-7VEOUEIN.js.map +1 -0
- package/dist/{chunk-6FP5I5EG.js → chunk-C5VIFUNU.js} +3 -3
- package/dist/{chunk-6FP5I5EG.js.map → chunk-C5VIFUNU.js.map} +1 -1
- package/dist/{chunk-GSS5PHRL.js → chunk-M2KBI2FX.js} +3 -3
- package/dist/{chunk-GSS5PHRL.js.map → chunk-M2KBI2FX.js.map} +1 -1
- package/dist/{chunk-XVHQN2UK.js → chunk-TYOU6RYA.js} +781 -866
- package/dist/chunk-TYOU6RYA.js.map +1 -0
- package/dist/{chunk-CGKBAJMM.js → chunk-Z2ZEVYDE.js} +2 -2
- package/dist/chunk-Z2ZEVYDE.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +12 -12
- package/dist/index.js.map +1 -1
- package/dist/useImportWorkflowTemplate-P62I2ADG.js +11 -0
- package/dist/{useImportWorkflowTemplate-RCPS4OTA.js.map → useImportWorkflowTemplate-P62I2ADG.js.map} +1 -1
- package/package.json +1 -1
- package/dist/WorkflowsList-CLI32VRE.js +0 -8
- package/dist/chunk-CGKBAJMM.js.map +0 -1
- package/dist/chunk-NDJSUC4W.js.map +0 -1
- package/dist/chunk-XVHQN2UK.js.map +0 -1
- package/dist/useImportWorkflowTemplate-RCPS4OTA.js +0 -11
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { registerWorkflowNodeTypes, ensureNodeConfigsLoaded, onNodeTypesUpdate, NODE_TYPES, getNodeMetadata, useNodeExecution, AVAILABLE_NODES, createNodeWithDefaultData, NODES_METADATA,
|
|
2
|
-
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, Input as Input$1 } from './chunk-
|
|
1
|
+
import { registerWorkflowNodeTypes, ensureNodeConfigsLoaded, onNodeTypesUpdate, NODE_TYPES, getNodeMetadata, useNodeExecution, AVAILABLE_NODES, createNodeWithDefaultData, NODES_METADATA, isNodeConfigsInitialized, HeaderWithIcon, useInstalledNodes, useInstallNode, useRefreshAvailableNodes, getNodeDetail, NODES, NodePropertyPanel, NODE_CONFIGS, ConnectionSelector } from './chunk-C5VIFUNU.js';
|
|
2
|
+
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, Input as Input$1 } from './chunk-7VEOUEIN.js';
|
|
3
3
|
import { cn, Badge as Badge$1, Button } from './chunk-Z54K22LP.js';
|
|
4
|
-
import { useFlowStore } from './chunk-
|
|
4
|
+
import { useFlowStore } from './chunk-Z2ZEVYDE.js';
|
|
5
5
|
import { useLazyWorkflowDefinition, useCreateWorkflow, useWorkflowVersions, useRestoreWorkflowVersion, useActivateWorkflow, useDeactivateWorkflow } from './chunk-4FFPGQD3.js';
|
|
6
6
|
import { NodeSchemaIntrospectionDocument, UpdateWorkflowDefinitionDocument, CreateWorkflowDefinitionDocument, CreateWorkflowVersionDocument, NodeUsageStatusDocument, RemoveNodeFromWorkflowsDocument } from './chunk-FGYVIXQ7.js';
|
|
7
7
|
import { BrowseWorkflowTemplatesDocument, BrowseWorkflowNodesDocument, UninstallWorkflowNodeDocument, CreateStoreOrderDocument } from './chunk-LUGJJ7LL.js';
|
|
@@ -15,15 +15,15 @@ import { useShallow, shallow } from 'zustand/shallow';
|
|
|
15
15
|
import * as React3 from 'react';
|
|
16
16
|
import React3__default, { forwardRef, lazy, memo, createContext, useContext, useMemo, useState, useRef, useEffect, useLayoutEffect, useCallback, Suspense, useDeferredValue } from 'react';
|
|
17
17
|
import { Handle, Position, getBezierPath, MarkerType, ReactFlowProvider, useReactFlow, ReactFlow, Background, useOnSelectionChange, useStore, MiniMap, getSmoothStepPath, EdgeLabelRenderer, getOutgoers, getConnectedEdges, useNodes, useNodesState, useEdgesState, addEdge, Controls, Panel } from '@xyflow/react';
|
|
18
|
-
import { cn as cn$1 } from '@burdenoff/fe-libs/utils';
|
|
19
|
-
import { Icon } from '@iconify/react';
|
|
20
18
|
import { produce } from 'immer';
|
|
19
|
+
import { cn as cn$1 } from '@burdenoff/fe-libs/utils';
|
|
21
20
|
import { Card as Card$1, Badge, CardContent as CardContent$1, Button as Button$1, Input, Sheet, SheetTrigger, SheetContent, SheetHeader, SheetTitle, Popover, PopoverTrigger, PopoverContent, Toaster, Tabs, TabsList, TabsTrigger, TabsContent, CardHeader as CardHeader$1, CardTitle as CardTitle$1, CardDescription as CardDescription$1, ScrollArea, TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, Label, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuItem, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Textarea } from '@burdenoff/fe-libs/ui';
|
|
22
21
|
import { isEmpty } from 'radash';
|
|
22
|
+
import { Icon } from '@iconify/react';
|
|
23
23
|
import { gql } from '@apollo/client';
|
|
24
|
-
import { Sparkles, Star, Download, Eye, History, Loader2, RotateCcw, Maximize2, LayoutGrid, Plus, Trash2, GitBranch, Store, AlertCircle, Search, RefreshCw, CheckCircle2, Package, Info, Copy, List, CheckCircle, XCircle, ArrowUpCircle, PlusCircle, ChevronDown, Type, Code, Hash, Braces, Workflow, ChevronRight, Layers, Check, DollarSign, X, AlertTriangle } from 'lucide-react';
|
|
25
24
|
import { useQuery, useMutation } from '@apollo/client/react';
|
|
26
25
|
import { gql as gql$1 } from '@apollo/client/core';
|
|
26
|
+
import { Sparkles, Star, Download, Eye, History, Loader2, RotateCcw, Maximize2, LayoutGrid, Plus, Trash2, GitBranch, AlertCircle, Search, RefreshCw, CheckCircle2, Package, Info, Copy, BadgeCheck, DollarSign, PlusCircle, ChevronDown, Type, Code, Hash, List, Braces, Workflow, ChevronRight, Layers, X, AlertTriangle } from 'lucide-react';
|
|
27
27
|
import { toast } from 'sonner';
|
|
28
28
|
import { animate, easeOut } from 'popmotion';
|
|
29
29
|
import { createPortal } from 'react-dom';
|
|
@@ -36,28 +36,19 @@ import { ErrorBoundary } from '@burdenoff/fe-libs/shared/components';
|
|
|
36
36
|
function ThemeProvider({ children }) {
|
|
37
37
|
return /* @__PURE__ */ jsx(ThemeProvider$1, { children });
|
|
38
38
|
}
|
|
39
|
-
function
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const newNode = createNodeWithDefaultData(type, {
|
|
53
|
-
position: _pos,
|
|
54
|
-
selected: true
|
|
55
|
-
});
|
|
56
|
-
addNodes(newNode);
|
|
57
|
-
return newNode;
|
|
58
|
-
},
|
|
59
|
-
[screenToFlowPosition, getNodes, addNodes, updateNode]
|
|
60
|
-
);
|
|
39
|
+
function useNodeList(nodes) {
|
|
40
|
+
return useMemo(() => {
|
|
41
|
+
return nodes.slice().sort((a, b) => {
|
|
42
|
+
if (a.type === "trigger:api" /* TRIGGER */) return -1;
|
|
43
|
+
if (b.type === "trigger:api" /* TRIGGER */) return 1;
|
|
44
|
+
if (a.type === "end" /* END */) return 1;
|
|
45
|
+
if (b.type === "end" /* END */) return -1;
|
|
46
|
+
return 0;
|
|
47
|
+
}).map((n) => ({
|
|
48
|
+
...n,
|
|
49
|
+
detail: getNodeDetail(n.type)
|
|
50
|
+
}));
|
|
51
|
+
}, [nodes]);
|
|
61
52
|
}
|
|
62
53
|
function SidebarPanelWrapper({
|
|
63
54
|
children,
|
|
@@ -73,244 +64,6 @@ function SidebarPanelWrapper({
|
|
|
73
64
|
}
|
|
74
65
|
);
|
|
75
66
|
}
|
|
76
|
-
|
|
77
|
-
// src/builder/contants/symbols.ts
|
|
78
|
-
var NODE_TYPE_DRAG_DATA_FORMAT = "application/flow-builder.node-type";
|
|
79
|
-
function NodePreviewDraggable({
|
|
80
|
-
icon,
|
|
81
|
-
title,
|
|
82
|
-
description,
|
|
83
|
-
type,
|
|
84
|
-
setActivePanel,
|
|
85
|
-
insertNode
|
|
86
|
-
}) {
|
|
87
|
-
const onDragStart = useCallback((e, type2) => {
|
|
88
|
-
e.dataTransfer.setData(NODE_TYPE_DRAG_DATA_FORMAT, type2);
|
|
89
|
-
e.dataTransfer.effectAllowed = "move";
|
|
90
|
-
}, []);
|
|
91
|
-
const onClick = useCallback(() => {
|
|
92
|
-
insertNode(type);
|
|
93
|
-
setActivePanel("none");
|
|
94
|
-
}, [insertNode, setActivePanel, type]);
|
|
95
|
-
return /* @__PURE__ */ jsxs(
|
|
96
|
-
"div",
|
|
97
|
-
{
|
|
98
|
-
className: "flex cursor-grab select-none gap-2 border border-card-foreground/10 rounded-xl bg-card p-2.5 shadow-sm transition hover:ring-2 hover:ring-primary/50",
|
|
99
|
-
onClick,
|
|
100
|
-
onDragStart: (e) => onDragStart(e, type),
|
|
101
|
-
draggable: true,
|
|
102
|
-
"data-vaul-no-drag": true,
|
|
103
|
-
children: [
|
|
104
|
-
/* @__PURE__ */ jsx("div", { className: "shrink-0", children: /* @__PURE__ */ jsx("div", { className: "size-10 flex items-center justify-center border border-card-foreground/10 rounded-xl bg-card", children: typeof icon === "string" ? /* @__PURE__ */ jsx(Icon, { icon, className: "size-6 text-card-foreground/80" }) : icon }) }),
|
|
105
|
-
/* @__PURE__ */ jsxs("div", { className: "ml-1 flex grow flex-col", children: [
|
|
106
|
-
/* @__PURE__ */ jsx("div", { className: "mt-px text-sm font-medium leading-normal", children: title }),
|
|
107
|
-
/* @__PURE__ */ jsx("div", { className: "line-clamp-3 mt-1 text-xs text-card-foreground/60 leading-normal", children: description })
|
|
108
|
-
] })
|
|
109
|
-
]
|
|
110
|
-
}
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
function AvailableNodesPanel() {
|
|
114
|
-
const [setActivePanel] = useFlowStore(
|
|
115
|
-
useShallow((s) => [s.actions.sidebar.setActivePanel])
|
|
116
|
-
);
|
|
117
|
-
const [triggersExpanded, setTriggersExpanded] = useState(true);
|
|
118
|
-
const [builtInExpanded, setBuiltInExpanded] = useState(true);
|
|
119
|
-
const [storeExpanded, setStoreExpanded] = useState(true);
|
|
120
|
-
const [nodesLoaded, setNodesLoaded] = useState(isNodeConfigsInitialized());
|
|
121
|
-
const insertNode = useInsertNode();
|
|
122
|
-
useEffect(() => {
|
|
123
|
-
if (!nodesLoaded) {
|
|
124
|
-
ensureNodeConfigsLoaded().then(() => {
|
|
125
|
-
setNodesLoaded(true);
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
}, [nodesLoaded]);
|
|
129
|
-
const isTriggerType = (type) => {
|
|
130
|
-
return type === "trigger" || type === "trigger:api" || type.startsWith("trigger:") || type.startsWith("internal:schedule") || type.startsWith("internal:webhook") || type.startsWith("internal:api") || type.startsWith("internal:form") || type.startsWith("internal:mcp") || type.endsWith("_trigger") || type.endsWith("Trigger") || type.endsWith("-trigger") || type === "integration/channel";
|
|
131
|
-
};
|
|
132
|
-
const triggerNodes = AVAILABLE_NODES.filter((node) => {
|
|
133
|
-
return isTriggerType(node.type) && (node.publishType === "BUILTIN" || node.publishType === void 0 || node.publishType === null);
|
|
134
|
-
});
|
|
135
|
-
const builtInNodes = AVAILABLE_NODES.filter((node) => {
|
|
136
|
-
return !isTriggerType(node.type) && (node.publishType === "BUILTIN" || node.publishType === void 0 || node.publishType === null);
|
|
137
|
-
});
|
|
138
|
-
const storeNodes = AVAILABLE_NODES.filter((node) => {
|
|
139
|
-
return node.publishType === "STORE";
|
|
140
|
-
});
|
|
141
|
-
const storeTriggerNodes = storeNodes.filter(
|
|
142
|
-
(node) => isTriggerType(node.type)
|
|
143
|
-
);
|
|
144
|
-
const storeActionNodes = storeNodes.filter(
|
|
145
|
-
(node) => !isTriggerType(node.type)
|
|
146
|
-
);
|
|
147
|
-
return /* @__PURE__ */ jsxs(SidebarPanelWrapper, { children: [
|
|
148
|
-
/* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-col items-center p-4 text-center", children: [
|
|
149
|
-
/* @__PURE__ */ jsx("div", { className: "size-12 flex items-center justify-center rounded-full bg-primary", children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:grid", className: "size-6 text-white" }) }),
|
|
150
|
-
/* @__PURE__ */ jsx("div", { className: "mt-4 text-balance font-medium", children: "Available Nodes" }),
|
|
151
|
-
/* @__PURE__ */ jsx("div", { className: "mt-1 w-2/3 text-xs text-light-50/40 font-medium leading-normal", children: "Drag and drop nodes to build your workflow" })
|
|
152
|
-
] }),
|
|
153
|
-
!nodesLoaded && /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center p-8", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
|
|
154
|
-
/* @__PURE__ */ jsx(
|
|
155
|
-
Icon,
|
|
156
|
-
{
|
|
157
|
-
icon: "mynaui:spinner",
|
|
158
|
-
className: "size-6 text-primary animate-spin"
|
|
159
|
-
}
|
|
160
|
-
),
|
|
161
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm text-foreground/60", children: "Loading nodes..." })
|
|
162
|
-
] }) }),
|
|
163
|
-
nodesLoaded && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 p-4 overflow-y-auto max-h-[calc(100vh-200px)] scrollbar-thin scrollbar-track-transparent hover:scrollbar-thumb-gray-300/50 scrollbar-thumb-gray-300/30 scrollbar-w-[3px]", children: [
|
|
164
|
-
(triggerNodes.length > 0 || storeTriggerNodes.length > 0) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
165
|
-
/* @__PURE__ */ jsxs(
|
|
166
|
-
"button",
|
|
167
|
-
{
|
|
168
|
-
onClick: () => setTriggersExpanded(!triggersExpanded),
|
|
169
|
-
className: "flex items-center justify-between px-2 py-1.5 text-sm font-medium text-foreground/80 hover:text-foreground transition-colors",
|
|
170
|
-
children: [
|
|
171
|
-
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
|
|
172
|
-
/* @__PURE__ */ jsx(
|
|
173
|
-
Icon,
|
|
174
|
-
{
|
|
175
|
-
icon: triggersExpanded ? "mynaui:chevron-down" : "mynaui:chevron-right",
|
|
176
|
-
className: "size-4"
|
|
177
|
-
}
|
|
178
|
-
),
|
|
179
|
-
/* @__PURE__ */ jsx(
|
|
180
|
-
Icon,
|
|
181
|
-
{
|
|
182
|
-
icon: "solar:play-bold",
|
|
183
|
-
className: "size-3.5 text-primary"
|
|
184
|
-
}
|
|
185
|
-
),
|
|
186
|
-
"Triggers"
|
|
187
|
-
] }),
|
|
188
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-foreground/50", children: triggerNodes.length + storeTriggerNodes.length })
|
|
189
|
-
]
|
|
190
|
-
}
|
|
191
|
-
),
|
|
192
|
-
triggersExpanded && /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-3 pl-2", children: [
|
|
193
|
-
triggerNodes.map((node) => /* @__PURE__ */ jsx(
|
|
194
|
-
NodePreviewDraggable,
|
|
195
|
-
{
|
|
196
|
-
type: node.type,
|
|
197
|
-
icon: node.icon,
|
|
198
|
-
title: node.title,
|
|
199
|
-
description: node.description ?? "",
|
|
200
|
-
setActivePanel,
|
|
201
|
-
insertNode
|
|
202
|
-
},
|
|
203
|
-
node.type
|
|
204
|
-
)),
|
|
205
|
-
storeTriggerNodes.map((node) => /* @__PURE__ */ jsx(
|
|
206
|
-
NodePreviewDraggable,
|
|
207
|
-
{
|
|
208
|
-
type: node.type,
|
|
209
|
-
icon: node.icon,
|
|
210
|
-
title: node.title,
|
|
211
|
-
description: node.description ?? "",
|
|
212
|
-
setActivePanel,
|
|
213
|
-
insertNode
|
|
214
|
-
},
|
|
215
|
-
node.type
|
|
216
|
-
))
|
|
217
|
-
] })
|
|
218
|
-
] }),
|
|
219
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
220
|
-
/* @__PURE__ */ jsxs(
|
|
221
|
-
"button",
|
|
222
|
-
{
|
|
223
|
-
onClick: () => setBuiltInExpanded(!builtInExpanded),
|
|
224
|
-
className: "flex items-center justify-between px-2 py-1.5 text-sm font-medium text-foreground/80 hover:text-foreground transition-colors",
|
|
225
|
-
children: [
|
|
226
|
-
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
|
|
227
|
-
/* @__PURE__ */ jsx(
|
|
228
|
-
Icon,
|
|
229
|
-
{
|
|
230
|
-
icon: builtInExpanded ? "mynaui:chevron-down" : "mynaui:chevron-right",
|
|
231
|
-
className: "size-4"
|
|
232
|
-
}
|
|
233
|
-
),
|
|
234
|
-
"Built-in Nodes"
|
|
235
|
-
] }),
|
|
236
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs text-foreground/50", children: builtInNodes.length })
|
|
237
|
-
]
|
|
238
|
-
}
|
|
239
|
-
),
|
|
240
|
-
builtInExpanded && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-3 pl-2", children: builtInNodes.map((node) => /* @__PURE__ */ jsx(
|
|
241
|
-
NodePreviewDraggable,
|
|
242
|
-
{
|
|
243
|
-
type: node.type,
|
|
244
|
-
icon: node.icon,
|
|
245
|
-
title: node.title,
|
|
246
|
-
description: node.description ?? "",
|
|
247
|
-
setActivePanel,
|
|
248
|
-
insertNode
|
|
249
|
-
},
|
|
250
|
-
node.type
|
|
251
|
-
)) })
|
|
252
|
-
] }),
|
|
253
|
-
storeActionNodes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
254
|
-
/* @__PURE__ */ jsxs(
|
|
255
|
-
"button",
|
|
256
|
-
{
|
|
257
|
-
onClick: () => setStoreExpanded(!storeExpanded),
|
|
258
|
-
className: "flex items-center justify-between px-2 py-1.5 text-sm font-medium text-foreground/80 hover:text-foreground transition-colors",
|
|
259
|
-
children: [
|
|
260
|
-
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
|
|
261
|
-
/* @__PURE__ */ jsx(
|
|
262
|
-
Icon,
|
|
263
|
-
{
|
|
264
|
-
icon: storeExpanded ? "mynaui:chevron-down" : "mynaui:chevron-right",
|
|
265
|
-
className: "size-4"
|
|
266
|
-
}
|
|
267
|
-
),
|
|
268
|
-
"Store Nodes",
|
|
269
|
-
/* @__PURE__ */ jsx(
|
|
270
|
-
Icon,
|
|
271
|
-
{
|
|
272
|
-
icon: "mynaui:shopping-bag",
|
|
273
|
-
className: "size-3.5 text-primary"
|
|
274
|
-
}
|
|
275
|
-
)
|
|
276
|
-
] }),
|
|
277
|
-
/* @__PURE__ */ jsxs("span", { className: "text-xs text-foreground/50", children: [
|
|
278
|
-
storeActionNodes.length,
|
|
279
|
-
" installed"
|
|
280
|
-
] })
|
|
281
|
-
]
|
|
282
|
-
}
|
|
283
|
-
),
|
|
284
|
-
storeExpanded && /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-3 pl-2", children: storeActionNodes.map((node) => /* @__PURE__ */ jsx(
|
|
285
|
-
NodePreviewDraggable,
|
|
286
|
-
{
|
|
287
|
-
type: node.type,
|
|
288
|
-
icon: node.icon,
|
|
289
|
-
title: node.title,
|
|
290
|
-
description: node.description ?? "",
|
|
291
|
-
setActivePanel,
|
|
292
|
-
insertNode
|
|
293
|
-
},
|
|
294
|
-
node.type
|
|
295
|
-
)) })
|
|
296
|
-
] })
|
|
297
|
-
] })
|
|
298
|
-
] });
|
|
299
|
-
}
|
|
300
|
-
function useNodeList(nodes) {
|
|
301
|
-
return useMemo(() => {
|
|
302
|
-
return nodes.slice().sort((a, b) => {
|
|
303
|
-
if (a.type === "trigger:api" /* TRIGGER */) return -1;
|
|
304
|
-
if (b.type === "trigger:api" /* TRIGGER */) return 1;
|
|
305
|
-
if (a.type === "end" /* END */) return 1;
|
|
306
|
-
if (b.type === "end" /* END */) return -1;
|
|
307
|
-
return 0;
|
|
308
|
-
}).map((n) => ({
|
|
309
|
-
...n,
|
|
310
|
-
detail: getNodeDetail(n.type)
|
|
311
|
-
}));
|
|
312
|
-
}, [nodes]);
|
|
313
|
-
}
|
|
314
67
|
function SidebarPanelHeading({
|
|
315
68
|
children,
|
|
316
69
|
className,
|
|
@@ -1309,37 +1062,51 @@ function NodePropertiesPanel() {
|
|
|
1309
1062
|
] });
|
|
1310
1063
|
}
|
|
1311
1064
|
|
|
1312
|
-
// src/builder/components/flow-builder/components/blocks/sidebar/
|
|
1313
|
-
var
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1065
|
+
// src/builder/components/flow-builder/components/blocks/sidebar/panels/store-browse/store-categories.ts
|
|
1066
|
+
var STORE_CATEGORIES = [
|
|
1067
|
+
{
|
|
1068
|
+
key: "ai",
|
|
1069
|
+
label: "AI & Automation",
|
|
1070
|
+
description: "AI models, agents, and intelligent automation",
|
|
1071
|
+
icon: "mynaui:brain"
|
|
1072
|
+
},
|
|
1073
|
+
{
|
|
1074
|
+
key: "integration",
|
|
1075
|
+
label: "Action in an App",
|
|
1076
|
+
description: "Connect with apps like Slack, Notion, Google Sheets",
|
|
1077
|
+
icon: "mynaui:puzzle"
|
|
1078
|
+
},
|
|
1079
|
+
{
|
|
1080
|
+
key: "data",
|
|
1081
|
+
label: "Data & Transform",
|
|
1082
|
+
description: "Manipulate, filter, or convert data",
|
|
1083
|
+
icon: "mynaui:database"
|
|
1084
|
+
},
|
|
1085
|
+
{
|
|
1086
|
+
key: "flow",
|
|
1087
|
+
label: "Flow & Logic",
|
|
1088
|
+
description: "Branch, merge, or loop the flow",
|
|
1089
|
+
icon: "mynaui:git-branch"
|
|
1090
|
+
},
|
|
1091
|
+
{
|
|
1092
|
+
key: "core",
|
|
1093
|
+
label: "Core",
|
|
1094
|
+
description: "HTTP requests, code, webhooks, and more",
|
|
1095
|
+
icon: "mynaui:cog"
|
|
1096
|
+
},
|
|
1097
|
+
{
|
|
1098
|
+
key: "communication",
|
|
1099
|
+
label: "Communication",
|
|
1100
|
+
description: "Email, messaging, and notifications",
|
|
1101
|
+
icon: "mynaui:message-dots"
|
|
1102
|
+
},
|
|
1103
|
+
{
|
|
1104
|
+
key: "trigger",
|
|
1105
|
+
label: "Triggers",
|
|
1106
|
+
description: "Start your workflow automatically",
|
|
1107
|
+
icon: "mynaui:bolt"
|
|
1108
|
+
}
|
|
1109
|
+
];
|
|
1343
1110
|
function useStoreNodes(options = {}) {
|
|
1344
1111
|
const client = useGlobalStoreClient();
|
|
1345
1112
|
const context = useContext(FluidGridsContext);
|
|
@@ -1720,159 +1487,318 @@ gql$1`
|
|
|
1720
1487
|
}
|
|
1721
1488
|
}
|
|
1722
1489
|
`;
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1490
|
+
|
|
1491
|
+
// src/builder/contants/symbols.ts
|
|
1492
|
+
var NODE_TYPE_DRAG_DATA_FORMAT = "application/flow-builder.node-type";
|
|
1493
|
+
function StoreNodeListItem({
|
|
1494
|
+
name,
|
|
1495
|
+
description,
|
|
1496
|
+
icon,
|
|
1497
|
+
isInstalled,
|
|
1498
|
+
hasUpdate,
|
|
1499
|
+
nodeType,
|
|
1500
|
+
isDraggable,
|
|
1728
1501
|
onClick
|
|
1729
1502
|
}) {
|
|
1503
|
+
const handleDragStart = useCallback(
|
|
1504
|
+
(e) => {
|
|
1505
|
+
if (!isDraggable || !nodeType) return;
|
|
1506
|
+
e.dataTransfer.setData(NODE_TYPE_DRAG_DATA_FORMAT, nodeType);
|
|
1507
|
+
e.dataTransfer.effectAllowed = "move";
|
|
1508
|
+
},
|
|
1509
|
+
[isDraggable, nodeType]
|
|
1510
|
+
);
|
|
1730
1511
|
return /* @__PURE__ */ jsxs(
|
|
1731
|
-
|
|
1512
|
+
"button",
|
|
1732
1513
|
{
|
|
1733
|
-
variant: "ghost",
|
|
1734
|
-
size: "sm",
|
|
1735
|
-
className: cn(
|
|
1736
|
-
"w-full justify-start gap-2 px-3",
|
|
1737
|
-
active && "bg-accent text-accent-foreground"
|
|
1738
|
-
),
|
|
1739
1514
|
onClick,
|
|
1515
|
+
draggable: isDraggable && !!nodeType,
|
|
1516
|
+
onDragStart: handleDragStart,
|
|
1517
|
+
title: isDraggable ? `${name} \u2014 drag to add to canvas` : name,
|
|
1518
|
+
className: "w-full flex items-center gap-3 px-2 py-2.5 rounded-md hover:bg-muted/60 transition-colors text-left group",
|
|
1519
|
+
style: isDraggable ? { cursor: "grab" } : void 0,
|
|
1740
1520
|
children: [
|
|
1741
|
-
/* @__PURE__ */ jsx(
|
|
1742
|
-
/* @__PURE__ */
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1521
|
+
/* @__PURE__ */ jsx("div", { className: "size-9 shrink-0 rounded-lg bg-muted flex items-center justify-center overflow-hidden", children: icon ? /* @__PURE__ */ jsx("img", { src: icon, alt: name, className: "w-full h-full object-cover" }) : /* @__PURE__ */ jsx("span", { className: "text-sm font-bold text-muted-foreground", children: name.charAt(0).toUpperCase() }) }),
|
|
1522
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
1523
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 flex-wrap", children: [
|
|
1524
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-foreground group-hover:text-primary transition-colors truncate", children: name }),
|
|
1525
|
+
hasUpdate && /* @__PURE__ */ jsx(
|
|
1526
|
+
"span",
|
|
1527
|
+
{
|
|
1528
|
+
className: "shrink-0 inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-semibold",
|
|
1529
|
+
style: {
|
|
1530
|
+
background: "var(--color-status-warning-bgSubtle)",
|
|
1531
|
+
color: "var(--color-status-warning-text)"
|
|
1532
|
+
},
|
|
1533
|
+
children: "Update"
|
|
1534
|
+
}
|
|
1535
|
+
),
|
|
1536
|
+
isInstalled && !hasUpdate && /* @__PURE__ */ jsxs(
|
|
1537
|
+
"span",
|
|
1538
|
+
{
|
|
1539
|
+
className: "shrink-0 inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded text-[10px] font-semibold",
|
|
1540
|
+
style: {
|
|
1541
|
+
background: "var(--color-status-success-bgSubtle)",
|
|
1542
|
+
color: "var(--color-status-success-text)"
|
|
1543
|
+
},
|
|
1544
|
+
children: [
|
|
1545
|
+
/* @__PURE__ */ jsx(
|
|
1546
|
+
"span",
|
|
1547
|
+
{
|
|
1548
|
+
className: "size-1.5 rounded-full inline-block",
|
|
1549
|
+
style: { background: "var(--color-status-success-bg)" }
|
|
1550
|
+
}
|
|
1551
|
+
),
|
|
1552
|
+
"Installed"
|
|
1553
|
+
]
|
|
1554
|
+
}
|
|
1555
|
+
)
|
|
1556
|
+
] }),
|
|
1557
|
+
description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground truncate mt-0.5 leading-snug", children: description })
|
|
1558
|
+
] }),
|
|
1559
|
+
isDraggable ? /* @__PURE__ */ jsx(
|
|
1560
|
+
Icon,
|
|
1561
|
+
{
|
|
1562
|
+
icon: "mynaui:drag-dots-vertical",
|
|
1563
|
+
className: "size-4 shrink-0 text-foreground/40 group-hover:text-primary transition-colors"
|
|
1564
|
+
}
|
|
1565
|
+
) : /* @__PURE__ */ jsx(
|
|
1566
|
+
Icon,
|
|
1567
|
+
{
|
|
1568
|
+
icon: "mynaui:chevron-right",
|
|
1569
|
+
className: "size-4 shrink-0 text-foreground/40"
|
|
1570
|
+
}
|
|
1571
|
+
)
|
|
1572
|
+
]
|
|
1573
|
+
}
|
|
1574
|
+
);
|
|
1575
|
+
}
|
|
1576
|
+
function StoreCategoryList({
|
|
1577
|
+
searchTerm,
|
|
1578
|
+
onSearchChange,
|
|
1579
|
+
onSelectCategory,
|
|
1580
|
+
onSelectNode
|
|
1581
|
+
}) {
|
|
1582
|
+
const isSearching = searchTerm.trim().length > 0;
|
|
1583
|
+
const { products, loading, hasMore, fetchMore } = useStoreNodes({
|
|
1584
|
+
filter: {
|
|
1585
|
+
type: "NODE",
|
|
1586
|
+
compatibleWith: "fluidgrids",
|
|
1587
|
+
search: isSearching ? searchTerm.trim() : void 0
|
|
1588
|
+
}
|
|
1589
|
+
});
|
|
1590
|
+
const { installedAppIds, installationsMap } = useInstalledNodes();
|
|
1591
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
1592
|
+
/* @__PURE__ */ jsx("div", { className: "px-3 pt-3 pb-2 shrink-0", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
1794
1593
|
/* @__PURE__ */ jsx(
|
|
1795
|
-
|
|
1594
|
+
Icon,
|
|
1796
1595
|
{
|
|
1797
|
-
icon:
|
|
1798
|
-
|
|
1799
|
-
active: activeTab === "missing",
|
|
1800
|
-
onClick: () => onTabChange("missing")
|
|
1596
|
+
icon: "mynaui:search",
|
|
1597
|
+
className: "absolute left-2.5 top-1/2 -translate-y-1/2 size-4 text-muted-foreground pointer-events-none"
|
|
1801
1598
|
}
|
|
1802
1599
|
),
|
|
1803
1600
|
/* @__PURE__ */ jsx(
|
|
1804
|
-
|
|
1601
|
+
Input$1,
|
|
1602
|
+
{
|
|
1603
|
+
value: searchTerm,
|
|
1604
|
+
onChange: (e) => onSearchChange(e.target.value),
|
|
1605
|
+
placeholder: "Search nodes...",
|
|
1606
|
+
className: "pl-8 text-sm h-9"
|
|
1607
|
+
}
|
|
1608
|
+
),
|
|
1609
|
+
searchTerm && /* @__PURE__ */ jsx(
|
|
1610
|
+
"button",
|
|
1805
1611
|
{
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
onClick: () => onTabChange("update-available")
|
|
1612
|
+
onClick: () => onSearchChange(""),
|
|
1613
|
+
className: "absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",
|
|
1614
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:x", className: "size-3.5" })
|
|
1810
1615
|
}
|
|
1811
1616
|
)
|
|
1812
|
-
] })
|
|
1617
|
+
] }) }),
|
|
1618
|
+
isSearching ? (
|
|
1619
|
+
/* Search results */
|
|
1620
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto px-2 pb-2", children: loading && products.length === 0 ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-10", children: /* @__PURE__ */ jsx(
|
|
1621
|
+
Icon,
|
|
1622
|
+
{
|
|
1623
|
+
icon: "mynaui:spinner",
|
|
1624
|
+
className: "size-5 text-primary animate-spin"
|
|
1625
|
+
}
|
|
1626
|
+
) }) : products.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-center py-10 px-4", children: /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
1627
|
+
"No nodes found for \u201C",
|
|
1628
|
+
searchTerm,
|
|
1629
|
+
"\u201D"
|
|
1630
|
+
] }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1631
|
+
/* @__PURE__ */ jsxs("p", { className: "px-2 py-1.5 text-xs text-muted-foreground font-medium", children: [
|
|
1632
|
+
products.length,
|
|
1633
|
+
" result",
|
|
1634
|
+
products.length !== 1 ? "s" : ""
|
|
1635
|
+
] }),
|
|
1636
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5", children: products.map((node) => {
|
|
1637
|
+
const installation = installationsMap.get(node.id);
|
|
1638
|
+
const isInstalled = installedAppIds.has(node.id);
|
|
1639
|
+
const hasUpdate = isInstalled && !!installation?.installedVersion && !!node.manifestVersion && installation.installedVersion !== node.manifestVersion;
|
|
1640
|
+
const manifestNodeType = node.manifest?.nodeType;
|
|
1641
|
+
const nodeType = manifestNodeType ?? (isInstalled ? `store/${node.slug}` : void 0);
|
|
1642
|
+
const isDraggable = !!nodeType && (isInstalled || AVAILABLE_NODES.some((n) => n.type === nodeType));
|
|
1643
|
+
return /* @__PURE__ */ jsx(
|
|
1644
|
+
StoreNodeListItem,
|
|
1645
|
+
{
|
|
1646
|
+
name: node.name,
|
|
1647
|
+
description: node.description,
|
|
1648
|
+
icon: node.icon,
|
|
1649
|
+
isInstalled,
|
|
1650
|
+
hasUpdate,
|
|
1651
|
+
nodeType,
|
|
1652
|
+
isDraggable,
|
|
1653
|
+
onClick: () => onSelectNode(node)
|
|
1654
|
+
},
|
|
1655
|
+
node.id
|
|
1656
|
+
);
|
|
1657
|
+
}) }),
|
|
1658
|
+
hasMore && /* @__PURE__ */ jsx(
|
|
1659
|
+
"button",
|
|
1660
|
+
{
|
|
1661
|
+
onClick: fetchMore,
|
|
1662
|
+
className: "w-full mt-2 py-2 text-xs text-primary hover:text-primary/80 font-medium transition-colors",
|
|
1663
|
+
children: "Load more"
|
|
1664
|
+
}
|
|
1665
|
+
)
|
|
1666
|
+
] }) })
|
|
1667
|
+
) : (
|
|
1668
|
+
/* Category list */
|
|
1669
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto px-2 pb-2", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0.5 pt-1", children: STORE_CATEGORIES.map((cat) => /* @__PURE__ */ jsxs(
|
|
1670
|
+
"button",
|
|
1671
|
+
{
|
|
1672
|
+
onClick: () => onSelectCategory(cat),
|
|
1673
|
+
className: "w-full flex items-center gap-3 px-2 py-3 rounded-md hover:bg-muted/60 transition-colors text-left group",
|
|
1674
|
+
children: [
|
|
1675
|
+
/* @__PURE__ */ jsx("div", { className: "size-9 shrink-0 rounded-lg bg-muted flex items-center justify-center", children: /* @__PURE__ */ jsx(Icon, { icon: cat.icon, className: "size-5 text-primary" }) }),
|
|
1676
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
1677
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground group-hover:text-primary transition-colors", children: cat.label }),
|
|
1678
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground truncate mt-0.5", children: cat.description })
|
|
1679
|
+
] }),
|
|
1680
|
+
/* @__PURE__ */ jsx(
|
|
1681
|
+
Icon,
|
|
1682
|
+
{
|
|
1683
|
+
icon: "mynaui:chevron-right",
|
|
1684
|
+
className: "size-4 shrink-0 text-foreground/40"
|
|
1685
|
+
}
|
|
1686
|
+
)
|
|
1687
|
+
]
|
|
1688
|
+
},
|
|
1689
|
+
cat.key
|
|
1690
|
+
)) }) })
|
|
1691
|
+
)
|
|
1813
1692
|
] });
|
|
1814
1693
|
}
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
);
|
|
1828
|
-
Card.displayName = "Card";
|
|
1829
|
-
var CardHeader = forwardRef(
|
|
1830
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1831
|
-
"div",
|
|
1832
|
-
{
|
|
1833
|
-
ref,
|
|
1834
|
-
className: cn("flex flex-col space-y-1.5 p-6", className),
|
|
1835
|
-
...props
|
|
1836
|
-
}
|
|
1837
|
-
)
|
|
1838
|
-
);
|
|
1839
|
-
CardHeader.displayName = "CardHeader";
|
|
1840
|
-
var CardTitle = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1841
|
-
"h3",
|
|
1842
|
-
{
|
|
1843
|
-
ref,
|
|
1844
|
-
className: cn(
|
|
1845
|
-
"text-2xl font-semibold leading-none tracking-tight",
|
|
1846
|
-
className
|
|
1847
|
-
),
|
|
1848
|
-
...props
|
|
1849
|
-
}
|
|
1850
|
-
));
|
|
1851
|
-
CardTitle.displayName = "CardTitle";
|
|
1852
|
-
var CardDescription = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1853
|
-
"p",
|
|
1854
|
-
{
|
|
1855
|
-
ref,
|
|
1856
|
-
className: cn("text-sm text-muted-foreground", className),
|
|
1857
|
-
...props
|
|
1858
|
-
}
|
|
1859
|
-
));
|
|
1860
|
-
CardDescription.displayName = "CardDescription";
|
|
1861
|
-
var CardContent = forwardRef(
|
|
1862
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props })
|
|
1863
|
-
);
|
|
1864
|
-
CardContent.displayName = "CardContent";
|
|
1865
|
-
var CardFooter = forwardRef(
|
|
1866
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1867
|
-
"div",
|
|
1868
|
-
{
|
|
1869
|
-
ref,
|
|
1870
|
-
className: cn("flex items-center p-6 pt-0", className),
|
|
1871
|
-
...props
|
|
1694
|
+
function StoreCategoryNodes({
|
|
1695
|
+
category,
|
|
1696
|
+
onBack,
|
|
1697
|
+
onSelectNode
|
|
1698
|
+
}) {
|
|
1699
|
+
const [searchTerm, setSearchTerm] = useState("");
|
|
1700
|
+
const { products, loading, hasMore, fetchMore } = useStoreNodes({
|
|
1701
|
+
filter: {
|
|
1702
|
+
type: "NODE",
|
|
1703
|
+
compatibleWith: "fluidgrids",
|
|
1704
|
+
category: category.key || void 0,
|
|
1705
|
+
search: searchTerm.trim() || void 0
|
|
1872
1706
|
}
|
|
1873
|
-
)
|
|
1874
|
-
);
|
|
1875
|
-
|
|
1707
|
+
});
|
|
1708
|
+
const { installedAppIds, installationsMap } = useInstalledNodes();
|
|
1709
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
1710
|
+
/* @__PURE__ */ jsxs("div", { className: "px-3 pt-3 pb-2 shrink-0", children: [
|
|
1711
|
+
/* @__PURE__ */ jsxs(
|
|
1712
|
+
"button",
|
|
1713
|
+
{
|
|
1714
|
+
onClick: onBack,
|
|
1715
|
+
className: "flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground mb-3 transition-colors",
|
|
1716
|
+
children: [
|
|
1717
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mynaui:chevron-left", className: "size-3.5" }),
|
|
1718
|
+
"Back"
|
|
1719
|
+
]
|
|
1720
|
+
}
|
|
1721
|
+
),
|
|
1722
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 mb-3", children: [
|
|
1723
|
+
/* @__PURE__ */ jsx("div", { className: "size-8 shrink-0 rounded-lg bg-muted flex items-center justify-center", children: /* @__PURE__ */ jsx(Icon, { icon: category.icon, className: "size-4 text-primary" }) }),
|
|
1724
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
1725
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-foreground leading-tight", children: category.label }),
|
|
1726
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground truncate", children: category.description })
|
|
1727
|
+
] })
|
|
1728
|
+
] }),
|
|
1729
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
1730
|
+
/* @__PURE__ */ jsx(
|
|
1731
|
+
Icon,
|
|
1732
|
+
{
|
|
1733
|
+
icon: "mynaui:search",
|
|
1734
|
+
className: "absolute left-2.5 top-1/2 -translate-y-1/2 size-4 text-muted-foreground pointer-events-none"
|
|
1735
|
+
}
|
|
1736
|
+
),
|
|
1737
|
+
/* @__PURE__ */ jsx(
|
|
1738
|
+
Input$1,
|
|
1739
|
+
{
|
|
1740
|
+
value: searchTerm,
|
|
1741
|
+
onChange: (e) => setSearchTerm(e.target.value),
|
|
1742
|
+
placeholder: `Search in ${category.label}...`,
|
|
1743
|
+
className: "pl-8 text-sm h-9"
|
|
1744
|
+
}
|
|
1745
|
+
),
|
|
1746
|
+
searchTerm && /* @__PURE__ */ jsx(
|
|
1747
|
+
"button",
|
|
1748
|
+
{
|
|
1749
|
+
onClick: () => setSearchTerm(""),
|
|
1750
|
+
className: "absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",
|
|
1751
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:x", className: "size-3.5" })
|
|
1752
|
+
}
|
|
1753
|
+
)
|
|
1754
|
+
] })
|
|
1755
|
+
] }),
|
|
1756
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto px-2 pb-2", children: loading && products.length === 0 ? /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-10", children: /* @__PURE__ */ jsx(
|
|
1757
|
+
Icon,
|
|
1758
|
+
{
|
|
1759
|
+
icon: "mynaui:spinner",
|
|
1760
|
+
className: "size-5 text-primary animate-spin"
|
|
1761
|
+
}
|
|
1762
|
+
) }) : products.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-center py-10 px-4", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: searchTerm ? `No nodes found for "${searchTerm}"` : "No nodes in this category yet" }) }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
1763
|
+
/* @__PURE__ */ jsxs("p", { className: "px-2 py-1.5 text-xs text-muted-foreground font-medium", children: [
|
|
1764
|
+
products.length,
|
|
1765
|
+
" node",
|
|
1766
|
+
products.length !== 1 ? "s" : "",
|
|
1767
|
+
searchTerm ? ` matching "${searchTerm}"` : ""
|
|
1768
|
+
] }),
|
|
1769
|
+
products.map((node) => {
|
|
1770
|
+
const installation = installationsMap.get(node.id);
|
|
1771
|
+
const isInstalled = installedAppIds.has(node.id);
|
|
1772
|
+
const hasUpdate = isInstalled && !!installation?.installedVersion && !!node.manifestVersion && installation.installedVersion !== node.manifestVersion;
|
|
1773
|
+
const manifestNodeType = node.manifest?.nodeType;
|
|
1774
|
+
const nodeType = manifestNodeType ?? (isInstalled ? `store/${node.slug}` : void 0);
|
|
1775
|
+
const isDraggable = !!nodeType && (isInstalled || AVAILABLE_NODES.some((n) => n.type === nodeType));
|
|
1776
|
+
return /* @__PURE__ */ jsx(
|
|
1777
|
+
StoreNodeListItem,
|
|
1778
|
+
{
|
|
1779
|
+
name: node.name,
|
|
1780
|
+
description: node.description,
|
|
1781
|
+
icon: node.icon,
|
|
1782
|
+
isInstalled,
|
|
1783
|
+
hasUpdate,
|
|
1784
|
+
nodeType,
|
|
1785
|
+
isDraggable,
|
|
1786
|
+
onClick: () => onSelectNode(node)
|
|
1787
|
+
},
|
|
1788
|
+
node.id
|
|
1789
|
+
);
|
|
1790
|
+
}),
|
|
1791
|
+
hasMore && /* @__PURE__ */ jsx(
|
|
1792
|
+
"button",
|
|
1793
|
+
{
|
|
1794
|
+
onClick: fetchMore,
|
|
1795
|
+
className: "w-full mt-2 py-2 text-xs text-primary hover:text-primary/80 font-medium transition-colors",
|
|
1796
|
+
children: "Load more"
|
|
1797
|
+
}
|
|
1798
|
+
)
|
|
1799
|
+
] }) })
|
|
1800
|
+
] });
|
|
1801
|
+
}
|
|
1876
1802
|
var UninstallNodeDialog = ({
|
|
1877
1803
|
nodeName,
|
|
1878
1804
|
nodeType,
|
|
@@ -1964,28 +1890,22 @@ var UninstallNodeDialog = ({
|
|
|
1964
1890
|
] }) });
|
|
1965
1891
|
};
|
|
1966
1892
|
function formatDownloads(count2) {
|
|
1967
|
-
if (count2 >= 1e6) {
|
|
1968
|
-
|
|
1969
|
-
}
|
|
1970
|
-
if (count2 >= 1e3) {
|
|
1971
|
-
return `${(count2 / 1e3).toFixed(1)}k`;
|
|
1972
|
-
}
|
|
1893
|
+
if (count2 >= 1e6) return `${(count2 / 1e6).toFixed(1)}M`;
|
|
1894
|
+
if (count2 >= 1e3) return `${(count2 / 1e3).toFixed(1)}k`;
|
|
1973
1895
|
return count2.toString();
|
|
1974
1896
|
}
|
|
1975
|
-
function
|
|
1976
|
-
node,
|
|
1977
|
-
isInstalled,
|
|
1978
|
-
installedVersion,
|
|
1979
|
-
installationId,
|
|
1980
|
-
onClick
|
|
1981
|
-
}) {
|
|
1897
|
+
function StoreNodeDetail({ node, onBack }) {
|
|
1982
1898
|
const { installNode, installing } = useInstallNode();
|
|
1983
1899
|
const { updateNode, updating } = useUpdateNode();
|
|
1984
1900
|
const { uninstallNode, loading: uninstalling } = useUninstallNode();
|
|
1985
|
-
const { checkNodeUsage} = useNodeUsageInWorkflows();
|
|
1901
|
+
const { checkNodeUsage } = useNodeUsageInWorkflows();
|
|
1986
1902
|
const { removeNodeFromWorkflows } = useRemoveNodeFromWorkflows();
|
|
1987
1903
|
const { createOrder, creating: creatingOrder } = useCreateOrder();
|
|
1988
|
-
const {
|
|
1904
|
+
const {
|
|
1905
|
+
installedAppIds,
|
|
1906
|
+
installationsMap,
|
|
1907
|
+
refetch: refetchInstalledNodes
|
|
1908
|
+
} = useInstalledNodes();
|
|
1989
1909
|
const { refreshAvailableNodes } = useRefreshAvailableNodes();
|
|
1990
1910
|
const [showUninstallDialog, setShowUninstallDialog] = useState(false);
|
|
1991
1911
|
const [checkingNodeUsage, setCheckingNodeUsage] = useState(false);
|
|
@@ -1993,490 +1913,474 @@ function StoreNodeCard({
|
|
|
1993
1913
|
const [nodeUsage, setNodeUsage] = useState({ isUsed: false, workflows: [] });
|
|
1994
1914
|
const context = useContext(FluidGridsContext);
|
|
1995
1915
|
const workspaceId = context?.workspaceId ?? getFluidGridsConfig().workspaceId;
|
|
1996
|
-
|
|
1916
|
+
const isInstalled = installedAppIds.has(node.id);
|
|
1917
|
+
const installation = installationsMap.get(node.id);
|
|
1918
|
+
const installedVersion = installation?.installedVersion;
|
|
1919
|
+
const installationId = installation?.installationId;
|
|
1997
1920
|
const latestVersion = node.manifestVersion;
|
|
1998
|
-
const hasUpdate = isInstalled && installedVersion && latestVersion && installedVersion !== latestVersion;
|
|
1999
|
-
const
|
|
2000
|
-
|
|
1921
|
+
const hasUpdate = isInstalled && !!installedVersion && !!latestVersion && installedVersion !== latestVersion;
|
|
1922
|
+
const isFree = node.pricingModel === "FREE";
|
|
1923
|
+
const isPurchased = node.isPurchased === true;
|
|
1924
|
+
const canInstall = isFree || isPurchased;
|
|
1925
|
+
const isInstalling = installing === node.id;
|
|
1926
|
+
const isUpdating = updating === node.id;
|
|
1927
|
+
const handleInstall = async () => {
|
|
2001
1928
|
const result = await installNode(node);
|
|
2002
1929
|
if (result.success) {
|
|
2003
|
-
toast.success("Node installed
|
|
1930
|
+
toast.success("Node installed!", {
|
|
2004
1931
|
description: `${node.name} is now available in your workflow builder.`
|
|
2005
1932
|
});
|
|
2006
|
-
console.log(
|
|
2007
|
-
"[StoreNodeCard] Refreshing available nodes after install..."
|
|
2008
|
-
);
|
|
2009
1933
|
await refreshAvailableNodes();
|
|
2010
|
-
console.log("[StoreNodeCard] Refetching installed nodes list...");
|
|
2011
1934
|
await refetchInstalledNodes();
|
|
2012
|
-
console.log("[StoreNodeCard] Refresh complete!");
|
|
2013
1935
|
} else {
|
|
2014
1936
|
toast.error("Installation failed", {
|
|
2015
|
-
description: result.error || "
|
|
1937
|
+
description: result.error || "Please try again."
|
|
2016
1938
|
});
|
|
2017
1939
|
}
|
|
2018
1940
|
};
|
|
2019
|
-
const handleUpdate = async (
|
|
2020
|
-
e.stopPropagation();
|
|
1941
|
+
const handleUpdate = async () => {
|
|
2021
1942
|
if (!installationId) {
|
|
2022
1943
|
toast.error("Cannot update node", {
|
|
2023
|
-
description: "Installation ID not found. Please reinstall
|
|
1944
|
+
description: "Installation ID not found. Please reinstall."
|
|
2024
1945
|
});
|
|
2025
1946
|
return;
|
|
2026
1947
|
}
|
|
2027
1948
|
const result = await updateNode(node, installationId);
|
|
2028
1949
|
if (result.success) {
|
|
2029
|
-
toast.success("Node updated
|
|
2030
|
-
description: `${node.name}
|
|
1950
|
+
toast.success("Node updated!", {
|
|
1951
|
+
description: `${node.name} updated to v${latestVersion}.`
|
|
2031
1952
|
});
|
|
2032
|
-
console.log("[StoreNodeCard] Refreshing available nodes after update...");
|
|
2033
1953
|
await refreshAvailableNodes();
|
|
2034
|
-
console.log("[StoreNodeCard] Refetching installed nodes list...");
|
|
2035
1954
|
await refetchInstalledNodes();
|
|
2036
|
-
console.log("[StoreNodeCard] Refresh complete!");
|
|
2037
1955
|
} else {
|
|
2038
1956
|
toast.error("Update failed", {
|
|
2039
|
-
description: result.error || "
|
|
2040
|
-
});
|
|
2041
|
-
}
|
|
2042
|
-
};
|
|
2043
|
-
const handlePurchase = async (e) => {
|
|
2044
|
-
e.stopPropagation();
|
|
2045
|
-
try {
|
|
2046
|
-
toast.info("Creating order", {
|
|
2047
|
-
description: `Preparing checkout for ${node.name}...`
|
|
2048
|
-
});
|
|
2049
|
-
const unitPrice = node.price || 0;
|
|
2050
|
-
const quantity = 1;
|
|
2051
|
-
const subtotal = unitPrice * quantity;
|
|
2052
|
-
const lineItem = {
|
|
2053
|
-
productId: node.id,
|
|
2054
|
-
name: node.name,
|
|
2055
|
-
// Required: product name at time of purchase
|
|
2056
|
-
quantity,
|
|
2057
|
-
unitPrice,
|
|
2058
|
-
// Required: unit price for one item
|
|
2059
|
-
subtotal,
|
|
2060
|
-
// Required: subtotal (unitPrice * quantity)
|
|
2061
|
-
itemType: "DIGITAL",
|
|
2062
|
-
// Optional: type of item
|
|
2063
|
-
pricingModel: node.pricingModel || "PAID_ONETIME",
|
|
2064
|
-
// Optional: pricing model
|
|
2065
|
-
version: node.manifestVersion || void 0
|
|
2066
|
-
// Optional: product version
|
|
2067
|
-
};
|
|
2068
|
-
const orderInput = {
|
|
2069
|
-
total: subtotal,
|
|
2070
|
-
lineItems: [lineItem],
|
|
2071
|
-
billingAccountId: ""
|
|
2072
|
-
// Will be set on billing page
|
|
2073
|
-
};
|
|
2074
|
-
const result = await createOrder(orderInput);
|
|
2075
|
-
if (result.success && result.order?.id) {
|
|
2076
|
-
console.log("[StoreNodeCard] Order created:", result.order.id);
|
|
2077
|
-
const checkoutUrl = `/billing/checkout/store/${result.order.id}`;
|
|
2078
|
-
console.log("[StoreNodeCard] Navigating to checkout:", checkoutUrl);
|
|
2079
|
-
window.location.href = checkoutUrl;
|
|
2080
|
-
} else {
|
|
2081
|
-
throw new Error(result.error || "Failed to create order");
|
|
2082
|
-
}
|
|
2083
|
-
} catch (error) {
|
|
2084
|
-
console.error("[StoreNodeCard] Purchase flow error:", error);
|
|
2085
|
-
toast.error("Failed to start checkout", {
|
|
2086
|
-
description: error instanceof Error ? error.message : "Please try again."
|
|
1957
|
+
description: result.error || "Please try again."
|
|
2087
1958
|
});
|
|
2088
1959
|
}
|
|
2089
1960
|
};
|
|
2090
|
-
const handleUninstallClick = async (
|
|
2091
|
-
|
|
2092
|
-
if (!installationId) {
|
|
2093
|
-
toast.error("Cannot uninstall node", {
|
|
2094
|
-
description: "Installation ID not found."
|
|
2095
|
-
});
|
|
2096
|
-
return;
|
|
2097
|
-
}
|
|
2098
|
-
if (!workspaceId) {
|
|
2099
|
-
toast.error("Workspace not found", {
|
|
2100
|
-
description: "Unable to check node usage without workspace context."
|
|
2101
|
-
});
|
|
2102
|
-
return;
|
|
2103
|
-
}
|
|
1961
|
+
const handleUninstallClick = async () => {
|
|
1962
|
+
if (!installationId || !workspaceId) return;
|
|
2104
1963
|
try {
|
|
2105
1964
|
setCheckingNodeUsage(true);
|
|
2106
|
-
const nodeVersion = installedVersion || latestVersion || "1.0.0";
|
|
2107
1965
|
const usage = await checkNodeUsage(
|
|
2108
1966
|
workspaceId,
|
|
2109
1967
|
node.name,
|
|
2110
|
-
|
|
2111
|
-
nodeVersion
|
|
1968
|
+
installedVersion || latestVersion || "1.0.0"
|
|
2112
1969
|
);
|
|
2113
1970
|
setNodeUsage(usage);
|
|
2114
1971
|
setShowUninstallDialog(true);
|
|
2115
|
-
} catch
|
|
2116
|
-
|
|
2117
|
-
toast.error("Failed to check node usage", {
|
|
2118
|
-
description: "Please try again."
|
|
2119
|
-
});
|
|
1972
|
+
} catch {
|
|
1973
|
+
toast.error("Failed to check node usage. Please try again.");
|
|
2120
1974
|
} finally {
|
|
2121
1975
|
setCheckingNodeUsage(false);
|
|
2122
1976
|
}
|
|
2123
1977
|
};
|
|
2124
1978
|
const handleConfirmUninstall = async () => {
|
|
2125
|
-
if (!workspaceId)
|
|
2126
|
-
toast.error("Workspace not found", {
|
|
2127
|
-
description: "Unable to uninstall without workspace context."
|
|
2128
|
-
});
|
|
2129
|
-
return;
|
|
2130
|
-
}
|
|
1979
|
+
if (!workspaceId) return;
|
|
2131
1980
|
try {
|
|
2132
1981
|
if (nodeUsage.isUsed && nodeUsage.workflows.length > 0) {
|
|
2133
1982
|
setRemovingFromWorkflows(true);
|
|
2134
|
-
const nodeVersion = installedVersion || latestVersion || "1.0.0";
|
|
2135
|
-
const workflowIds = nodeUsage.workflows.map((wf) => wf.id);
|
|
2136
|
-
console.log(
|
|
2137
|
-
`[StoreNodeCard] Removing node ${node.name} (v${nodeVersion}) from ${workflowIds.length} workflows...`
|
|
2138
|
-
);
|
|
2139
1983
|
const removeResult = await removeNodeFromWorkflows(
|
|
2140
1984
|
node.name,
|
|
2141
|
-
|
|
2142
|
-
|
|
1985
|
+
installedVersion || latestVersion || "1.0.0",
|
|
1986
|
+
nodeUsage.workflows.map((wf) => wf.id)
|
|
2143
1987
|
);
|
|
2144
1988
|
if (!removeResult.success) {
|
|
2145
1989
|
throw new Error("Failed to remove node from workflows");
|
|
2146
1990
|
}
|
|
2147
|
-
console.log(
|
|
2148
|
-
`[StoreNodeCard] Node removed from ${removeResult.removedFromWorkflows.length} workflows, ${removeResult.deactivatedWorkflows.length} workflows deactivated`
|
|
2149
|
-
);
|
|
2150
|
-
toast.info("Node removed from workflows", {
|
|
2151
|
-
description: `Removed from ${removeResult.removedFromWorkflows.length} workflow(s) and deactivated ${removeResult.deactivatedWorkflows.length} workflow(s).`
|
|
2152
|
-
});
|
|
2153
1991
|
setRemovingFromWorkflows(false);
|
|
2154
1992
|
}
|
|
2155
|
-
const result = await uninstallNode({
|
|
2156
|
-
productId: node.id,
|
|
2157
|
-
workspaceId
|
|
2158
|
-
});
|
|
1993
|
+
const result = await uninstallNode({ productId: node.id, workspaceId });
|
|
2159
1994
|
if (result) {
|
|
2160
|
-
toast.success("Node uninstalled
|
|
1995
|
+
toast.success("Node uninstalled", {
|
|
2161
1996
|
description: `${node.name} has been removed from your workspace.`
|
|
2162
1997
|
});
|
|
2163
1998
|
setShowUninstallDialog(false);
|
|
2164
|
-
console.log(
|
|
2165
|
-
"[StoreNodeCard] Refreshing available nodes after uninstall..."
|
|
2166
|
-
);
|
|
2167
1999
|
await refreshAvailableNodes();
|
|
2168
|
-
console.log("[StoreNodeCard] Refetching installed nodes list...");
|
|
2169
2000
|
await refetchInstalledNodes();
|
|
2170
|
-
console.log("[StoreNodeCard] Refresh complete!");
|
|
2171
2001
|
} else {
|
|
2172
2002
|
throw new Error("Uninstall failed");
|
|
2173
2003
|
}
|
|
2174
|
-
} catch (
|
|
2004
|
+
} catch (err) {
|
|
2175
2005
|
toast.error("Uninstall failed", {
|
|
2176
|
-
description:
|
|
2006
|
+
description: err instanceof Error ? err.message : "Please try again."
|
|
2177
2007
|
});
|
|
2178
2008
|
} finally {
|
|
2179
2009
|
setRemovingFromWorkflows(false);
|
|
2180
2010
|
}
|
|
2181
2011
|
};
|
|
2182
|
-
const
|
|
2183
|
-
|
|
2012
|
+
const handlePurchase = async () => {
|
|
2013
|
+
try {
|
|
2014
|
+
toast.info("Creating order", {
|
|
2015
|
+
description: `Preparing checkout for ${node.name}...`
|
|
2016
|
+
});
|
|
2017
|
+
const unitPrice = node.price || 0;
|
|
2018
|
+
const result = await createOrder({
|
|
2019
|
+
total: unitPrice,
|
|
2020
|
+
lineItems: [
|
|
2021
|
+
{
|
|
2022
|
+
productId: node.id,
|
|
2023
|
+
name: node.name,
|
|
2024
|
+
quantity: 1,
|
|
2025
|
+
unitPrice,
|
|
2026
|
+
subtotal: unitPrice,
|
|
2027
|
+
itemType: "DIGITAL",
|
|
2028
|
+
pricingModel: node.pricingModel || "PAID_ONETIME",
|
|
2029
|
+
version: node.manifestVersion || void 0
|
|
2030
|
+
}
|
|
2031
|
+
],
|
|
2032
|
+
billingAccountId: ""
|
|
2033
|
+
});
|
|
2034
|
+
if (result.success && result.order?.id) {
|
|
2035
|
+
window.location.href = `/billing/checkout/store/${result.order.id}`;
|
|
2036
|
+
} else {
|
|
2037
|
+
throw new Error(result.error || "Failed to create order");
|
|
2038
|
+
}
|
|
2039
|
+
} catch (err) {
|
|
2040
|
+
toast.error("Failed to start checkout", {
|
|
2041
|
+
description: err instanceof Error ? err.message : "Please try again."
|
|
2042
|
+
});
|
|
2043
|
+
}
|
|
2184
2044
|
};
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
children: [
|
|
2199
|
-
/* @__PURE__ */
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2240
|
-
/* @__PURE__ */ jsx(RefreshCw, { className: "size-3 mr-1" }),
|
|
2241
|
-
"Update to v",
|
|
2242
|
-
latestVersion
|
|
2243
|
-
] })
|
|
2244
|
-
}
|
|
2245
|
-
),
|
|
2246
|
-
isInstalled ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2247
|
-
/* @__PURE__ */ jsxs(Badge$1, { variant: "secondary", className: "w-full justify-center py-2", children: [
|
|
2248
|
-
/* @__PURE__ */ jsx(Check, { className: "size-3 mr-1" }),
|
|
2249
|
-
"Installed ",
|
|
2250
|
-
installedVersion && `(v${installedVersion})`
|
|
2251
|
-
] }),
|
|
2045
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
2046
|
+
/* @__PURE__ */ jsx("div", { className: "px-3 pt-3 pb-1 shrink-0", children: /* @__PURE__ */ jsxs(
|
|
2047
|
+
"button",
|
|
2048
|
+
{
|
|
2049
|
+
onClick: onBack,
|
|
2050
|
+
className: "flex items-center gap-1.5 text-xs text-muted-foreground hover:text-foreground transition-colors",
|
|
2051
|
+
children: [
|
|
2052
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mynaui:chevron-left", className: "size-3.5" }),
|
|
2053
|
+
"Back"
|
|
2054
|
+
]
|
|
2055
|
+
}
|
|
2056
|
+
) }),
|
|
2057
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto px-3 pb-2", children: [
|
|
2058
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center text-center py-4", children: [
|
|
2059
|
+
/* @__PURE__ */ jsx("div", { className: "size-16 rounded-xl bg-muted flex items-center justify-center overflow-hidden mb-3", children: node.icon ? /* @__PURE__ */ jsx(
|
|
2060
|
+
"img",
|
|
2061
|
+
{
|
|
2062
|
+
src: node.icon,
|
|
2063
|
+
alt: node.name,
|
|
2064
|
+
className: "w-full h-full object-cover"
|
|
2065
|
+
}
|
|
2066
|
+
) : /* @__PURE__ */ jsx("span", { className: "text-2xl font-bold text-muted-foreground", children: node.name.charAt(0).toUpperCase() }) }),
|
|
2067
|
+
/* @__PURE__ */ jsx("h2", { className: "text-base font-semibold text-foreground leading-tight", children: node.name }),
|
|
2068
|
+
(node.authorName || node.publisher?.name) && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground mt-1 flex items-center gap-1", children: [
|
|
2069
|
+
"by ",
|
|
2070
|
+
node.authorName || node.publisher?.name,
|
|
2071
|
+
node.publisher?.isVerified && /* @__PURE__ */ jsx(BadgeCheck, { className: "size-3.5 text-primary" })
|
|
2072
|
+
] })
|
|
2073
|
+
] }),
|
|
2074
|
+
(isInstalled || hasUpdate || node.featured) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-2 mb-4 flex-wrap", children: [
|
|
2075
|
+
hasUpdate && /* @__PURE__ */ jsxs(
|
|
2076
|
+
"span",
|
|
2077
|
+
{
|
|
2078
|
+
className: "inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-semibold",
|
|
2079
|
+
style: {
|
|
2080
|
+
background: "var(--color-status-warning-bgSubtle)",
|
|
2081
|
+
color: "var(--color-status-warning-text)"
|
|
2082
|
+
},
|
|
2083
|
+
children: [
|
|
2084
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mynaui:refresh", className: "size-3" }),
|
|
2085
|
+
"Update available \u2014 v",
|
|
2086
|
+
latestVersion
|
|
2087
|
+
]
|
|
2088
|
+
}
|
|
2089
|
+
),
|
|
2090
|
+
isInstalled && !hasUpdate && /* @__PURE__ */ jsxs(
|
|
2091
|
+
"span",
|
|
2092
|
+
{
|
|
2093
|
+
className: "inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-semibold",
|
|
2094
|
+
style: {
|
|
2095
|
+
background: "var(--color-status-success-bgSubtle)",
|
|
2096
|
+
color: "var(--color-status-success-text)"
|
|
2097
|
+
},
|
|
2098
|
+
children: [
|
|
2252
2099
|
/* @__PURE__ */ jsx(
|
|
2253
|
-
|
|
2100
|
+
"span",
|
|
2254
2101
|
{
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
className: "w-full",
|
|
2258
|
-
onClick: handleUninstallClick,
|
|
2259
|
-
disabled: uninstalling || checkingNodeUsage || removingFromWorkflows,
|
|
2260
|
-
children: uninstalling ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2261
|
-
/* @__PURE__ */ jsx(Loader2, { className: "size-3 mr-1 animate-spin" }),
|
|
2262
|
-
"Uninstalling..."
|
|
2263
|
-
] }) : checkingNodeUsage ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2264
|
-
/* @__PURE__ */ jsx(Loader2, { className: "size-3 mr-1 animate-spin" }),
|
|
2265
|
-
"Checking..."
|
|
2266
|
-
] }) : removingFromWorkflows ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2267
|
-
/* @__PURE__ */ jsx(Loader2, { className: "size-3 mr-1 animate-spin" }),
|
|
2268
|
-
"Removing..."
|
|
2269
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2270
|
-
/* @__PURE__ */ jsx(Trash2, { className: "size-3 mr-1" }),
|
|
2271
|
-
"Uninstall"
|
|
2272
|
-
] })
|
|
2102
|
+
className: "size-1.5 rounded-full",
|
|
2103
|
+
style: { background: "var(--color-status-success-bg)" }
|
|
2273
2104
|
}
|
|
2274
|
-
)
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
className: "w-full justify-center py-2 cursor-pointer hover:bg-primary/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
|
|
2291
|
-
onClick: handlePurchase,
|
|
2292
|
-
children: creatingOrder ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2293
|
-
/* @__PURE__ */ jsx(Loader2, { className: "size-3 mr-1 animate-spin" }),
|
|
2294
|
-
"Creating order..."
|
|
2295
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2296
|
-
/* @__PURE__ */ jsx(DollarSign, { className: "size-3 mr-1" }),
|
|
2297
|
-
"$",
|
|
2298
|
-
node.price?.toFixed(2) || "0.00"
|
|
2299
|
-
] })
|
|
2300
|
-
}
|
|
2301
|
-
)
|
|
2105
|
+
),
|
|
2106
|
+
"Installed",
|
|
2107
|
+
installedVersion ? ` v${installedVersion}` : ""
|
|
2108
|
+
]
|
|
2109
|
+
}
|
|
2110
|
+
),
|
|
2111
|
+
node.featured && !isInstalled && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-semibold bg-primary/10 text-primary", children: "Featured" })
|
|
2112
|
+
] }),
|
|
2113
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-4 text-xs text-muted-foreground mb-4", children: [
|
|
2114
|
+
node.rating != null && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
2115
|
+
/* @__PURE__ */ jsx(Star, { className: "size-3 fill-yellow-400 text-yellow-400" }),
|
|
2116
|
+
node.rating.toFixed(1),
|
|
2117
|
+
/* @__PURE__ */ jsxs("span", { className: "opacity-60", children: [
|
|
2118
|
+
"(",
|
|
2119
|
+
node.reviewCount ?? 0,
|
|
2120
|
+
")"
|
|
2302
2121
|
] })
|
|
2303
2122
|
] }),
|
|
2304
|
-
|
|
2305
|
-
|
|
2123
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
2124
|
+
/* @__PURE__ */ jsx(Download, { className: "size-3" }),
|
|
2125
|
+
formatDownloads(node.downloads ?? 0)
|
|
2126
|
+
] }),
|
|
2127
|
+
latestVersion && /* @__PURE__ */ jsxs("span", { className: "opacity-80", children: [
|
|
2128
|
+
"v",
|
|
2129
|
+
latestVersion
|
|
2130
|
+
] })
|
|
2131
|
+
] }),
|
|
2132
|
+
node.description && /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground/80 leading-relaxed mb-4", children: node.description }),
|
|
2133
|
+
node.publisher && /* @__PURE__ */ jsxs("div", { className: "mb-4 p-2.5 rounded-lg bg-muted/50 flex items-center gap-2", children: [
|
|
2134
|
+
/* @__PURE__ */ jsx("div", { className: "size-6 rounded bg-muted flex items-center justify-center shrink-0", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-bold text-muted-foreground", children: node.publisher.name.charAt(0) }) }),
|
|
2135
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-foreground font-medium flex-1 min-w-0 truncate", children: node.publisher.name }),
|
|
2136
|
+
node.publisher.isVerified && /* @__PURE__ */ jsx(BadgeCheck, { className: "size-4 text-primary shrink-0" })
|
|
2137
|
+
] }),
|
|
2138
|
+
node.license && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground mb-4", children: [
|
|
2139
|
+
"License:",
|
|
2140
|
+
" ",
|
|
2141
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground/70", children: node.license })
|
|
2142
|
+
] }),
|
|
2143
|
+
node.compatibleProducts && node.compatibleProducts.length > 0 && /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
|
|
2144
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mb-1.5", children: "Compatible with" }),
|
|
2145
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: node.compatibleProducts.map((p) => /* @__PURE__ */ jsx(
|
|
2146
|
+
"span",
|
|
2306
2147
|
{
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
]
|
|
2317
|
-
}
|
|
2318
|
-
);
|
|
2319
|
-
}
|
|
2320
|
-
function StoreNodesGrid({
|
|
2321
|
-
filterTab,
|
|
2322
|
-
searchTerm,
|
|
2323
|
-
onNodeClick
|
|
2324
|
-
}) {
|
|
2325
|
-
const { products, loading, hasMore, fetchMore, error } = useStoreNodes({
|
|
2326
|
-
filter: {
|
|
2327
|
-
search: searchTerm || void 0,
|
|
2328
|
-
type: "NODE",
|
|
2329
|
-
compatibleWith: "fluidgrids"
|
|
2330
|
-
},
|
|
2331
|
-
sortBy: "DOWNLOADS",
|
|
2332
|
-
limit: 20
|
|
2333
|
-
});
|
|
2334
|
-
const { installedAppIds, installationsMap } = useInstalledNodes();
|
|
2335
|
-
console.log("[StoreNodesGrid] Debug:", {
|
|
2336
|
-
products,
|
|
2337
|
-
productsLength: products?.length,
|
|
2338
|
-
loading,
|
|
2339
|
-
error,
|
|
2340
|
-
filterTab,
|
|
2341
|
-
searchTerm
|
|
2342
|
-
});
|
|
2343
|
-
const filteredProducts = useMemo(() => {
|
|
2344
|
-
if (!products) return [];
|
|
2345
|
-
switch (filterTab) {
|
|
2346
|
-
case "installed":
|
|
2347
|
-
return products.filter((p) => installedAppIds.has(p.id));
|
|
2348
|
-
case "all":
|
|
2349
|
-
default:
|
|
2350
|
-
return products;
|
|
2351
|
-
}
|
|
2352
|
-
}, [products, filterTab, installedAppIds]);
|
|
2353
|
-
if (loading && filteredProducts.length === 0) {
|
|
2354
|
-
return /* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsx(Loader2, { className: "size-8 animate-spin text-muted-foreground" }) });
|
|
2355
|
-
}
|
|
2356
|
-
if (error) {
|
|
2357
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center p-8 text-center", children: [
|
|
2358
|
-
/* @__PURE__ */ jsx("p", { className: "text-lg font-medium text-destructive", children: "Error loading nodes" }),
|
|
2359
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: error.message || "Failed to fetch nodes from store" }),
|
|
2360
|
-
/* @__PURE__ */ jsx(
|
|
2148
|
+
className: "px-2 py-0.5 rounded-full text-xs bg-muted text-muted-foreground",
|
|
2149
|
+
children: p
|
|
2150
|
+
},
|
|
2151
|
+
p
|
|
2152
|
+
)) })
|
|
2153
|
+
] })
|
|
2154
|
+
] }),
|
|
2155
|
+
/* @__PURE__ */ jsxs("div", { className: "shrink-0 px-3 pb-3 pt-2 border-t border-border/50 flex flex-col gap-2", children: [
|
|
2156
|
+
hasUpdate && /* @__PURE__ */ jsx(
|
|
2361
2157
|
Button,
|
|
2362
2158
|
{
|
|
2159
|
+
size: "sm",
|
|
2363
2160
|
variant: "outline",
|
|
2364
|
-
className: "
|
|
2365
|
-
onClick:
|
|
2366
|
-
|
|
2161
|
+
className: "w-full",
|
|
2162
|
+
onClick: handleUpdate,
|
|
2163
|
+
disabled: isUpdating,
|
|
2164
|
+
children: isUpdating ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2165
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-3.5 mr-1.5 animate-spin" }),
|
|
2166
|
+
"Updating..."
|
|
2167
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2168
|
+
/* @__PURE__ */ jsx(RefreshCw, { className: "size-3.5 mr-1.5" }),
|
|
2169
|
+
"Update to v",
|
|
2170
|
+
latestVersion
|
|
2171
|
+
] })
|
|
2367
2172
|
}
|
|
2368
|
-
)
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
if (!loading && filteredProducts.length === 0) {
|
|
2372
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center p-8 text-center space-y-4", children: [
|
|
2373
|
-
/* @__PURE__ */ jsx("p", { className: "text-lg font-medium text-muted-foreground", children: "No nodes found" }),
|
|
2374
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Try adjusting your search or filters" }),
|
|
2375
|
-
/* @__PURE__ */ jsxs("div", { className: "mt-4 p-4 bg-muted rounded-lg text-left text-xs font-mono max-w-md", children: [
|
|
2376
|
-
/* @__PURE__ */ jsx("div", { className: "font-bold mb-2", children: "Debug Info:" }),
|
|
2377
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2378
|
-
"Total products: ",
|
|
2379
|
-
products?.length || 0
|
|
2380
|
-
] }),
|
|
2381
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2382
|
-
"Filter tab: ",
|
|
2383
|
-
filterTab
|
|
2384
|
-
] }),
|
|
2385
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2386
|
-
'Search term: "',
|
|
2387
|
-
searchTerm,
|
|
2388
|
-
'"'
|
|
2389
|
-
] }),
|
|
2390
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2391
|
-
"Loading: ",
|
|
2392
|
-
loading ? "yes" : "no"
|
|
2393
|
-
] }),
|
|
2394
|
-
/* @__PURE__ */ jsx("div", { children: "Error: none" }),
|
|
2395
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2396
|
-
"Installed count: ",
|
|
2397
|
-
installedAppIds.size
|
|
2398
|
-
] })
|
|
2399
|
-
] })
|
|
2400
|
-
] });
|
|
2401
|
-
}
|
|
2402
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto bg-background", children: [
|
|
2403
|
-
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6 p-6", children: filteredProducts.map((node) => {
|
|
2404
|
-
const installation = installationsMap.get(node.id);
|
|
2405
|
-
return /* @__PURE__ */ jsx(
|
|
2406
|
-
StoreNodeCard,
|
|
2173
|
+
),
|
|
2174
|
+
isInstalled ? /* @__PURE__ */ jsx(
|
|
2175
|
+
Button,
|
|
2407
2176
|
{
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2177
|
+
size: "sm",
|
|
2178
|
+
variant: "destructive",
|
|
2179
|
+
className: "w-full",
|
|
2180
|
+
onClick: handleUninstallClick,
|
|
2181
|
+
disabled: uninstalling || checkingNodeUsage || removingFromWorkflows,
|
|
2182
|
+
children: uninstalling || removingFromWorkflows ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2183
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-3.5 mr-1.5 animate-spin" }),
|
|
2184
|
+
"Uninstalling..."
|
|
2185
|
+
] }) : checkingNodeUsage ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2186
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-3.5 mr-1.5 animate-spin" }),
|
|
2187
|
+
"Checking usage..."
|
|
2188
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2189
|
+
/* @__PURE__ */ jsx(Trash2, { className: "size-3.5 mr-1.5" }),
|
|
2190
|
+
"Uninstall"
|
|
2191
|
+
] })
|
|
2192
|
+
}
|
|
2193
|
+
) : canInstall ? /* @__PURE__ */ jsx(
|
|
2194
|
+
Button,
|
|
2195
|
+
{
|
|
2196
|
+
size: "sm",
|
|
2197
|
+
className: "w-full",
|
|
2198
|
+
onClick: handleInstall,
|
|
2199
|
+
disabled: isInstalling,
|
|
2200
|
+
children: isInstalling ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2201
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-3.5 mr-1.5 animate-spin" }),
|
|
2202
|
+
"Installing..."
|
|
2203
|
+
] }) : "Install"
|
|
2204
|
+
}
|
|
2205
|
+
) : /* @__PURE__ */ jsx(
|
|
2206
|
+
Button,
|
|
2207
|
+
{
|
|
2208
|
+
size: "sm",
|
|
2209
|
+
className: "w-full",
|
|
2210
|
+
onClick: handlePurchase,
|
|
2211
|
+
disabled: creatingOrder,
|
|
2212
|
+
children: creatingOrder ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2213
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-3.5 mr-1.5 animate-spin" }),
|
|
2214
|
+
"Creating order..."
|
|
2215
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2216
|
+
/* @__PURE__ */ jsx(DollarSign, { className: "size-3.5 mr-1.5" }),
|
|
2217
|
+
"$",
|
|
2218
|
+
node.price?.toFixed(2) ?? "0.00"
|
|
2219
|
+
] })
|
|
2220
|
+
}
|
|
2221
|
+
)
|
|
2222
|
+
] }),
|
|
2223
|
+
showUninstallDialog && /* @__PURE__ */ jsx(
|
|
2224
|
+
UninstallNodeDialog,
|
|
2225
|
+
{
|
|
2226
|
+
nodeName: node.name,
|
|
2227
|
+
nodeType: node.name,
|
|
2228
|
+
isUsed: nodeUsage.isUsed,
|
|
2229
|
+
workflows: nodeUsage.workflows,
|
|
2230
|
+
loading: uninstalling || removingFromWorkflows,
|
|
2231
|
+
onConfirm: handleConfirmUninstall,
|
|
2232
|
+
onCancel: () => setShowUninstallDialog(false)
|
|
2233
|
+
}
|
|
2234
|
+
)
|
|
2421
2235
|
] });
|
|
2422
2236
|
}
|
|
2423
|
-
function
|
|
2424
|
-
const [
|
|
2425
|
-
const [
|
|
2426
|
-
const [
|
|
2427
|
-
null
|
|
2428
|
-
);
|
|
2429
|
-
const { refetch: refetchStoreNodes } = useStoreNodes({
|
|
2430
|
-
filter: {
|
|
2431
|
-
type: "NODE",
|
|
2432
|
-
compatibleWith: "fluidgrids"
|
|
2433
|
-
}
|
|
2434
|
-
});
|
|
2435
|
-
const { refetch: refetchInstalledNodes } = useInstalledNodes();
|
|
2237
|
+
function StoreBrowsePanel() {
|
|
2238
|
+
const [view, setView] = useState({ type: "categories" });
|
|
2239
|
+
const [globalSearch, setGlobalSearch] = useState("");
|
|
2240
|
+
const [, setNodesReady] = useState(isNodeConfigsInitialized);
|
|
2436
2241
|
useEffect(() => {
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2242
|
+
void ensureNodeConfigsLoaded().then(() => setNodesReady(true));
|
|
2243
|
+
}, []);
|
|
2244
|
+
const openCategory = useCallback((category) => {
|
|
2245
|
+
setView({ type: "category-nodes", category });
|
|
2246
|
+
setGlobalSearch("");
|
|
2247
|
+
}, []);
|
|
2248
|
+
const openNodeDetail = useCallback((node) => {
|
|
2249
|
+
setView((prev) => ({
|
|
2250
|
+
type: "node-detail",
|
|
2251
|
+
node,
|
|
2252
|
+
from: prev.type === "node-detail" ? prev.from : prev
|
|
2253
|
+
}));
|
|
2254
|
+
}, []);
|
|
2255
|
+
const goBack = useCallback(() => {
|
|
2256
|
+
setView((prev) => {
|
|
2257
|
+
if (prev.type === "node-detail") return prev.from;
|
|
2258
|
+
return { type: "categories" };
|
|
2442
2259
|
});
|
|
2443
2260
|
}, []);
|
|
2444
|
-
return /* @__PURE__ */ jsxs(
|
|
2445
|
-
/* @__PURE__ */
|
|
2446
|
-
|
|
2447
|
-
{
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2261
|
+
return /* @__PURE__ */ jsxs(SidebarPanelWrapper, { children: [
|
|
2262
|
+
view.type === "categories" && /* @__PURE__ */ jsxs("div", { className: "px-4 pt-4 pb-2 shrink-0 flex items-center gap-2", children: [
|
|
2263
|
+
/* @__PURE__ */ jsx("div", { className: "size-7 flex items-center justify-center rounded-lg bg-primary", children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:store", className: "size-4 text-white" }) }),
|
|
2264
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2265
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground leading-tight", children: "Node Store" }),
|
|
2266
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Browse & install workflow nodes" })
|
|
2267
|
+
] })
|
|
2268
|
+
] }),
|
|
2269
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-hidden flex flex-col", children: [
|
|
2270
|
+
view.type === "categories" && /* @__PURE__ */ jsx(
|
|
2271
|
+
StoreCategoryList,
|
|
2272
|
+
{
|
|
2273
|
+
searchTerm: globalSearch,
|
|
2274
|
+
onSearchChange: setGlobalSearch,
|
|
2275
|
+
onSelectCategory: openCategory,
|
|
2276
|
+
onSelectNode: openNodeDetail
|
|
2277
|
+
}
|
|
2278
|
+
),
|
|
2279
|
+
view.type === "category-nodes" && /* @__PURE__ */ jsx(
|
|
2280
|
+
StoreCategoryNodes,
|
|
2281
|
+
{
|
|
2282
|
+
category: view.category,
|
|
2283
|
+
onBack: goBack,
|
|
2284
|
+
onSelectNode: openNodeDetail
|
|
2285
|
+
}
|
|
2286
|
+
),
|
|
2287
|
+
view.type === "node-detail" && /* @__PURE__ */ jsx(StoreNodeDetail, { node: view.node, onBack: goBack })
|
|
2288
|
+
] })
|
|
2462
2289
|
] });
|
|
2463
2290
|
}
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2291
|
+
|
|
2292
|
+
// src/builder/components/flow-builder/components/blocks/sidebar/constants/panels.tsx
|
|
2293
|
+
var PANEL_COMPONENTS = {
|
|
2294
|
+
"node-properties": NodePropertiesPanel,
|
|
2295
|
+
"store-browse": StoreBrowsePanel,
|
|
2296
|
+
none: () => null
|
|
2297
|
+
};
|
|
2298
|
+
function SwitchSidebarPanel({ active }) {
|
|
2299
|
+
const PanelComponent = PANEL_COMPONENTS[active];
|
|
2300
|
+
return PanelComponent ? /* @__PURE__ */ jsx(PanelComponent, {}) : null;
|
|
2301
|
+
}
|
|
2302
|
+
function SidebarButtonItem({
|
|
2303
|
+
children,
|
|
2304
|
+
className,
|
|
2305
|
+
active,
|
|
2306
|
+
...props
|
|
2307
|
+
}) {
|
|
2308
|
+
return /* @__PURE__ */ jsx(
|
|
2309
|
+
Button$1,
|
|
2467
2310
|
{
|
|
2468
|
-
size: "
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2311
|
+
size: "icon",
|
|
2312
|
+
type: "button",
|
|
2313
|
+
variant: active ? "default" : "ghost",
|
|
2314
|
+
className: cn$1(
|
|
2315
|
+
"size-8 flex items-center justify-center",
|
|
2316
|
+
className
|
|
2317
|
+
),
|
|
2318
|
+
...props,
|
|
2319
|
+
children
|
|
2477
2320
|
}
|
|
2478
|
-
)
|
|
2321
|
+
);
|
|
2479
2322
|
}
|
|
2323
|
+
var Card = forwardRef(
|
|
2324
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2325
|
+
"div",
|
|
2326
|
+
{
|
|
2327
|
+
ref,
|
|
2328
|
+
className: cn(
|
|
2329
|
+
"rounded-lg border bg-card text-card-foreground shadow-sm transition-all duration-200 ease-out hover:shadow-md",
|
|
2330
|
+
className
|
|
2331
|
+
),
|
|
2332
|
+
...props
|
|
2333
|
+
}
|
|
2334
|
+
)
|
|
2335
|
+
);
|
|
2336
|
+
Card.displayName = "Card";
|
|
2337
|
+
var CardHeader = forwardRef(
|
|
2338
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2339
|
+
"div",
|
|
2340
|
+
{
|
|
2341
|
+
ref,
|
|
2342
|
+
className: cn("flex flex-col space-y-1.5 p-6", className),
|
|
2343
|
+
...props
|
|
2344
|
+
}
|
|
2345
|
+
)
|
|
2346
|
+
);
|
|
2347
|
+
CardHeader.displayName = "CardHeader";
|
|
2348
|
+
var CardTitle = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2349
|
+
"h3",
|
|
2350
|
+
{
|
|
2351
|
+
ref,
|
|
2352
|
+
className: cn(
|
|
2353
|
+
"text-2xl font-semibold leading-none tracking-tight",
|
|
2354
|
+
className
|
|
2355
|
+
),
|
|
2356
|
+
...props
|
|
2357
|
+
}
|
|
2358
|
+
));
|
|
2359
|
+
CardTitle.displayName = "CardTitle";
|
|
2360
|
+
var CardDescription = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2361
|
+
"p",
|
|
2362
|
+
{
|
|
2363
|
+
ref,
|
|
2364
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
2365
|
+
...props
|
|
2366
|
+
}
|
|
2367
|
+
));
|
|
2368
|
+
CardDescription.displayName = "CardDescription";
|
|
2369
|
+
var CardContent = forwardRef(
|
|
2370
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props })
|
|
2371
|
+
);
|
|
2372
|
+
CardContent.displayName = "CardContent";
|
|
2373
|
+
var CardFooter = forwardRef(
|
|
2374
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2375
|
+
"div",
|
|
2376
|
+
{
|
|
2377
|
+
ref,
|
|
2378
|
+
className: cn("flex items-center p-6 pt-0", className),
|
|
2379
|
+
...props
|
|
2380
|
+
}
|
|
2381
|
+
)
|
|
2382
|
+
);
|
|
2383
|
+
CardFooter.displayName = "CardFooter";
|
|
2480
2384
|
function formatNumber(count2) {
|
|
2481
2385
|
if (count2 >= 1e6) {
|
|
2482
2386
|
return `${(count2 / 1e6).toFixed(1)}M`;
|
|
@@ -2768,7 +2672,7 @@ function TemplatesModal({
|
|
|
2768
2672
|
) });
|
|
2769
2673
|
}
|
|
2770
2674
|
var LazyTemplateConfigurationModal = lazy(
|
|
2771
|
-
() => import('./TemplateConfigurationModal-
|
|
2675
|
+
() => import('./TemplateConfigurationModal-FPQR7W4M.js').then((m) => ({
|
|
2772
2676
|
default: m.TemplateConfigurationModal
|
|
2773
2677
|
}))
|
|
2774
2678
|
);
|
|
@@ -2776,7 +2680,6 @@ function DesktopSidebarFragment({
|
|
|
2776
2680
|
activePanel,
|
|
2777
2681
|
setActivePanel
|
|
2778
2682
|
}) {
|
|
2779
|
-
const [storeModalOpen, setStoreModalOpen] = useState(false);
|
|
2780
2683
|
const [templatesModalOpen, setTemplatesModalOpen] = useState(false);
|
|
2781
2684
|
const [configModalOpen, setConfigModalOpen] = useState(false);
|
|
2782
2685
|
const [configTemplate, setConfigTemplate] = useState(
|
|
@@ -2789,7 +2692,7 @@ function DesktopSidebarFragment({
|
|
|
2789
2692
|
const handleUseTemplate = useCallback(
|
|
2790
2693
|
async (template) => {
|
|
2791
2694
|
try {
|
|
2792
|
-
const { useImportWorkflowTemplate: useImportWorkflowTemplate2 } = await import('./useImportWorkflowTemplate-
|
|
2695
|
+
const { useImportWorkflowTemplate: useImportWorkflowTemplate2 } = await import('./useImportWorkflowTemplate-P62I2ADG.js');
|
|
2793
2696
|
const { useTemplateDetail: useTemplateDetail2 } = await import('./useTemplateDetail-NK63V3PC.js');
|
|
2794
2697
|
toast.loading("Loading template...", { id: "template-load" });
|
|
2795
2698
|
const { getGlobalStoreClient } = await import('./global-client-OW43ZRDR.js');
|
|
@@ -3011,18 +2914,6 @@ function DesktopSidebarFragment({
|
|
|
3011
2914
|
return /* @__PURE__ */ jsxs("div", { className: "relative max-w-sm w-fit flex shrink-0 divide-x divide-card-foreground/10", children: [
|
|
3012
2915
|
activePanel !== "none" && /* @__PURE__ */ jsx("div", { className: "min-w-xs grow bg-card", children: /* @__PURE__ */ jsx(SwitchSidebarPanel, { active: activePanel }) }),
|
|
3013
2916
|
/* @__PURE__ */ jsx("div", { className: "shrink-0 bg-card p-1.5", children: /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col gap-2", children: [
|
|
3014
|
-
/* @__PURE__ */ jsx(
|
|
3015
|
-
SidebarButtonItem,
|
|
3016
|
-
{
|
|
3017
|
-
active: activePanel === "available-nodes",
|
|
3018
|
-
onClick: () => setActivePanel(
|
|
3019
|
-
activePanel === "available-nodes" ? "none" : "available-nodes"
|
|
3020
|
-
),
|
|
3021
|
-
title: "Available Nodes",
|
|
3022
|
-
children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:grid", className: "size-5" })
|
|
3023
|
-
}
|
|
3024
|
-
),
|
|
3025
|
-
/* @__PURE__ */ jsx("div", { className: "mx-auto h-px w-4 bg-card-foreground/10" }),
|
|
3026
2917
|
/* @__PURE__ */ jsx(
|
|
3027
2918
|
SidebarButtonItem,
|
|
3028
2919
|
{
|
|
@@ -3038,10 +2929,12 @@ function DesktopSidebarFragment({
|
|
|
3038
2929
|
/* @__PURE__ */ jsx(
|
|
3039
2930
|
SidebarButtonItem,
|
|
3040
2931
|
{
|
|
3041
|
-
active:
|
|
3042
|
-
onClick: () =>
|
|
2932
|
+
active: activePanel === "store-browse",
|
|
2933
|
+
onClick: () => setActivePanel(
|
|
2934
|
+
activePanel === "store-browse" ? "none" : "store-browse"
|
|
2935
|
+
),
|
|
3043
2936
|
title: "Browse custom nodes from the store",
|
|
3044
|
-
children: /* @__PURE__ */ jsx(
|
|
2937
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:store", className: "size-5" })
|
|
3045
2938
|
}
|
|
3046
2939
|
),
|
|
3047
2940
|
/* @__PURE__ */ jsx(
|
|
@@ -3054,7 +2947,6 @@ function DesktopSidebarFragment({
|
|
|
3054
2947
|
}
|
|
3055
2948
|
)
|
|
3056
2949
|
] }) }),
|
|
3057
|
-
/* @__PURE__ */ jsx(StoreNodesModal, { open: storeModalOpen, onOpenChange: setStoreModalOpen }),
|
|
3058
2950
|
/* @__PURE__ */ jsx(
|
|
3059
2951
|
TemplatesModal,
|
|
3060
2952
|
{
|
|
@@ -9215,6 +9107,29 @@ var useAddNodeOnEdgeDropStore = create()(
|
|
|
9215
9107
|
}
|
|
9216
9108
|
})
|
|
9217
9109
|
);
|
|
9110
|
+
function useInsertNode() {
|
|
9111
|
+
const { addNodes, screenToFlowPosition, getNodes, updateNode } = useReactFlow();
|
|
9112
|
+
return useCallback(
|
|
9113
|
+
(type, pos) => {
|
|
9114
|
+
const _pos = pos || screenToFlowPosition({
|
|
9115
|
+
x: window.innerWidth / 2,
|
|
9116
|
+
y: window.innerHeight / 2
|
|
9117
|
+
});
|
|
9118
|
+
getNodes().forEach((node) => {
|
|
9119
|
+
if (node.selected) {
|
|
9120
|
+
updateNode(node.id, { selected: false });
|
|
9121
|
+
}
|
|
9122
|
+
});
|
|
9123
|
+
const newNode = createNodeWithDefaultData(type, {
|
|
9124
|
+
position: _pos,
|
|
9125
|
+
selected: true
|
|
9126
|
+
});
|
|
9127
|
+
addNodes(newNode);
|
|
9128
|
+
return newNode;
|
|
9129
|
+
},
|
|
9130
|
+
[screenToFlowPosition, getNodes, addNodes, updateNode]
|
|
9131
|
+
);
|
|
9132
|
+
}
|
|
9218
9133
|
function useAddNodeOnEdgeDrop() {
|
|
9219
9134
|
const [
|
|
9220
9135
|
dropPosition,
|
|
@@ -11344,7 +11259,7 @@ function WorkflowItem({
|
|
|
11344
11259
|
edges: [],
|
|
11345
11260
|
nodes: [],
|
|
11346
11261
|
sidebar: {
|
|
11347
|
-
active: "
|
|
11262
|
+
active: "store-browse",
|
|
11348
11263
|
panels: {
|
|
11349
11264
|
nodeProperties: {
|
|
11350
11265
|
selectedNode: null
|
|
@@ -11490,5 +11405,5 @@ function WorkflowBuilder() {
|
|
|
11490
11405
|
}
|
|
11491
11406
|
|
|
11492
11407
|
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, TemplateCard, WorkflowBuilder, useWorkflowTemplates };
|
|
11493
|
-
//# sourceMappingURL=chunk-
|
|
11494
|
-
//# sourceMappingURL=chunk-
|
|
11408
|
+
//# sourceMappingURL=chunk-TYOU6RYA.js.map
|
|
11409
|
+
//# sourceMappingURL=chunk-TYOU6RYA.js.map
|