@burdenoff/fluidgrids-fe-sdk 2026.728.1 → 2026.730.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/ExecutionDetailPage-H2KAEHLX.js +8 -0
- package/dist/{ExecutionDetailPage-G4FTQ5AF.js.map → ExecutionDetailPage-H2KAEHLX.js.map} +1 -1
- package/dist/ExecutionsListPage-ONF5IUB4.js +8 -0
- package/dist/{ExecutionsListPage-AAMQIVJS.js.map → ExecutionsListPage-ONF5IUB4.js.map} +1 -1
- package/dist/{WorkflowBuilder-2QYBWEWO.js → WorkflowBuilder-CLIMJZPI.js} +6 -6
- package/dist/{WorkflowBuilder-2QYBWEWO.js.map → WorkflowBuilder-CLIMJZPI.js.map} +1 -1
- package/dist/WorkflowsList-ZNSFZMAQ.js +10 -0
- package/dist/{WorkflowsList-IKUTWG7U.js.map → WorkflowsList-ZNSFZMAQ.js.map} +1 -1
- package/dist/{blocks-7Q5XRFI7.js → blocks-M44L2H7I.js} +4 -4
- package/dist/{blocks-7Q5XRFI7.js.map → blocks-M44L2H7I.js.map} +1 -1
- package/dist/{chunk-47457KC3.js → chunk-42PCKNPK.js} +3 -3
- package/dist/{chunk-47457KC3.js.map → chunk-42PCKNPK.js.map} +1 -1
- package/dist/{chunk-U2OJNTKM.js → chunk-DZTLVUGS.js} +7 -7
- package/dist/{chunk-U2OJNTKM.js.map → chunk-DZTLVUGS.js.map} +1 -1
- package/dist/{chunk-3ZCTYLHL.js → chunk-ECX7WKZ3.js} +421 -40
- package/dist/chunk-ECX7WKZ3.js.map +1 -0
- package/dist/{chunk-3M2I2ITB.js → chunk-EPFS7HOM.js} +169 -57
- package/dist/chunk-EPFS7HOM.js.map +1 -0
- package/dist/{chunk-Y6U32527.js → chunk-GWO5RZQX.js} +4 -4
- package/dist/{chunk-Y6U32527.js.map → chunk-GWO5RZQX.js.map} +1 -1
- package/dist/{chunk-H7WSQN2I.js → chunk-IU65EQOS.js} +62 -3
- package/dist/chunk-IU65EQOS.js.map +1 -0
- package/dist/{chunk-LNY6ATSV.js → chunk-JTET2M65.js} +3 -3
- package/dist/{chunk-LNY6ATSV.js.map → chunk-JTET2M65.js.map} +1 -1
- package/dist/chunk-XPUAUQ3I.js +589 -0
- package/dist/chunk-XPUAUQ3I.js.map +1 -0
- package/dist/index.d.ts +207 -1
- package/dist/index.js +29 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/ExecutionDetailPage-G4FTQ5AF.js +0 -8
- package/dist/ExecutionsListPage-AAMQIVJS.js +0 -8
- package/dist/WorkflowsList-IKUTWG7U.js +0 -10
- package/dist/chunk-2WURM2ZA.js +0 -406
- package/dist/chunk-2WURM2ZA.js.map +0 -1
- package/dist/chunk-3M2I2ITB.js.map +0 -1
- package/dist/chunk-3ZCTYLHL.js.map +0 -1
- package/dist/chunk-H7WSQN2I.js.map +0 -1
|
@@ -0,0 +1,589 @@
|
|
|
1
|
+
import { useWorkflowDefinitions, useDuplicateWorkflow, useDeleteWorkflow } from './chunk-42PCKNPK.js';
|
|
2
|
+
import { useFlowStore } from './chunk-KU64CCSV.js';
|
|
3
|
+
import { SdkPermissionButton, FLUIDGRIDS_PERMISSIONS, SdkPermissionGate } from './chunk-UIY2HBWA.js';
|
|
4
|
+
import { config } from './chunk-WWU2O2SR.js';
|
|
5
|
+
import { useState, useMemo } from 'react';
|
|
6
|
+
import { useNavigate } from 'react-router-dom';
|
|
7
|
+
import { v4 } from 'uuid';
|
|
8
|
+
import { Icon } from '@iconify/react';
|
|
9
|
+
import { Button, Badge, Input, IllustratedEmptyState, Skeleton, TooltipProvider, Card, Tooltip, TooltipTrigger, TooltipContent, AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction } from '@burdenoff/fe-libs/ui';
|
|
10
|
+
import { cn } from '@burdenoff/fe-libs/utils';
|
|
11
|
+
import { toast } from 'sonner';
|
|
12
|
+
import { Share2, Copy } from 'lucide-react';
|
|
13
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
14
|
+
|
|
15
|
+
function SharePopup({
|
|
16
|
+
url = window.location.href,
|
|
17
|
+
embedSrc = `${config.fluidgridFrontendUrl}/workflow-view/565201ec-e803-4281-ad39-a135c46daa89/1.0`
|
|
18
|
+
}) {
|
|
19
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
20
|
+
const [width, setWidth] = useState(600);
|
|
21
|
+
const [height, setHeight] = useState(400);
|
|
22
|
+
const [activeTab, setActiveTab] = useState("link");
|
|
23
|
+
const embedCode = `<iframe src="${embedSrc}" width="${width}" height="${height}"></iframe>`;
|
|
24
|
+
const copyToClipboard = (text, message) => {
|
|
25
|
+
navigator.clipboard.writeText(text);
|
|
26
|
+
toast.success(message);
|
|
27
|
+
};
|
|
28
|
+
if (!isOpen) {
|
|
29
|
+
return /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "icon", onClick: () => setIsOpen(true), children: [
|
|
30
|
+
/* @__PURE__ */ jsx(Share2, { className: "h-4 w-4" }),
|
|
31
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "Share" })
|
|
32
|
+
] });
|
|
33
|
+
}
|
|
34
|
+
return /* @__PURE__ */ jsx(
|
|
35
|
+
"div",
|
|
36
|
+
{
|
|
37
|
+
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50",
|
|
38
|
+
onClick: () => setIsOpen(false),
|
|
39
|
+
children: /* @__PURE__ */ jsxs(
|
|
40
|
+
"div",
|
|
41
|
+
{
|
|
42
|
+
className: "bg-card rounded-lg p-6 max-w-md w-full mx-4",
|
|
43
|
+
onClick: (e) => e.stopPropagation(),
|
|
44
|
+
children: [
|
|
45
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center mb-4", children: [
|
|
46
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: "Share" }),
|
|
47
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", onClick: () => setIsOpen(false), children: "\xD7" })
|
|
48
|
+
] }),
|
|
49
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 mb-4", children: [
|
|
50
|
+
/* @__PURE__ */ jsx(
|
|
51
|
+
Button,
|
|
52
|
+
{
|
|
53
|
+
variant: activeTab === "link" ? "default" : "outline",
|
|
54
|
+
size: "sm",
|
|
55
|
+
onClick: () => setActiveTab("link"),
|
|
56
|
+
children: "Share Link"
|
|
57
|
+
}
|
|
58
|
+
),
|
|
59
|
+
/* @__PURE__ */ jsx(
|
|
60
|
+
Button,
|
|
61
|
+
{
|
|
62
|
+
variant: activeTab === "embed" ? "default" : "outline",
|
|
63
|
+
size: "sm",
|
|
64
|
+
onClick: () => setActiveTab("embed"),
|
|
65
|
+
children: "Embed"
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
] }),
|
|
69
|
+
activeTab === "link" && /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
70
|
+
/* @__PURE__ */ jsx(
|
|
71
|
+
"input",
|
|
72
|
+
{
|
|
73
|
+
readOnly: true,
|
|
74
|
+
value: url,
|
|
75
|
+
className: "flex-1 h-9 px-3 rounded-md border bg-background text-sm"
|
|
76
|
+
}
|
|
77
|
+
),
|
|
78
|
+
/* @__PURE__ */ jsx(
|
|
79
|
+
Button,
|
|
80
|
+
{
|
|
81
|
+
size: "sm",
|
|
82
|
+
onClick: () => copyToClipboard(url, "Link copied to clipboard"),
|
|
83
|
+
children: /* @__PURE__ */ jsx(Copy, { className: "h-4 w-4" })
|
|
84
|
+
}
|
|
85
|
+
)
|
|
86
|
+
] }),
|
|
87
|
+
activeTab === "embed" && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
88
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
89
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
90
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Width" }),
|
|
91
|
+
/* @__PURE__ */ jsx(
|
|
92
|
+
"input",
|
|
93
|
+
{
|
|
94
|
+
type: "number",
|
|
95
|
+
value: width,
|
|
96
|
+
onChange: (e) => setWidth(Number(e.target.value)),
|
|
97
|
+
className: "w-full h-9 px-3 rounded-md border bg-background text-sm mt-1"
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
] }),
|
|
101
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
102
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Height" }),
|
|
103
|
+
/* @__PURE__ */ jsx(
|
|
104
|
+
"input",
|
|
105
|
+
{
|
|
106
|
+
type: "number",
|
|
107
|
+
value: height,
|
|
108
|
+
onChange: (e) => setHeight(Number(e.target.value)),
|
|
109
|
+
className: "w-full h-9 px-3 rounded-md border bg-background text-sm mt-1"
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
] })
|
|
113
|
+
] }),
|
|
114
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
115
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: "Embed Code" }),
|
|
116
|
+
/* @__PURE__ */ jsxs("div", { className: "relative mt-1", children: [
|
|
117
|
+
/* @__PURE__ */ jsx(
|
|
118
|
+
"input",
|
|
119
|
+
{
|
|
120
|
+
readOnly: true,
|
|
121
|
+
value: embedCode,
|
|
122
|
+
className: "w-full h-9 px-3 pr-12 rounded-md border bg-background text-sm font-mono"
|
|
123
|
+
}
|
|
124
|
+
),
|
|
125
|
+
/* @__PURE__ */ jsx(
|
|
126
|
+
Button,
|
|
127
|
+
{
|
|
128
|
+
size: "sm",
|
|
129
|
+
className: "absolute right-1 top-1/2 -translate-y-1/2 h-7",
|
|
130
|
+
onClick: () => copyToClipboard(embedCode, "Embed code copied to clipboard"),
|
|
131
|
+
children: /* @__PURE__ */ jsx(Copy, { className: "h-4 w-4" })
|
|
132
|
+
}
|
|
133
|
+
)
|
|
134
|
+
] })
|
|
135
|
+
] })
|
|
136
|
+
] })
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
var STATUS_STYLES = {
|
|
144
|
+
DRAFT: { label: "Draft", dotClass: "bg-muted-foreground/60" },
|
|
145
|
+
ACTIVE: {
|
|
146
|
+
label: "Active",
|
|
147
|
+
dotClass: "bg-[var(--color-status-success-text)]"
|
|
148
|
+
},
|
|
149
|
+
ARCHIVED: { label: "Archived", dotClass: "bg-muted-foreground/30" },
|
|
150
|
+
DEPRECATED: {
|
|
151
|
+
label: "Deprecated",
|
|
152
|
+
dotClass: "bg-[var(--color-status-error-text)]"
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
function relativeTime(iso) {
|
|
156
|
+
if (!iso) return "\u2014";
|
|
157
|
+
const then = new Date(iso).getTime();
|
|
158
|
+
if (Number.isNaN(then)) return "\u2014";
|
|
159
|
+
const mins = Math.floor((Date.now() - then) / 6e4);
|
|
160
|
+
if (mins < 1) return "just now";
|
|
161
|
+
if (mins < 60) return `${mins}m ago`;
|
|
162
|
+
const hrs = Math.floor(mins / 60);
|
|
163
|
+
if (hrs < 24) return `${hrs}h ago`;
|
|
164
|
+
const days = Math.floor(hrs / 24);
|
|
165
|
+
if (days < 7) return `${days}d ago`;
|
|
166
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
167
|
+
month: "short",
|
|
168
|
+
day: "numeric",
|
|
169
|
+
year: "numeric"
|
|
170
|
+
}).format(new Date(then));
|
|
171
|
+
}
|
|
172
|
+
var CardWorkflow = ({
|
|
173
|
+
workflow,
|
|
174
|
+
onUpdateSuccess
|
|
175
|
+
}) => {
|
|
176
|
+
const navigate = useNavigate();
|
|
177
|
+
const resetWorkflow = useFlowStore((s) => s.actions.resetWorkflow);
|
|
178
|
+
const { duplicateWorkflow: duplicateWorkflowMutation } = useDuplicateWorkflow();
|
|
179
|
+
const { deleteWorkflow: deleteWorkflowMutation } = useDeleteWorkflow();
|
|
180
|
+
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
|
|
181
|
+
const [isDeleting, setIsDeleting] = useState(false);
|
|
182
|
+
async function handleDuplicateWorkflow() {
|
|
183
|
+
try {
|
|
184
|
+
resetWorkflow();
|
|
185
|
+
const result = await duplicateWorkflowMutation(
|
|
186
|
+
workflow.workflow_key,
|
|
187
|
+
workflow.version,
|
|
188
|
+
{
|
|
189
|
+
newWorkflowKey: `${workflow.workflow_key}_copy_${Date.now()}`
|
|
190
|
+
}
|
|
191
|
+
);
|
|
192
|
+
if (result?.success && result.workflow) {
|
|
193
|
+
navigate(
|
|
194
|
+
`../workflow/${result.workflow.workflowKey}/${result.workflow.version}`
|
|
195
|
+
);
|
|
196
|
+
} else {
|
|
197
|
+
throw new Error(result?.message || "Failed to duplicate workflow");
|
|
198
|
+
}
|
|
199
|
+
} catch (error) {
|
|
200
|
+
console.error("Error duplicating workflow:", error);
|
|
201
|
+
toast.error(
|
|
202
|
+
`Error duplicating workflow: ${error instanceof Error ? error.message : String(error)}`
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const handleDeleteWorkflow = async () => {
|
|
207
|
+
if (!workflow.workflow_key) {
|
|
208
|
+
console.error("Workflow ID is required to delete.");
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
setIsDeleting(true);
|
|
212
|
+
try {
|
|
213
|
+
const success = await deleteWorkflowMutation(workflow.workflow_key);
|
|
214
|
+
if (success) {
|
|
215
|
+
setShowDeleteDialog(false);
|
|
216
|
+
}
|
|
217
|
+
} catch (error) {
|
|
218
|
+
console.error("Error deleting workflow:", error);
|
|
219
|
+
toast.error(
|
|
220
|
+
`Error deleting workflow: ${error instanceof Error ? error.message : String(error)}`
|
|
221
|
+
);
|
|
222
|
+
} finally {
|
|
223
|
+
setIsDeleting(false);
|
|
224
|
+
setShowDeleteDialog(false);
|
|
225
|
+
onUpdateSuccess();
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
const handleOnEdit = () => {
|
|
229
|
+
navigate("../workflow/" + workflow.workflow_key + "/" + workflow.version);
|
|
230
|
+
};
|
|
231
|
+
const handleCardClick = (e) => {
|
|
232
|
+
const el = e.target;
|
|
233
|
+
if (el.closest("button, a, input, [role='dialog'], .fixed")) return;
|
|
234
|
+
handleOnEdit();
|
|
235
|
+
};
|
|
236
|
+
const statusInfo = STATUS_STYLES[workflow.status ?? "DRAFT"] ?? STATUS_STYLES.DRAFT;
|
|
237
|
+
const updatedExact = workflow.updated_at ? new Date(workflow.updated_at).toLocaleString() : void 0;
|
|
238
|
+
return /* @__PURE__ */ jsxs(TooltipProvider, { children: [
|
|
239
|
+
/* @__PURE__ */ jsxs(
|
|
240
|
+
Card,
|
|
241
|
+
{
|
|
242
|
+
role: "button",
|
|
243
|
+
tabIndex: 0,
|
|
244
|
+
"aria-label": `Open workflow ${workflow.name}`,
|
|
245
|
+
onClick: handleCardClick,
|
|
246
|
+
onKeyDown: (e) => {
|
|
247
|
+
if (e.target === e.currentTarget && (e.key === "Enter" || e.key === " ")) {
|
|
248
|
+
e.preventDefault();
|
|
249
|
+
handleOnEdit();
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
className: cn(
|
|
253
|
+
"group relative flex min-h-44 cursor-pointer flex-col gap-0 rounded-xl border-border bg-card p-0",
|
|
254
|
+
"transition-all duration-150 hover:-translate-y-0.5 hover:border-primary/40 hover:shadow-lg",
|
|
255
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50"
|
|
256
|
+
),
|
|
257
|
+
children: [
|
|
258
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 items-start gap-3 p-4", children: [
|
|
259
|
+
/* @__PURE__ */ jsx("div", { className: "flex size-9 shrink-0 items-center justify-center rounded-lg border border-primary/20 bg-primary/10 text-primary", children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:transit-connection-variant", className: "size-5" }) }),
|
|
260
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
261
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
262
|
+
/* @__PURE__ */ jsx("h3", { className: "truncate font-semibold leading-6 text-card-foreground", children: workflow?.name }),
|
|
263
|
+
/* @__PURE__ */ jsxs("span", { className: "mt-0.5 inline-flex shrink-0 items-center gap-1.5 rounded-full border border-border px-2 py-0.5 text-[11px] font-medium text-muted-foreground", children: [
|
|
264
|
+
/* @__PURE__ */ jsx(
|
|
265
|
+
"span",
|
|
266
|
+
{
|
|
267
|
+
className: cn("size-1.5 rounded-full", statusInfo.dotClass)
|
|
268
|
+
}
|
|
269
|
+
),
|
|
270
|
+
statusInfo.label
|
|
271
|
+
] })
|
|
272
|
+
] }),
|
|
273
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 line-clamp-2 text-xs leading-snug text-muted-foreground", children: workflow.description || "No description" })
|
|
274
|
+
] })
|
|
275
|
+
] }),
|
|
276
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-t border-border px-4 py-1.5", children: [
|
|
277
|
+
/* @__PURE__ */ jsxs(
|
|
278
|
+
"div",
|
|
279
|
+
{
|
|
280
|
+
className: "flex min-w-0 items-center gap-1.5 text-[11px] text-muted-foreground",
|
|
281
|
+
title: updatedExact,
|
|
282
|
+
children: [
|
|
283
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:clock-outline", className: "size-3.5 shrink-0" }),
|
|
284
|
+
/* @__PURE__ */ jsxs("span", { className: "truncate", children: [
|
|
285
|
+
"Updated ",
|
|
286
|
+
relativeTime(workflow.updated_at)
|
|
287
|
+
] }),
|
|
288
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xB7" }),
|
|
289
|
+
/* @__PURE__ */ jsxs("span", { className: "shrink-0 font-mono", children: [
|
|
290
|
+
workflow.version,
|
|
291
|
+
workflow.alias ? ` (${workflow.alias})` : ""
|
|
292
|
+
] }),
|
|
293
|
+
workflow.total_versions && workflow.total_versions > 1 ? /* @__PURE__ */ jsxs("span", { className: "shrink-0", children: [
|
|
294
|
+
"\xB7 ",
|
|
295
|
+
workflow.total_versions,
|
|
296
|
+
" versions"
|
|
297
|
+
] }) : null
|
|
298
|
+
]
|
|
299
|
+
}
|
|
300
|
+
),
|
|
301
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-0.5 opacity-60 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100", children: [
|
|
302
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
303
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
304
|
+
Button,
|
|
305
|
+
{
|
|
306
|
+
variant: "ghost",
|
|
307
|
+
size: "icon",
|
|
308
|
+
className: "size-8",
|
|
309
|
+
onClick: handleOnEdit,
|
|
310
|
+
"aria-label": "Edit workflow",
|
|
311
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:edit", className: "size-4" })
|
|
312
|
+
}
|
|
313
|
+
) }),
|
|
314
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx("p", { children: "Edit workflow" }) })
|
|
315
|
+
] }),
|
|
316
|
+
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
317
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(
|
|
318
|
+
SharePopup,
|
|
319
|
+
{
|
|
320
|
+
url: `${config.fluidgridFrontendUrl}/workflow-view/${workflow.workflow_key}/${workflow.version}`,
|
|
321
|
+
embedSrc: `${config.fluidgridFrontendUrl}/workflow-view/${workflow.workflow_key}/${workflow.version}`
|
|
322
|
+
}
|
|
323
|
+
) }) }),
|
|
324
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx("p", { children: "Share workflow" }) })
|
|
325
|
+
] }),
|
|
326
|
+
/* @__PURE__ */ jsx(
|
|
327
|
+
SdkPermissionGate,
|
|
328
|
+
{
|
|
329
|
+
permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_CREATE,
|
|
330
|
+
children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
331
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
332
|
+
Button,
|
|
333
|
+
{
|
|
334
|
+
variant: "ghost",
|
|
335
|
+
size: "icon",
|
|
336
|
+
className: "size-8",
|
|
337
|
+
onClick: () => handleDuplicateWorkflow(),
|
|
338
|
+
"aria-label": "Duplicate workflow",
|
|
339
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:copy", className: "size-4" })
|
|
340
|
+
}
|
|
341
|
+
) }),
|
|
342
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx("p", { children: "Duplicate workflow" }) })
|
|
343
|
+
] })
|
|
344
|
+
}
|
|
345
|
+
),
|
|
346
|
+
/* @__PURE__ */ jsx(
|
|
347
|
+
SdkPermissionGate,
|
|
348
|
+
{
|
|
349
|
+
permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_DELETE,
|
|
350
|
+
children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
351
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
352
|
+
Button,
|
|
353
|
+
{
|
|
354
|
+
variant: "ghost",
|
|
355
|
+
size: "icon",
|
|
356
|
+
className: "size-8 text-[var(--color-status-error-text)] hover:text-[var(--color-status-error-text)]",
|
|
357
|
+
onClick: () => setShowDeleteDialog(true),
|
|
358
|
+
"aria-label": "Delete workflow",
|
|
359
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:trash", className: "size-4" })
|
|
360
|
+
}
|
|
361
|
+
) }),
|
|
362
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx("p", { children: "Delete workflow" }) })
|
|
363
|
+
] })
|
|
364
|
+
}
|
|
365
|
+
)
|
|
366
|
+
] })
|
|
367
|
+
] })
|
|
368
|
+
]
|
|
369
|
+
}
|
|
370
|
+
),
|
|
371
|
+
/* @__PURE__ */ jsx(AlertDialog, { open: showDeleteDialog, onOpenChange: setShowDeleteDialog, children: /* @__PURE__ */ jsxs(AlertDialogContent, { children: [
|
|
372
|
+
/* @__PURE__ */ jsxs(AlertDialogHeader, { children: [
|
|
373
|
+
/* @__PURE__ */ jsx(AlertDialogTitle, { children: "Delete Workflow" }),
|
|
374
|
+
/* @__PURE__ */ jsxs(AlertDialogDescription, { children: [
|
|
375
|
+
'Are you sure you want to delete workflow "',
|
|
376
|
+
workflow.name,
|
|
377
|
+
'" and all its versions? This action cannot be undone.'
|
|
378
|
+
] })
|
|
379
|
+
] }),
|
|
380
|
+
/* @__PURE__ */ jsxs(AlertDialogFooter, { children: [
|
|
381
|
+
/* @__PURE__ */ jsx(AlertDialogCancel, { disabled: isDeleting, children: "Cancel" }),
|
|
382
|
+
/* @__PURE__ */ jsx(
|
|
383
|
+
AlertDialogAction,
|
|
384
|
+
{
|
|
385
|
+
onClick: handleDeleteWorkflow,
|
|
386
|
+
disabled: isDeleting,
|
|
387
|
+
className: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
388
|
+
children: isDeleting ? "Deleting..." : "Delete"
|
|
389
|
+
}
|
|
390
|
+
)
|
|
391
|
+
] })
|
|
392
|
+
] }) })
|
|
393
|
+
] });
|
|
394
|
+
};
|
|
395
|
+
var STATUS_FILTERS = [
|
|
396
|
+
{ value: "ACTIVE", label: "Active" },
|
|
397
|
+
{ value: "DRAFT", label: "Draft" },
|
|
398
|
+
{ value: "ARCHIVED", label: "Archived" },
|
|
399
|
+
{ value: "DEPRECATED", label: "Deprecated" }
|
|
400
|
+
];
|
|
401
|
+
function SkeletonCard() {
|
|
402
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-40 flex-col justify-between rounded-xl border border-border bg-card p-6", children: [
|
|
403
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2.5", children: [
|
|
404
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-2/3 bg-card-foreground/15" }),
|
|
405
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-full bg-card-foreground/10" })
|
|
406
|
+
] }),
|
|
407
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
408
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "mr-4 h-6 w-full bg-card-foreground/10" }),
|
|
409
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-8 bg-card-foreground/10" }),
|
|
410
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-8 bg-card-foreground/10" })
|
|
411
|
+
] })
|
|
412
|
+
] });
|
|
413
|
+
}
|
|
414
|
+
function WorkflowsList() {
|
|
415
|
+
const navigate = useNavigate();
|
|
416
|
+
const { workflows, loading, error, refetch } = useWorkflowDefinitions({
|
|
417
|
+
limit: 100,
|
|
418
|
+
latestOnly: true
|
|
419
|
+
});
|
|
420
|
+
const [search, setSearch] = useState("");
|
|
421
|
+
const [statusFilter, setStatusFilter] = useState(null);
|
|
422
|
+
const presentStatuses = useMemo(() => {
|
|
423
|
+
const seen = new Set(workflows.map((w) => w.status ?? "DRAFT"));
|
|
424
|
+
return STATUS_FILTERS.filter((s) => seen.has(s.value));
|
|
425
|
+
}, [workflows]);
|
|
426
|
+
const filtered = useMemo(() => {
|
|
427
|
+
const q = search.trim().toLowerCase();
|
|
428
|
+
return workflows.filter((w) => {
|
|
429
|
+
if (statusFilter && (w.status ?? "DRAFT") !== statusFilter) return false;
|
|
430
|
+
if (!q) return true;
|
|
431
|
+
return [w.name, w.description, w.alias].filter((v) => typeof v === "string").some((v) => v.toLowerCase().includes(q));
|
|
432
|
+
});
|
|
433
|
+
}, [workflows, search, statusFilter]);
|
|
434
|
+
search.trim() !== "" || statusFilter !== null;
|
|
435
|
+
const createButton = /* @__PURE__ */ jsx(
|
|
436
|
+
SdkPermissionButton,
|
|
437
|
+
{
|
|
438
|
+
permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_CREATE,
|
|
439
|
+
deniedTooltip: "You don't have permission to create workflows",
|
|
440
|
+
children: /* @__PURE__ */ jsxs(
|
|
441
|
+
Button,
|
|
442
|
+
{
|
|
443
|
+
variant: "default",
|
|
444
|
+
size: "default",
|
|
445
|
+
className: "font-bold text-primary-foreground",
|
|
446
|
+
onClick: () => navigate(`../workflow/${v4()}/v1`),
|
|
447
|
+
children: [
|
|
448
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mynaui:plus", className: "size-5 text-primary-foreground" }),
|
|
449
|
+
"Create Workflow"
|
|
450
|
+
]
|
|
451
|
+
}
|
|
452
|
+
)
|
|
453
|
+
}
|
|
454
|
+
);
|
|
455
|
+
return (
|
|
456
|
+
// min-h-screen (matching the sibling pages) makes short content still fill
|
|
457
|
+
// the viewport, keeping the shell footer below the fold.
|
|
458
|
+
/* @__PURE__ */ jsx("main", { className: "flex min-h-screen w-full flex-col bg-background-primary", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-5 p-4 sm:p-6", children: [
|
|
459
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [
|
|
460
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
461
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5", children: [
|
|
462
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold tracking-tight", children: "Workflows" }),
|
|
463
|
+
!loading && !error && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "font-mono", children: workflows.length })
|
|
464
|
+
] }),
|
|
465
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: "Build, run, and manage your automations. Open a workflow to edit it in the visual builder." })
|
|
466
|
+
] }),
|
|
467
|
+
createButton
|
|
468
|
+
] }),
|
|
469
|
+
!loading && !error && workflows.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
470
|
+
/* @__PURE__ */ jsxs("div", { className: "relative w-full max-w-xs", children: [
|
|
471
|
+
/* @__PURE__ */ jsx(
|
|
472
|
+
Icon,
|
|
473
|
+
{
|
|
474
|
+
icon: "mynaui:search",
|
|
475
|
+
className: "pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground"
|
|
476
|
+
}
|
|
477
|
+
),
|
|
478
|
+
/* @__PURE__ */ jsx(
|
|
479
|
+
Input,
|
|
480
|
+
{
|
|
481
|
+
value: search,
|
|
482
|
+
onChange: (e) => setSearch(e.target.value),
|
|
483
|
+
placeholder: "Search workflows\u2026",
|
|
484
|
+
"aria-label": "Search workflows",
|
|
485
|
+
className: "pl-8"
|
|
486
|
+
}
|
|
487
|
+
)
|
|
488
|
+
] }),
|
|
489
|
+
presentStatuses.length > 1 && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [
|
|
490
|
+
/* @__PURE__ */ jsx(
|
|
491
|
+
"button",
|
|
492
|
+
{
|
|
493
|
+
type: "button",
|
|
494
|
+
onClick: () => setStatusFilter(null),
|
|
495
|
+
className: cn(
|
|
496
|
+
"rounded-full border px-3 py-1 text-xs font-medium transition-colors",
|
|
497
|
+
statusFilter === null ? "border-transparent bg-primary text-primary-foreground" : "border-border bg-card text-muted-foreground hover:text-foreground"
|
|
498
|
+
),
|
|
499
|
+
children: "All"
|
|
500
|
+
}
|
|
501
|
+
),
|
|
502
|
+
presentStatuses.map((s) => /* @__PURE__ */ jsx(
|
|
503
|
+
"button",
|
|
504
|
+
{
|
|
505
|
+
type: "button",
|
|
506
|
+
onClick: () => setStatusFilter(
|
|
507
|
+
(cur) => cur === s.value ? null : s.value
|
|
508
|
+
),
|
|
509
|
+
className: cn(
|
|
510
|
+
"rounded-full border px-3 py-1 text-xs font-medium transition-colors",
|
|
511
|
+
statusFilter === s.value ? "border-transparent bg-primary text-primary-foreground" : "border-border bg-card text-muted-foreground hover:text-foreground"
|
|
512
|
+
),
|
|
513
|
+
children: s.label
|
|
514
|
+
},
|
|
515
|
+
s.value
|
|
516
|
+
))
|
|
517
|
+
] })
|
|
518
|
+
] }),
|
|
519
|
+
loading ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4", children: Array.from({ length: 6 }, (_, i) => /* @__PURE__ */ jsx(SkeletonCard, {}, i)) }) : error ? /* @__PURE__ */ jsx("div", { className: "grid flex-1 place-items-center", children: /* @__PURE__ */ jsxs("div", { className: "flex max-w-md flex-col items-center gap-3 rounded-xl border border-border bg-card p-8 text-center", children: [
|
|
520
|
+
/* @__PURE__ */ jsx(
|
|
521
|
+
Icon,
|
|
522
|
+
{
|
|
523
|
+
icon: "mynaui:danger-triangle",
|
|
524
|
+
className: "size-8 text-destructive"
|
|
525
|
+
}
|
|
526
|
+
),
|
|
527
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
528
|
+
/* @__PURE__ */ jsx("p", { className: "font-semibold", children: "Couldn't load workflows" }),
|
|
529
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: error.message })
|
|
530
|
+
] }),
|
|
531
|
+
/* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: () => refetch(), children: [
|
|
532
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mynaui:refresh", className: "size-4" }),
|
|
533
|
+
"Try again"
|
|
534
|
+
] })
|
|
535
|
+
] }) }) : workflows.length === 0 ? /* @__PURE__ */ jsx("div", { className: "grid flex-1 place-items-center", children: /* @__PURE__ */ jsx(
|
|
536
|
+
IllustratedEmptyState,
|
|
537
|
+
{
|
|
538
|
+
illustration: "onboarding",
|
|
539
|
+
title: "Create your first workflow",
|
|
540
|
+
description: "Workflows automate multi-step processes \u2014 sync signups into your CRM, post alerts to Slack, or transform data between apps. Start from a blank canvas or a template.",
|
|
541
|
+
action: createButton
|
|
542
|
+
}
|
|
543
|
+
) }) : filtered.length === 0 ? /* @__PURE__ */ jsx("div", { className: "grid flex-1 place-items-center", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3 text-center", children: [
|
|
544
|
+
/* @__PURE__ */ jsx(
|
|
545
|
+
Icon,
|
|
546
|
+
{
|
|
547
|
+
icon: "mynaui:search",
|
|
548
|
+
className: "size-8 text-muted-foreground"
|
|
549
|
+
}
|
|
550
|
+
),
|
|
551
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium", children: "No workflows match your filters" }),
|
|
552
|
+
/* @__PURE__ */ jsx(
|
|
553
|
+
Button,
|
|
554
|
+
{
|
|
555
|
+
variant: "outline",
|
|
556
|
+
size: "sm",
|
|
557
|
+
onClick: () => {
|
|
558
|
+
setSearch("");
|
|
559
|
+
setStatusFilter(null);
|
|
560
|
+
},
|
|
561
|
+
children: "Clear filters"
|
|
562
|
+
}
|
|
563
|
+
)
|
|
564
|
+
] }) }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4", children: filtered.map((workflow) => /* @__PURE__ */ jsx(
|
|
565
|
+
CardWorkflow,
|
|
566
|
+
{
|
|
567
|
+
workflow: {
|
|
568
|
+
id: workflow.id,
|
|
569
|
+
workflow_key: workflow.workflowKey,
|
|
570
|
+
version: workflow.version,
|
|
571
|
+
name: workflow.name,
|
|
572
|
+
description: workflow.description ?? void 0,
|
|
573
|
+
status: workflow.status ?? void 0,
|
|
574
|
+
alias: workflow.alias ?? void 0,
|
|
575
|
+
updated_at: workflow.updatedAt ?? void 0,
|
|
576
|
+
created_at: workflow.createdAt ?? void 0,
|
|
577
|
+
total_versions: workflow.totalVersions ?? void 0
|
|
578
|
+
},
|
|
579
|
+
onUpdateSuccess: () => refetch()
|
|
580
|
+
},
|
|
581
|
+
workflow.id
|
|
582
|
+
)) })
|
|
583
|
+
] }) })
|
|
584
|
+
);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
export { WorkflowsList };
|
|
588
|
+
//# sourceMappingURL=chunk-XPUAUQ3I.js.map
|
|
589
|
+
//# sourceMappingURL=chunk-XPUAUQ3I.js.map
|