@burdenoff/fluidgrids-fe-sdk 2026.1103.2 → 2026.1104.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-ND2VMU45.js +25 -0
- package/dist/{ExecutionsListPage-RC342VCZ.js → ExecutionsListPage-EZ65FXER.js} +9 -9
- package/dist/{TemplateDetailPanel-XJ43LW3G.js → TemplateDetailPanel-7MPY5MYT.js} +1 -1
- package/dist/{WorkflowBuilder-TCS4JELN.js → WorkflowBuilder-4I44FWII.js} +14 -14
- package/dist/{WorkflowsList-6ES2EDGZ.js → WorkflowsList-YFD2RKKQ.js} +9 -9
- package/dist/{agentTools-4JT66UQB.js → agentTools-SZZN6TP3.js} +5 -5
- package/dist/{chunk-EKB3EIIC.js → chunk-4EUEKSEQ.js} +1 -1
- package/dist/{chunk-Y7MQ3LYB.js → chunk-4YCMMBSK.js} +2 -2
- package/dist/{chunk-ZUVFD5KV.js → chunk-5375NUIO.js} +2 -0
- package/dist/{chunk-6WPW42TX.js → chunk-5D4XS3WJ.js} +2 -2
- package/dist/{chunk-742OIXMP.js → chunk-5UHAB75U.js} +1 -1
- package/dist/{chunk-YC76QFWZ.js → chunk-AAIZ6S6E.js} +2 -2
- package/dist/{chunk-QXACKASD.js → chunk-AFX3EKFN.js} +22 -3
- package/dist/{chunk-JTQFBZTV.js → chunk-AVHBWJRY.js} +6 -3
- package/dist/{chunk-OBWB73Y7.js → chunk-BIB7IH26.js} +4 -4
- package/dist/{chunk-G2FPOWN5.js → chunk-D4WA2M2N.js} +2 -2
- package/dist/{chunk-LTINUSLK.js → chunk-DFIX6YWP.js} +59 -16
- package/dist/{chunk-PC3CICOW.js → chunk-F7LQL43U.js} +1 -1
- package/dist/{chunk-SHYDX2LO.js → chunk-GEY7RXRZ.js} +5 -5
- package/dist/{chunk-AOLY5INN.js → chunk-H4ERTSMX.js} +31 -1
- package/dist/{chunk-Y7BNGLRI.js → chunk-IK7IGG6T.js} +6 -6
- package/dist/{chunk-N6XYVO7N.js → chunk-KHXRYQYP.js} +2 -2
- package/dist/{chunk-UH7JKPUF.js → chunk-MF7JLSJX.js} +1 -1
- package/dist/{chunk-BVCMAGLJ.js → chunk-NGXJHYV5.js} +1 -1
- package/dist/{chunk-UW5GY6LQ.js → chunk-NIY6R42C.js} +4 -4
- package/dist/{chunk-BP6YPKNK.js → chunk-NJRCAE6K.js} +4 -4
- package/dist/{chunk-LVTOWRAM.js → chunk-NYBL5WHP.js} +2 -2
- package/dist/{chunk-UMULDJCK.js → chunk-OMB3WMDQ.js} +6 -6
- package/dist/{chunk-M23H4LSY.js → chunk-ON7LK6QH.js} +5 -5
- package/dist/{chunk-MY4HMUWU.js → chunk-Q72EOY4T.js} +3 -3
- package/dist/{chunk-H2KIJEYM.js → chunk-SS7Y66P5.js} +2 -2
- package/dist/{chunk-52OIBKPO.js → chunk-TBHAZK52.js} +1 -1
- package/dist/{chunk-VQZEGCRF.js → chunk-VDJFTZ2H.js} +1 -1
- package/dist/{chunk-RFOKJE3A.js → chunk-WTV6SQYK.js} +11 -11
- package/dist/{chunk-SIVS3XSV.js → chunk-X6PIU7FE.js} +224 -5
- package/dist/{chunk-ILPQAQB5.js → chunk-XCSCD3IU.js} +465 -219
- package/dist/{chunk-K6HD5GC7.js → chunk-XNU2PLJ2.js} +4 -4
- package/dist/{chunk-SUIH376K.js → chunk-YYVRBROH.js} +1 -1
- package/dist/{chunk-VFLHURFM.js → chunk-ZDCJPQ5M.js} +1 -1
- package/dist/executions.js +14 -14
- package/dist/history.js +6 -6
- package/dist/index.d.ts +408 -1
- package/dist/index.js +46 -46
- package/dist/{node-detail-view-CMQ7DUYM.js → node-detail-view-GAGSLHAO.js} +10 -10
- package/dist/nodes.js +2 -2
- package/dist/observability.js +7 -7
- package/dist/{quick-config-panel-NJ72QZPM.js → quick-config-panel-44RBX6YR.js} +7 -7
- package/dist/settings.js +7 -7
- package/dist/templates.js +13 -13
- package/dist/workflow-builder.js +15 -15
- package/dist/workflows-list.js +9 -9
- package/package.json +4 -4
- package/dist/ExecutionDetailPage-JRBUIU5J.js +0 -25
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { CreateWorkflowRefusalDialog, firstWorkflowProgress, GUIDED_TOUR_STATE, builderPathFor } from './chunk-
|
|
2
|
-
import { useExecutions } from './chunk-
|
|
3
|
-
import { useExportWorkflowAs, downloadWorkflowExport, importAcceptAttribute, QuotaExhaustedDialog, importFileKind, parseWorkflowImport, CODE_EXPORT_FORMATS, ImportSourceError, assertImportByteSize, MAX_IMPORT_ARCHIVE_BYTES, readProjectArchive, checkTypeScriptImport, MAX_IMPORT_SOURCE_BYTES, typeScriptModuleFile, typeScriptImportSource, workflowNameFromFile, primaryImportModule } from './chunk-
|
|
1
|
+
import { CreateWorkflowRefusalDialog, firstWorkflowProgress, GUIDED_TOUR_STATE, builderPathFor } from './chunk-TBHAZK52.js';
|
|
2
|
+
import { useExecutions } from './chunk-5D4XS3WJ.js';
|
|
3
|
+
import { useExportWorkflowAs, WorkflowShareDialog, downloadWorkflowExport, importAcceptAttribute, canEditWorkflow, canShareWorkflow, QuotaExhaustedDialog, importFileKind, parseWorkflowImport, CODE_EXPORT_FORMATS, ImportSourceError, assertImportByteSize, MAX_IMPORT_ARCHIVE_BYTES, readProjectArchive, checkTypeScriptImport, MAX_IMPORT_SOURCE_BYTES, typeScriptModuleFile, typeScriptImportSource, workflowNameFromFile, primaryImportModule } from './chunk-X6PIU7FE.js';
|
|
4
4
|
import { workflowsListControls } from './chunk-FNZZ5JJL.js';
|
|
5
|
-
import { useCreateWorkflow, useWorkflowDefinitions, useLazyWorkflowDefinition, useImportWorkflow, useDuplicateWorkflow, useDeleteWorkflow } from './chunk-
|
|
5
|
+
import { useCreateWorkflow, useWorkflowDefinitions, useLazyWorkflowDefinition, useImportWorkflow, usePreviewN8nImport, useDuplicateWorkflow, useDeleteWorkflow } from './chunk-AFX3EKFN.js';
|
|
6
6
|
import { useFluidGridsPageControls } from './chunk-PJAWNFJV.js';
|
|
7
7
|
import { FluidGridsDocsLink } from './chunk-4VJ3MDOV.js';
|
|
8
|
-
import { createThenOpen, useFluidGridsFlag, FLUIDGRIDS_FLAGS, BILLING_PLANS_PATH, describeOperationError, useFlowStore, throwIfResultError, isQuotaExhaustedFailure } from './chunk-
|
|
9
|
-
import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton, SdkPermissionGate } from './chunk-
|
|
10
|
-
import { WorkflowFoldersDocument, CreateWorkflowFolderDocument, RenameWorkflowFolderDocument, MoveWorkflowFolderDocument, DeleteWorkflowFolderDocument, WorkflowProjectsDocument, CreateWorkflowProjectDocument, RenameWorkflowProjectDocument, DeleteWorkflowProjectDocument, BulkMoveWorkflowsToFolderDocument, BulkAssignWorkflowsToProjectDocument, BulkDeleteWorkflowsDocument } from './chunk-
|
|
8
|
+
import { createThenOpen, FluidGridsContext, useFluidGridsFlag, FLUIDGRIDS_FLAGS, BILLING_PLANS_PATH, describeOperationError, useFlowStore, throwIfResultError, isQuotaExhaustedFailure } from './chunk-AAIZ6S6E.js';
|
|
9
|
+
import { useFluidGridsPermission, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton, SdkPermissionGate } from './chunk-5375NUIO.js';
|
|
10
|
+
import { WorkflowFoldersDocument, CreateWorkflowFolderDocument, RenameWorkflowFolderDocument, MoveWorkflowFolderDocument, DeleteWorkflowFolderDocument, WorkflowProjectsDocument, CreateWorkflowProjectDocument, RenameWorkflowProjectDocument, DeleteWorkflowProjectDocument, BulkMoveWorkflowsToFolderDocument, BulkAssignWorkflowsToProjectDocument, BulkDeleteWorkflowsDocument } from './chunk-AVHBWJRY.js';
|
|
11
11
|
import { useTr } from './chunk-UULVIT25.js';
|
|
12
12
|
import { getFluidGridsClient } from './chunk-NTWG3CJX.js';
|
|
13
|
-
import { useState, useRef, useCallback, useMemo, useEffect } from 'react';
|
|
13
|
+
import { useState, useRef, useCallback, useContext, useMemo, useEffect } from 'react';
|
|
14
14
|
import { useNavigate } from 'react-router';
|
|
15
15
|
import { v4 } from 'uuid';
|
|
16
16
|
import { Icon } from '@iconify/react';
|
|
@@ -18,7 +18,6 @@ import { NextSteps, Button, Badge, Input, IllustratedEmptyState, Checkbox, Dialo
|
|
|
18
18
|
import { cn } from '@burdenoff/fe-libs/utils';
|
|
19
19
|
import { TagBadge } from '@burdenoff/fe-libs/tag';
|
|
20
20
|
import { toast } from 'sonner';
|
|
21
|
-
import { Share2, Copy } from 'lucide-react';
|
|
22
21
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
23
22
|
|
|
24
23
|
function useCreateWorkflowFirst(options = {}) {
|
|
@@ -52,200 +51,6 @@ function useCreateWorkflowFirst(options = {}) {
|
|
|
52
51
|
const clearRefusal = useCallback(() => setRefusal(null), []);
|
|
53
52
|
return { start, creating, refusal, clearRefusal };
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
// src/components/share-target.ts
|
|
57
|
-
var PLACEHOLDER_SEGMENTS = /* @__PURE__ */ new Set(["undefined", "null"]);
|
|
58
|
-
function toPublicUrl(raw) {
|
|
59
|
-
if (typeof raw !== "string" || raw.trim() === "") return null;
|
|
60
|
-
let parsed;
|
|
61
|
-
try {
|
|
62
|
-
parsed = new URL(raw);
|
|
63
|
-
} catch {
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return null;
|
|
67
|
-
if (!parsed.hostname || PLACEHOLDER_SEGMENTS.has(parsed.hostname)) {
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
const hasPlaceholderSegment = parsed.pathname.split("/").some((segment) => PLACEHOLDER_SEGMENTS.has(segment.toLowerCase()));
|
|
71
|
-
if (hasPlaceholderSegment) return null;
|
|
72
|
-
return parsed.href;
|
|
73
|
-
}
|
|
74
|
-
function resolveShareTarget(input) {
|
|
75
|
-
const shareUrl = toPublicUrl(input.shareUrl);
|
|
76
|
-
if (!shareUrl) return null;
|
|
77
|
-
const embedUrl = toPublicUrl(input.embedUrl);
|
|
78
|
-
return embedUrl ? { shareUrl, embedUrl } : { shareUrl };
|
|
79
|
-
}
|
|
80
|
-
var MIN_EMBED_SIZE = 100;
|
|
81
|
-
var MAX_EMBED_SIZE = 4e3;
|
|
82
|
-
function clampEmbedSize(value, fallback) {
|
|
83
|
-
if (!Number.isFinite(value)) return fallback;
|
|
84
|
-
return Math.min(MAX_EMBED_SIZE, Math.max(MIN_EMBED_SIZE, Math.round(value)));
|
|
85
|
-
}
|
|
86
|
-
function buildEmbedSnippet(embedUrl, width, height) {
|
|
87
|
-
const w = clampEmbedSize(width, 600);
|
|
88
|
-
const h = clampEmbedSize(height, 400);
|
|
89
|
-
return `<iframe src="${embedUrl}" width="${w}" height="${h}" frameborder="0"></iframe>`;
|
|
90
|
-
}
|
|
91
|
-
function SharePopup({ shareUrl, embedUrl }) {
|
|
92
|
-
const tr = useTr();
|
|
93
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
94
|
-
const [width, setWidth] = useState(600);
|
|
95
|
-
const [height, setHeight] = useState(400);
|
|
96
|
-
const [activeTab, setActiveTab] = useState("link");
|
|
97
|
-
const target = resolveShareTarget({ shareUrl, embedUrl });
|
|
98
|
-
if (!target) {
|
|
99
|
-
return /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "icon", disabled: true, "aria-disabled": "true", children: [
|
|
100
|
-
/* @__PURE__ */ jsx(Share2, { className: "h-4 w-4" }),
|
|
101
|
-
/* @__PURE__ */ jsx("span", { className: "sr-only", children: tr(
|
|
102
|
-
"fluidgrids.components.sharePopup.unavailableLabel",
|
|
103
|
-
"Sharing is not available yet"
|
|
104
|
-
) })
|
|
105
|
-
] });
|
|
106
|
-
}
|
|
107
|
-
const embedCode = target.embedUrl ? buildEmbedSnippet(target.embedUrl, width, height) : "";
|
|
108
|
-
const copyToClipboard = (text, message) => {
|
|
109
|
-
navigator.clipboard.writeText(text).then(
|
|
110
|
-
() => toast.success(message),
|
|
111
|
-
() => toast.error(
|
|
112
|
-
tr(
|
|
113
|
-
"fluidgrids.components.sharePopup.copyFailedToast",
|
|
114
|
-
"Could not copy to clipboard"
|
|
115
|
-
)
|
|
116
|
-
)
|
|
117
|
-
);
|
|
118
|
-
};
|
|
119
|
-
if (!isOpen) {
|
|
120
|
-
return /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "icon", onClick: () => setIsOpen(true), children: [
|
|
121
|
-
/* @__PURE__ */ jsx(Share2, { className: "h-4 w-4" }),
|
|
122
|
-
/* @__PURE__ */ jsx("span", { className: "sr-only", children: tr("fluidgrids.components.sharePopup.openLabel", "Share") })
|
|
123
|
-
] });
|
|
124
|
-
}
|
|
125
|
-
return /* @__PURE__ */ jsx(
|
|
126
|
-
"div",
|
|
127
|
-
{
|
|
128
|
-
className: "fixed inset-0 z-50 flex items-center justify-center bg-bg-overlay",
|
|
129
|
-
onClick: () => setIsOpen(false),
|
|
130
|
-
children: /* @__PURE__ */ jsxs(
|
|
131
|
-
"div",
|
|
132
|
-
{
|
|
133
|
-
className: "bg-card rounded-lg p-6 max-w-md w-full mx-4",
|
|
134
|
-
onClick: (e) => e.stopPropagation(),
|
|
135
|
-
children: [
|
|
136
|
-
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center mb-4", children: [
|
|
137
|
-
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold", children: tr("fluidgrids.components.sharePopup.title", "Share") }),
|
|
138
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", onClick: () => setIsOpen(false), children: "\xD7" })
|
|
139
|
-
] }),
|
|
140
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 mb-4", children: [
|
|
141
|
-
/* @__PURE__ */ jsx(
|
|
142
|
-
Button,
|
|
143
|
-
{
|
|
144
|
-
variant: activeTab === "link" ? "default" : "outline",
|
|
145
|
-
size: "sm",
|
|
146
|
-
onClick: () => setActiveTab("link"),
|
|
147
|
-
children: tr("fluidgrids.components.sharePopup.tabShareLink", "Share Link")
|
|
148
|
-
}
|
|
149
|
-
),
|
|
150
|
-
target.embedUrl && /* @__PURE__ */ jsx(
|
|
151
|
-
Button,
|
|
152
|
-
{
|
|
153
|
-
variant: activeTab === "embed" ? "default" : "outline",
|
|
154
|
-
size: "sm",
|
|
155
|
-
onClick: () => setActiveTab("embed"),
|
|
156
|
-
children: tr("fluidgrids.components.sharePopup.tabEmbed", "Embed")
|
|
157
|
-
}
|
|
158
|
-
)
|
|
159
|
-
] }),
|
|
160
|
-
activeTab === "link" && /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
|
|
161
|
-
/* @__PURE__ */ jsx(
|
|
162
|
-
"input",
|
|
163
|
-
{
|
|
164
|
-
readOnly: true,
|
|
165
|
-
value: target.shareUrl,
|
|
166
|
-
className: "flex-1 h-9 px-3 rounded-md border bg-background text-sm"
|
|
167
|
-
}
|
|
168
|
-
),
|
|
169
|
-
/* @__PURE__ */ jsx(
|
|
170
|
-
Button,
|
|
171
|
-
{
|
|
172
|
-
size: "sm",
|
|
173
|
-
onClick: () => copyToClipboard(
|
|
174
|
-
target.shareUrl,
|
|
175
|
-
tr(
|
|
176
|
-
"fluidgrids.components.sharePopup.linkCopiedToast",
|
|
177
|
-
"Link copied to clipboard"
|
|
178
|
-
)
|
|
179
|
-
),
|
|
180
|
-
children: /* @__PURE__ */ jsx(Copy, { className: "h-4 w-4" })
|
|
181
|
-
}
|
|
182
|
-
)
|
|
183
|
-
] }),
|
|
184
|
-
activeTab === "embed" && target.embedUrl && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
185
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
186
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
187
|
-
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: tr("fluidgrids.components.sharePopup.widthLabel", "Width") }),
|
|
188
|
-
/* @__PURE__ */ jsx(
|
|
189
|
-
"input",
|
|
190
|
-
{
|
|
191
|
-
type: "number",
|
|
192
|
-
value: width,
|
|
193
|
-
onChange: (e) => setWidth(Number(e.target.value)),
|
|
194
|
-
className: "w-full h-9 px-3 rounded-md border bg-background text-sm mt-1"
|
|
195
|
-
}
|
|
196
|
-
)
|
|
197
|
-
] }),
|
|
198
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
199
|
-
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: tr("fluidgrids.components.sharePopup.heightLabel", "Height") }),
|
|
200
|
-
/* @__PURE__ */ jsx(
|
|
201
|
-
"input",
|
|
202
|
-
{
|
|
203
|
-
type: "number",
|
|
204
|
-
value: height,
|
|
205
|
-
onChange: (e) => setHeight(Number(e.target.value)),
|
|
206
|
-
className: "w-full h-9 px-3 rounded-md border bg-background text-sm mt-1"
|
|
207
|
-
}
|
|
208
|
-
)
|
|
209
|
-
] })
|
|
210
|
-
] }),
|
|
211
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
212
|
-
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: tr(
|
|
213
|
-
"fluidgrids.components.sharePopup.embedCodeLabel",
|
|
214
|
-
"Embed Code"
|
|
215
|
-
) }),
|
|
216
|
-
/* @__PURE__ */ jsxs("div", { className: "relative mt-1", children: [
|
|
217
|
-
/* @__PURE__ */ jsx(
|
|
218
|
-
"input",
|
|
219
|
-
{
|
|
220
|
-
readOnly: true,
|
|
221
|
-
value: embedCode,
|
|
222
|
-
className: "w-full h-9 px-3 pr-12 rounded-md border bg-background text-sm font-mono"
|
|
223
|
-
}
|
|
224
|
-
),
|
|
225
|
-
/* @__PURE__ */ jsx(
|
|
226
|
-
Button,
|
|
227
|
-
{
|
|
228
|
-
size: "sm",
|
|
229
|
-
className: "absolute right-1 top-1/2 -translate-y-1/2 h-7",
|
|
230
|
-
onClick: () => copyToClipboard(
|
|
231
|
-
embedCode,
|
|
232
|
-
tr(
|
|
233
|
-
"fluidgrids.components.sharePopup.embedCopiedToast",
|
|
234
|
-
"Embed code copied to clipboard"
|
|
235
|
-
)
|
|
236
|
-
),
|
|
237
|
-
children: /* @__PURE__ */ jsx(Copy, { className: "h-4 w-4" })
|
|
238
|
-
}
|
|
239
|
-
)
|
|
240
|
-
] })
|
|
241
|
-
] })
|
|
242
|
-
] })
|
|
243
|
-
]
|
|
244
|
-
}
|
|
245
|
-
)
|
|
246
|
-
}
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
54
|
function WorkflowStatusPill({ status }) {
|
|
250
55
|
const tr = useTr();
|
|
251
56
|
const styles = {
|
|
@@ -360,7 +165,9 @@ var CardWorkflow = ({
|
|
|
360
165
|
onUpdateSuccess,
|
|
361
166
|
onExport,
|
|
362
167
|
onExportAs,
|
|
363
|
-
exportingFormat = null
|
|
168
|
+
exportingFormat = null,
|
|
169
|
+
onShare,
|
|
170
|
+
onMoveToProject
|
|
364
171
|
}) => {
|
|
365
172
|
const tr = useTr();
|
|
366
173
|
const navigate = useNavigate();
|
|
@@ -435,6 +242,9 @@ var CardWorkflow = ({
|
|
|
435
242
|
return;
|
|
436
243
|
handleOnEdit();
|
|
437
244
|
};
|
|
245
|
+
const restricted = workflow.visibility === "RESTRICTED";
|
|
246
|
+
const editable = canEditWorkflow(workflow.my_access);
|
|
247
|
+
const shareable = canShareWorkflow(workflow.my_access);
|
|
438
248
|
const updatedExact = workflow.updated_at ? new Date(workflow.updated_at).toLocaleString() : void 0;
|
|
439
249
|
return /* @__PURE__ */ jsxs(TooltipProvider, { children: [
|
|
440
250
|
/* @__PURE__ */ jsxs(
|
|
@@ -460,7 +270,27 @@ var CardWorkflow = ({
|
|
|
460
270
|
/* @__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" }) }),
|
|
461
271
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
462
272
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
463
|
-
/* @__PURE__ */
|
|
273
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [
|
|
274
|
+
/* @__PURE__ */ jsx("h3", { className: "truncate font-semibold leading-6 text-card-foreground", children: workflow?.name }),
|
|
275
|
+
restricted && /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
276
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
277
|
+
"span",
|
|
278
|
+
{
|
|
279
|
+
className: "shrink-0 text-muted-foreground",
|
|
280
|
+
"data-testid": "workflow-restricted-badge",
|
|
281
|
+
"aria-label": tr(
|
|
282
|
+
"fluidgrids.builder.cardWorkflow.restricted",
|
|
283
|
+
"Shared only with chosen people"
|
|
284
|
+
),
|
|
285
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:lock-outline", className: "size-3.5" })
|
|
286
|
+
}
|
|
287
|
+
) }),
|
|
288
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx("p", { children: tr(
|
|
289
|
+
"fluidgrids.builder.cardWorkflow.restricted",
|
|
290
|
+
"Shared only with chosen people"
|
|
291
|
+
) }) })
|
|
292
|
+
] })
|
|
293
|
+
] }),
|
|
464
294
|
/* @__PURE__ */ jsx(WorkflowStatusPill, { status: workflow.status })
|
|
465
295
|
] }),
|
|
466
296
|
/* @__PURE__ */ jsx("p", { className: "mt-1 line-clamp-2 text-xs leading-snug text-muted-foreground", children: workflow.description || tr(
|
|
@@ -556,13 +386,60 @@ var CardWorkflow = ({
|
|
|
556
386
|
"Workflow settings"
|
|
557
387
|
) }) })
|
|
558
388
|
] }),
|
|
559
|
-
/* @__PURE__ */
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
389
|
+
onShare && shareable && /* @__PURE__ */ jsx(
|
|
390
|
+
SdkPermissionGate,
|
|
391
|
+
{
|
|
392
|
+
permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_SHARE,
|
|
393
|
+
children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
394
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
395
|
+
Button,
|
|
396
|
+
{
|
|
397
|
+
variant: "ghost",
|
|
398
|
+
size: "icon",
|
|
399
|
+
className: "size-8",
|
|
400
|
+
onClick: onShare,
|
|
401
|
+
"data-testid": "workflow-card-share",
|
|
402
|
+
"aria-label": tr(
|
|
403
|
+
"fluidgrids.builder.cardWorkflow.shareWorkflow",
|
|
404
|
+
"Share workflow"
|
|
405
|
+
),
|
|
406
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "mynaui:share", className: "size-4" })
|
|
407
|
+
}
|
|
408
|
+
) }),
|
|
409
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx("p", { children: tr(
|
|
410
|
+
"fluidgrids.builder.cardWorkflow.shareWorkflow",
|
|
411
|
+
"Share workflow"
|
|
412
|
+
) }) })
|
|
413
|
+
] })
|
|
414
|
+
}
|
|
415
|
+
),
|
|
416
|
+
onMoveToProject && editable && /* @__PURE__ */ jsx(
|
|
417
|
+
SdkPermissionGate,
|
|
418
|
+
{
|
|
419
|
+
permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_UPDATE,
|
|
420
|
+
children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
421
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
422
|
+
Button,
|
|
423
|
+
{
|
|
424
|
+
variant: "ghost",
|
|
425
|
+
size: "icon",
|
|
426
|
+
className: "size-8",
|
|
427
|
+
onClick: onMoveToProject,
|
|
428
|
+
"data-testid": "workflow-card-move-project",
|
|
429
|
+
"aria-label": tr(
|
|
430
|
+
"fluidgrids.builder.cardWorkflow.moveToProject",
|
|
431
|
+
"Move to project"
|
|
432
|
+
),
|
|
433
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:folder-move-outline", className: "size-4" })
|
|
434
|
+
}
|
|
435
|
+
) }),
|
|
436
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "top", children: /* @__PURE__ */ jsx("p", { children: tr(
|
|
437
|
+
"fluidgrids.builder.cardWorkflow.moveToProject",
|
|
438
|
+
"Move to project"
|
|
439
|
+
) }) })
|
|
440
|
+
] })
|
|
441
|
+
}
|
|
442
|
+
),
|
|
566
443
|
onExportAs ? /* @__PURE__ */ jsx("span", { "data-card-action": "", children: /* @__PURE__ */ jsx(
|
|
567
444
|
WorkflowExportMenu,
|
|
568
445
|
{
|
|
@@ -615,7 +492,7 @@ var CardWorkflow = ({
|
|
|
615
492
|
] })
|
|
616
493
|
}
|
|
617
494
|
),
|
|
618
|
-
/* @__PURE__ */ jsx(
|
|
495
|
+
editable && /* @__PURE__ */ jsx(
|
|
619
496
|
SdkPermissionGate,
|
|
620
497
|
{
|
|
621
498
|
permission: FLUIDGRIDS_PERMISSIONS.WORKFLOW_DELETE,
|
|
@@ -698,6 +575,159 @@ var CardWorkflow = ({
|
|
|
698
575
|
)
|
|
699
576
|
] });
|
|
700
577
|
};
|
|
578
|
+
function Section({
|
|
579
|
+
title,
|
|
580
|
+
icon,
|
|
581
|
+
testId,
|
|
582
|
+
children
|
|
583
|
+
}) {
|
|
584
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1", "data-testid": testId, children: [
|
|
585
|
+
/* @__PURE__ */ jsxs("p", { className: "flex items-center gap-1.5 text-xs font-medium text-foreground", children: [
|
|
586
|
+
/* @__PURE__ */ jsx(Icon, { icon, className: "size-3.5 text-muted-foreground" }),
|
|
587
|
+
title
|
|
588
|
+
] }),
|
|
589
|
+
/* @__PURE__ */ jsx("ul", { className: "space-y-1 pl-5 text-xs text-muted-foreground", children })
|
|
590
|
+
] });
|
|
591
|
+
}
|
|
592
|
+
function keyed(entries, keyOf) {
|
|
593
|
+
const seen = /* @__PURE__ */ new Map();
|
|
594
|
+
for (const entry of entries) {
|
|
595
|
+
const key = keyOf(entry);
|
|
596
|
+
if (!seen.has(key)) seen.set(key, entry);
|
|
597
|
+
}
|
|
598
|
+
return [...seen.entries()];
|
|
599
|
+
}
|
|
600
|
+
function N8nImportReport({ report }) {
|
|
601
|
+
const tr = useTr();
|
|
602
|
+
return /* @__PURE__ */ jsxs(
|
|
603
|
+
"div",
|
|
604
|
+
{
|
|
605
|
+
className: "space-y-3 rounded-lg border border-border bg-background p-3",
|
|
606
|
+
"data-testid": "fluidgrids-import-n8n-report",
|
|
607
|
+
children: [
|
|
608
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
|
|
609
|
+
/* @__PURE__ */ jsx(
|
|
610
|
+
Icon,
|
|
611
|
+
{
|
|
612
|
+
icon: "mynaui:download",
|
|
613
|
+
className: "mt-0.5 size-4 shrink-0 text-muted-foreground"
|
|
614
|
+
}
|
|
615
|
+
),
|
|
616
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
617
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: tr(
|
|
618
|
+
"fluidgrids.workflowsList.importN8nDetected",
|
|
619
|
+
"n8n workflow detected"
|
|
620
|
+
) }),
|
|
621
|
+
/* @__PURE__ */ jsx(
|
|
622
|
+
"p",
|
|
623
|
+
{
|
|
624
|
+
className: "text-xs text-muted-foreground",
|
|
625
|
+
"data-testid": "fluidgrids-import-n8n-summary",
|
|
626
|
+
children: tr(
|
|
627
|
+
"fluidgrids.workflowsList.importN8nSummary",
|
|
628
|
+
"{{mapped}} of {{total}} nodes convert directly \xB7 {{placeholders}} placeholders \xB7 {{connections}} connections to set up",
|
|
629
|
+
{
|
|
630
|
+
mapped: String(report.mappedNodes.length),
|
|
631
|
+
total: String(report.nodeCount),
|
|
632
|
+
placeholders: String(report.placeholders.length),
|
|
633
|
+
connections: String(report.connectionsNeeded.length)
|
|
634
|
+
}
|
|
635
|
+
)
|
|
636
|
+
}
|
|
637
|
+
)
|
|
638
|
+
] })
|
|
639
|
+
] }),
|
|
640
|
+
report.placeholders.length > 0 && /* @__PURE__ */ jsx(
|
|
641
|
+
Section,
|
|
642
|
+
{
|
|
643
|
+
title: tr(
|
|
644
|
+
"fluidgrids.workflowsList.importN8nPlaceholders",
|
|
645
|
+
"Placeholders: these nodes are kept as disabled No-op nodes, with their n8n settings in the node notes"
|
|
646
|
+
),
|
|
647
|
+
icon: "mynaui:square-dashed",
|
|
648
|
+
testId: "fluidgrids-import-n8n-placeholders",
|
|
649
|
+
children: report.placeholders.map((placeholder) => /* @__PURE__ */ jsxs("li", { children: [
|
|
650
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: placeholder.name }),
|
|
651
|
+
" ",
|
|
652
|
+
/* @__PURE__ */ jsxs("span", { className: "font-mono", children: [
|
|
653
|
+
"(",
|
|
654
|
+
placeholder.n8nType,
|
|
655
|
+
")"
|
|
656
|
+
] }),
|
|
657
|
+
":",
|
|
658
|
+
" ",
|
|
659
|
+
placeholder.reason
|
|
660
|
+
] }, placeholder.nodeId))
|
|
661
|
+
}
|
|
662
|
+
),
|
|
663
|
+
report.connectionsNeeded.length > 0 && /* @__PURE__ */ jsx(
|
|
664
|
+
Section,
|
|
665
|
+
{
|
|
666
|
+
title: tr(
|
|
667
|
+
"fluidgrids.workflowsList.importN8nConnections",
|
|
668
|
+
"Connections to create: n8n credentials are never imported"
|
|
669
|
+
),
|
|
670
|
+
icon: "mynaui:key",
|
|
671
|
+
testId: "fluidgrids-import-n8n-connections",
|
|
672
|
+
children: keyed(
|
|
673
|
+
report.connectionsNeeded,
|
|
674
|
+
(connection) => `${connection.nodeId}|${connection.provider ?? ""}|${connection.n8nCredentialType ?? ""}`
|
|
675
|
+
).map(([key, connection]) => /* @__PURE__ */ jsxs("li", { children: [
|
|
676
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: connection.nodeName }),
|
|
677
|
+
connection.provider && connection.provider !== "*" ? ` \xB7 ${connection.provider}` : "",
|
|
678
|
+
connection.n8nCredentialName ? ` \xB7 ${tr(
|
|
679
|
+
"fluidgrids.workflowsList.importN8nCredentialWas",
|
|
680
|
+
"was {{credential}} in n8n",
|
|
681
|
+
{ credential: connection.n8nCredentialName }
|
|
682
|
+
)}` : ""
|
|
683
|
+
] }, key))
|
|
684
|
+
}
|
|
685
|
+
),
|
|
686
|
+
report.expressionIssues.length > 0 && /* @__PURE__ */ jsx(
|
|
687
|
+
Section,
|
|
688
|
+
{
|
|
689
|
+
title: tr(
|
|
690
|
+
"fluidgrids.workflowsList.importN8nExpressions",
|
|
691
|
+
"Expressions and conditions to review"
|
|
692
|
+
),
|
|
693
|
+
icon: "mynaui:code",
|
|
694
|
+
testId: "fluidgrids-import-n8n-expressions",
|
|
695
|
+
children: keyed(
|
|
696
|
+
report.expressionIssues,
|
|
697
|
+
(issue) => `${issue.nodeName}|${issue.expression}|${issue.reason}`
|
|
698
|
+
).map(([key, issue]) => /* @__PURE__ */ jsxs("li", { children: [
|
|
699
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: issue.nodeName }),
|
|
700
|
+
": ",
|
|
701
|
+
/* @__PURE__ */ jsx("span", { className: "break-all font-mono", children: issue.expression }),
|
|
702
|
+
" ",
|
|
703
|
+
"\u2014 ",
|
|
704
|
+
issue.reason
|
|
705
|
+
] }, key))
|
|
706
|
+
}
|
|
707
|
+
),
|
|
708
|
+
report.warnings.length > 0 && /* @__PURE__ */ jsx(
|
|
709
|
+
Section,
|
|
710
|
+
{
|
|
711
|
+
title: tr("fluidgrids.workflowsList.importN8nNotes", "Notes"),
|
|
712
|
+
icon: "mynaui:info-circle",
|
|
713
|
+
testId: "fluidgrids-import-n8n-warnings",
|
|
714
|
+
children: keyed(
|
|
715
|
+
report.warnings,
|
|
716
|
+
(warning) => `${warning.nodeName ?? ""}|${warning.message}`
|
|
717
|
+
).map(([key, warning]) => /* @__PURE__ */ jsxs("li", { children: [
|
|
718
|
+
warning.nodeName ? /* @__PURE__ */ jsxs("span", { className: "font-medium text-foreground", children: [
|
|
719
|
+
warning.nodeName,
|
|
720
|
+
":",
|
|
721
|
+
" "
|
|
722
|
+
] }) : null,
|
|
723
|
+
warning.message
|
|
724
|
+
] }, key))
|
|
725
|
+
}
|
|
726
|
+
)
|
|
727
|
+
]
|
|
728
|
+
}
|
|
729
|
+
);
|
|
730
|
+
}
|
|
701
731
|
function formatMiB(bytes) {
|
|
702
732
|
const mib = bytes / (1024 * 1024);
|
|
703
733
|
return Number.isInteger(mib) ? String(mib) : mib.toFixed(1);
|
|
@@ -788,7 +818,17 @@ function WorkflowImportDialog({
|
|
|
788
818
|
const [workflowKey, setWorkflowKey] = useState("");
|
|
789
819
|
const [version, setVersion] = useState("");
|
|
790
820
|
const [loadingUrl, setLoadingUrl] = useState(false);
|
|
821
|
+
const { previewN8nImport } = usePreviewN8nImport();
|
|
822
|
+
const [n8nPreview, setN8nPreview] = useState(null);
|
|
823
|
+
const [previewingN8n, setPreviewingN8n] = useState(false);
|
|
824
|
+
const previewRequest = useRef(0);
|
|
825
|
+
const dropN8nPreview = () => {
|
|
826
|
+
previewRequest.current += 1;
|
|
827
|
+
setN8nPreview(null);
|
|
828
|
+
setPreviewingN8n(false);
|
|
829
|
+
};
|
|
791
830
|
const reset = () => {
|
|
831
|
+
dropN8nPreview();
|
|
792
832
|
setRawJson("");
|
|
793
833
|
setUrl("");
|
|
794
834
|
setParsed(null);
|
|
@@ -800,6 +840,7 @@ function WorkflowImportDialog({
|
|
|
800
840
|
setSubmitted(false);
|
|
801
841
|
};
|
|
802
842
|
const selectTypeScript = (label, files) => {
|
|
843
|
+
dropN8nPreview();
|
|
803
844
|
setParsed(null);
|
|
804
845
|
setIssues(null);
|
|
805
846
|
setSubmitted(false);
|
|
@@ -809,6 +850,7 @@ function WorkflowImportDialog({
|
|
|
809
850
|
setVersion("");
|
|
810
851
|
};
|
|
811
852
|
const refuseSource = (error) => {
|
|
853
|
+
dropN8nPreview();
|
|
812
854
|
setTypeScript(null);
|
|
813
855
|
setParsed(null);
|
|
814
856
|
setSubmitted(false);
|
|
@@ -838,16 +880,39 @@ function WorkflowImportDialog({
|
|
|
838
880
|
}
|
|
839
881
|
return true;
|
|
840
882
|
};
|
|
883
|
+
const showN8nPreview = async (next) => {
|
|
884
|
+
const request = previewRequest.current;
|
|
885
|
+
setPreviewingN8n(true);
|
|
886
|
+
try {
|
|
887
|
+
const preview = await previewN8nImport(next.definitionJson);
|
|
888
|
+
if (request !== previewRequest.current) return;
|
|
889
|
+
setN8nPreview(preview);
|
|
890
|
+
setName(preview.name);
|
|
891
|
+
} catch (error) {
|
|
892
|
+
if (request !== previewRequest.current) return;
|
|
893
|
+
setParsed(null);
|
|
894
|
+
toast.error(
|
|
895
|
+
error instanceof Error ? error.message : tr(
|
|
896
|
+
"fluidgrids.workflowsList.importN8nPreviewFailed",
|
|
897
|
+
"The n8n workflow could not be read"
|
|
898
|
+
)
|
|
899
|
+
);
|
|
900
|
+
} finally {
|
|
901
|
+
if (request === previewRequest.current) setPreviewingN8n(false);
|
|
902
|
+
}
|
|
903
|
+
};
|
|
841
904
|
const parse = (value) => {
|
|
842
905
|
setTypeScript(null);
|
|
843
906
|
setIssues(null);
|
|
844
907
|
setSubmitted(false);
|
|
908
|
+
dropN8nPreview();
|
|
845
909
|
try {
|
|
846
910
|
const next = parseWorkflowImport(value);
|
|
847
911
|
setParsed(next);
|
|
848
912
|
setName(next.name);
|
|
849
913
|
setWorkflowKey("");
|
|
850
914
|
setVersion(next.version ?? "");
|
|
915
|
+
if (next.source === "n8n") void showN8nPreview(next);
|
|
851
916
|
} catch (error) {
|
|
852
917
|
setParsed(null);
|
|
853
918
|
toast.error(
|
|
@@ -1126,6 +1191,7 @@ function WorkflowImportDialog({
|
|
|
1126
1191
|
onChange: (event) => {
|
|
1127
1192
|
setRawJson(event.target.value);
|
|
1128
1193
|
setParsed(null);
|
|
1194
|
+
dropN8nPreview();
|
|
1129
1195
|
},
|
|
1130
1196
|
onBlur: () => rawJson.trim() && parse(rawJson),
|
|
1131
1197
|
placeholder: tr(
|
|
@@ -1140,7 +1206,20 @@ function WorkflowImportDialog({
|
|
|
1140
1206
|
}
|
|
1141
1207
|
),
|
|
1142
1208
|
(parsed || typeScript) && /* @__PURE__ */ jsxs("div", { className: "space-y-3 rounded-lg border border-border bg-muted/30 p-3", children: [
|
|
1143
|
-
parsed ? /* @__PURE__ */
|
|
1209
|
+
parsed?.source === "n8n" ? n8nPreview ? /* @__PURE__ */ jsx(N8nImportReport, { report: n8nPreview.report }) : /* @__PURE__ */ jsx(
|
|
1210
|
+
"p",
|
|
1211
|
+
{
|
|
1212
|
+
className: "text-xs text-muted-foreground",
|
|
1213
|
+
"data-testid": "fluidgrids-import-n8n-previewing",
|
|
1214
|
+
children: previewingN8n ? tr(
|
|
1215
|
+
"fluidgrids.workflowsList.importN8nPreviewing",
|
|
1216
|
+
"Reading the n8n workflow\u2026"
|
|
1217
|
+
) : tr(
|
|
1218
|
+
"fluidgrids.workflowsList.importN8nDetected",
|
|
1219
|
+
"n8n workflow detected"
|
|
1220
|
+
)
|
|
1221
|
+
}
|
|
1222
|
+
) : parsed ? /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
1144
1223
|
parsed.nodeReferences.length,
|
|
1145
1224
|
" ",
|
|
1146
1225
|
tr(
|
|
@@ -1223,7 +1302,7 @@ function WorkflowImportDialog({
|
|
|
1223
1302
|
Button,
|
|
1224
1303
|
{
|
|
1225
1304
|
onClick: () => void handleImport(),
|
|
1226
|
-
disabled: loading || !parsed && !typeScript || !name.trim(),
|
|
1305
|
+
disabled: loading || !parsed && !typeScript || !name.trim() || parsed?.source === "n8n" && !n8nPreview,
|
|
1227
1306
|
children: loading ? tr("fluidgrids.workflowsList.importing", "Importing\u2026") : tr("fluidgrids.workflowsList.importConfirm", "Import workflow")
|
|
1228
1307
|
}
|
|
1229
1308
|
)
|
|
@@ -2238,6 +2317,87 @@ function FirstWorkflowChecklist({
|
|
|
2238
2317
|
}
|
|
2239
2318
|
return /* @__PURE__ */ jsx(ChecklistWithRuns, { workflows, canCreate });
|
|
2240
2319
|
}
|
|
2320
|
+
var NO_PROJECT = "__none__";
|
|
2321
|
+
function WorkflowMoveToProjectDialog({
|
|
2322
|
+
workflow,
|
|
2323
|
+
onClose,
|
|
2324
|
+
onMoved
|
|
2325
|
+
}) {
|
|
2326
|
+
const tr = useTr();
|
|
2327
|
+
const { projects } = useWorkflowProjects();
|
|
2328
|
+
const { bulkAssignToProject, loading } = useBulkWorkflowActions();
|
|
2329
|
+
const [choice, setChoice] = useState(null);
|
|
2330
|
+
const current = workflow?.projectId ?? NO_PROJECT;
|
|
2331
|
+
const selected = choice ?? current;
|
|
2332
|
+
const close = () => {
|
|
2333
|
+
setChoice(null);
|
|
2334
|
+
onClose();
|
|
2335
|
+
};
|
|
2336
|
+
const move = async () => {
|
|
2337
|
+
if (!workflow) return;
|
|
2338
|
+
const result = await bulkAssignToProject(
|
|
2339
|
+
[workflow.id],
|
|
2340
|
+
selected === NO_PROJECT ? null : selected
|
|
2341
|
+
);
|
|
2342
|
+
if (!result || result.failedIds.length > 0) {
|
|
2343
|
+
toast.error(
|
|
2344
|
+
tr(
|
|
2345
|
+
"fluidgrids.workflowsList.moveToProject.failed",
|
|
2346
|
+
"The workflow couldn't be moved"
|
|
2347
|
+
)
|
|
2348
|
+
);
|
|
2349
|
+
return;
|
|
2350
|
+
}
|
|
2351
|
+
toast.success(
|
|
2352
|
+
tr("fluidgrids.workflowsList.moveToProject.moved", "Workflow moved")
|
|
2353
|
+
);
|
|
2354
|
+
setChoice(null);
|
|
2355
|
+
onMoved?.();
|
|
2356
|
+
onClose();
|
|
2357
|
+
};
|
|
2358
|
+
return /* @__PURE__ */ jsx(Dialog, { open: workflow !== null, onOpenChange: (open) => !open && close(), children: /* @__PURE__ */ jsxs(DialogContent, { "data-testid": "move-to-project-dialog", children: [
|
|
2359
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
2360
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: tr(
|
|
2361
|
+
"fluidgrids.workflowsList.moveToProject.title",
|
|
2362
|
+
"Move {{name}} to a project",
|
|
2363
|
+
{ name: workflow?.name ?? "" }
|
|
2364
|
+
) }),
|
|
2365
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: tr(
|
|
2366
|
+
"fluidgrids.workflowsList.moveToProject.description",
|
|
2367
|
+
"Every version moves, and new versions stay in the project."
|
|
2368
|
+
) })
|
|
2369
|
+
] }),
|
|
2370
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
2371
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "move-to-project-select", children: tr("fluidgrids.workflowsList.moveToProject.label", "Project") }),
|
|
2372
|
+
/* @__PURE__ */ jsxs(Select, { value: selected, onValueChange: setChoice, children: [
|
|
2373
|
+
/* @__PURE__ */ jsx(
|
|
2374
|
+
SelectTrigger,
|
|
2375
|
+
{
|
|
2376
|
+
id: "move-to-project-select",
|
|
2377
|
+
"data-testid": "move-to-project-select",
|
|
2378
|
+
children: /* @__PURE__ */ jsx(SelectValue, {})
|
|
2379
|
+
}
|
|
2380
|
+
),
|
|
2381
|
+
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
2382
|
+
/* @__PURE__ */ jsx(SelectItem, { value: NO_PROJECT, children: tr("fluidgrids.workflowsList.bulk.noProject", "No project") }),
|
|
2383
|
+
projects.map((project) => /* @__PURE__ */ jsx(SelectItem, { value: project.id, children: project.name }, project.id))
|
|
2384
|
+
] })
|
|
2385
|
+
] })
|
|
2386
|
+
] }),
|
|
2387
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
2388
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: close, disabled: loading, children: tr("fluidgrids.workflowsList.moveToProject.cancel", "Cancel") }),
|
|
2389
|
+
/* @__PURE__ */ jsx(
|
|
2390
|
+
Button,
|
|
2391
|
+
{
|
|
2392
|
+
onClick: () => void move(),
|
|
2393
|
+
disabled: loading || selected === current,
|
|
2394
|
+
"data-testid": "move-to-project-confirm",
|
|
2395
|
+
children: tr("fluidgrids.workflowsList.moveToProject.confirm", "Move")
|
|
2396
|
+
}
|
|
2397
|
+
)
|
|
2398
|
+
] })
|
|
2399
|
+
] }) });
|
|
2400
|
+
}
|
|
2241
2401
|
function useStatusFilters() {
|
|
2242
2402
|
const tr = useTr();
|
|
2243
2403
|
return useMemo(
|
|
@@ -2262,6 +2422,29 @@ function useStatusFilters() {
|
|
|
2262
2422
|
[tr]
|
|
2263
2423
|
);
|
|
2264
2424
|
}
|
|
2425
|
+
function useAccessFilters() {
|
|
2426
|
+
const tr = useTr();
|
|
2427
|
+
return useMemo(
|
|
2428
|
+
() => [
|
|
2429
|
+
{
|
|
2430
|
+
value: "ALL" /* All */,
|
|
2431
|
+
label: tr("fluidgrids.workflowsList.access.all", "All")
|
|
2432
|
+
},
|
|
2433
|
+
{
|
|
2434
|
+
value: "OWNED_BY_ME" /* OwnedByMe */,
|
|
2435
|
+
label: tr("fluidgrids.workflowsList.access.mine", "Mine")
|
|
2436
|
+
},
|
|
2437
|
+
{
|
|
2438
|
+
value: "SHARED_WITH_ME" /* SharedWithMe */,
|
|
2439
|
+
label: tr(
|
|
2440
|
+
"fluidgrids.workflowsList.access.sharedWithMe",
|
|
2441
|
+
"Shared with me"
|
|
2442
|
+
)
|
|
2443
|
+
}
|
|
2444
|
+
],
|
|
2445
|
+
[tr]
|
|
2446
|
+
);
|
|
2447
|
+
}
|
|
2265
2448
|
function SkeletonCard() {
|
|
2266
2449
|
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-40 flex-col justify-between rounded-xl border border-border bg-card p-6", children: [
|
|
2267
2450
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2.5", children: [
|
|
@@ -2279,10 +2462,19 @@ function WorkflowsList() {
|
|
|
2279
2462
|
const tr = useTr();
|
|
2280
2463
|
const navigate = useNavigate();
|
|
2281
2464
|
const STATUS_FILTERS = useStatusFilters();
|
|
2465
|
+
const ACCESS_FILTERS = useAccessFilters();
|
|
2466
|
+
const workspaceId = useContext(FluidGridsContext)?.workspaceId ?? "";
|
|
2467
|
+
const [accessFilter, setAccessFilter] = useState(
|
|
2468
|
+
"ALL" /* All */
|
|
2469
|
+
);
|
|
2282
2470
|
const { workflows, loading, error, tagsByKey, refetch } = useWorkflowDefinitions({
|
|
2283
2471
|
limit: 100,
|
|
2284
|
-
latestOnly: true
|
|
2472
|
+
latestOnly: true,
|
|
2473
|
+
...accessFilter === "ALL" /* All */ ? {} : { access: accessFilter }
|
|
2285
2474
|
});
|
|
2475
|
+
const [sharing, setSharing] = useState(null);
|
|
2476
|
+
const [moving, setMoving] = useState(null);
|
|
2477
|
+
const filteredByAccess = accessFilter !== "ALL" /* All */;
|
|
2286
2478
|
const { getWorkflow } = useLazyWorkflowDefinition();
|
|
2287
2479
|
const { allowed: canCreate } = useFluidGridsPermission(
|
|
2288
2480
|
FLUIDGRIDS_PERMISSIONS.WORKFLOW_CREATE
|
|
@@ -2469,7 +2661,7 @@ function WorkflowsList() {
|
|
|
2469
2661
|
}
|
|
2470
2662
|
),
|
|
2471
2663
|
!loading && !error && /* @__PURE__ */ jsx(FirstWorkflowChecklist, { workflows, canCreate }),
|
|
2472
|
-
!loading && !error && workflows.length > 0 && /* @__PURE__ */ jsxs(
|
|
2664
|
+
!loading && !error && (workflows.length > 0 || filteredByAccess) && /* @__PURE__ */ jsxs(
|
|
2473
2665
|
"div",
|
|
2474
2666
|
{
|
|
2475
2667
|
className: "flex flex-wrap items-center gap-3",
|
|
@@ -2507,6 +2699,29 @@ function WorkflowsList() {
|
|
|
2507
2699
|
onSelectProject: setProjectFilter
|
|
2508
2700
|
}
|
|
2509
2701
|
),
|
|
2702
|
+
/* @__PURE__ */ jsx(
|
|
2703
|
+
"div",
|
|
2704
|
+
{
|
|
2705
|
+
className: "flex flex-wrap items-center gap-1.5",
|
|
2706
|
+
role: "group",
|
|
2707
|
+
"aria-label": tr("fluidgrids.workflowsList.access.label", "Access"),
|
|
2708
|
+
"data-testid": "workflow-access-filter",
|
|
2709
|
+
children: ACCESS_FILTERS.map((option) => /* @__PURE__ */ jsx(
|
|
2710
|
+
"button",
|
|
2711
|
+
{
|
|
2712
|
+
type: "button",
|
|
2713
|
+
"aria-pressed": accessFilter === option.value,
|
|
2714
|
+
onClick: () => setAccessFilter(option.value),
|
|
2715
|
+
className: cn(
|
|
2716
|
+
"rounded-full border px-3 py-1 text-xs font-medium transition-colors",
|
|
2717
|
+
accessFilter === option.value ? "border-transparent bg-primary text-primary-foreground" : "border-border bg-card text-muted-foreground hover:text-foreground"
|
|
2718
|
+
),
|
|
2719
|
+
children: option.label
|
|
2720
|
+
},
|
|
2721
|
+
option.value
|
|
2722
|
+
))
|
|
2723
|
+
}
|
|
2724
|
+
),
|
|
2510
2725
|
/* @__PURE__ */ jsxs(
|
|
2511
2726
|
Button,
|
|
2512
2727
|
{
|
|
@@ -2603,7 +2818,7 @@ function WorkflowsList() {
|
|
|
2603
2818
|
/* @__PURE__ */ jsx(Icon, { icon: "mynaui:refresh", className: "size-4" }),
|
|
2604
2819
|
tr("fluidgrids.workflowsList.tryAgainButton", "Try again")
|
|
2605
2820
|
] })
|
|
2606
|
-
] }) }) : workflows.length === 0 ? /* @__PURE__ */ jsx("div", { className: "grid flex-1 place-items-center", children: /* @__PURE__ */ jsx(
|
|
2821
|
+
] }) }) : workflows.length === 0 && !filteredByAccess ? /* @__PURE__ */ jsx("div", { className: "grid flex-1 place-items-center", children: /* @__PURE__ */ jsx(
|
|
2607
2822
|
IllustratedEmptyState,
|
|
2608
2823
|
{
|
|
2609
2824
|
illustration: "onboarding",
|
|
@@ -2638,6 +2853,7 @@ function WorkflowsList() {
|
|
|
2638
2853
|
setSearch("");
|
|
2639
2854
|
setStatusFilter(null);
|
|
2640
2855
|
setTagFilter(null);
|
|
2856
|
+
setAccessFilter("ALL" /* All */);
|
|
2641
2857
|
},
|
|
2642
2858
|
children: tr(
|
|
2643
2859
|
"fluidgrids.workflowsList.clearFiltersButton",
|
|
@@ -2679,9 +2895,20 @@ function WorkflowsList() {
|
|
|
2679
2895
|
"Tag"
|
|
2680
2896
|
),
|
|
2681
2897
|
color: a.tagInfo?.color ?? void 0
|
|
2682
|
-
}))
|
|
2898
|
+
})),
|
|
2899
|
+
visibility: workflow.visibility ?? void 0,
|
|
2900
|
+
my_access: workflow.myAccess ?? null
|
|
2683
2901
|
},
|
|
2684
2902
|
onUpdateSuccess: () => refetch(),
|
|
2903
|
+
onShare: () => setSharing({
|
|
2904
|
+
workflowKey: workflow.workflowKey,
|
|
2905
|
+
name: workflow.name
|
|
2906
|
+
}),
|
|
2907
|
+
onMoveToProject: () => setMoving({
|
|
2908
|
+
id: workflow.id,
|
|
2909
|
+
name: workflow.name,
|
|
2910
|
+
projectId: workflow.projectId ?? null
|
|
2911
|
+
}),
|
|
2685
2912
|
onExport: () => void handleExport(workflow.id),
|
|
2686
2913
|
onExportAs: codeFirst ? (format) => void handleExportAs(
|
|
2687
2914
|
workflow.workflowKey,
|
|
@@ -2695,6 +2922,25 @@ function WorkflowsList() {
|
|
|
2695
2922
|
]
|
|
2696
2923
|
}
|
|
2697
2924
|
),
|
|
2925
|
+
/* @__PURE__ */ jsx(
|
|
2926
|
+
WorkflowShareDialog,
|
|
2927
|
+
{
|
|
2928
|
+
open: sharing !== null,
|
|
2929
|
+
onClose: () => setSharing(null),
|
|
2930
|
+
workflowKey: sharing?.workflowKey ?? null,
|
|
2931
|
+
workflowName: sharing?.name ?? "",
|
|
2932
|
+
workspaceId,
|
|
2933
|
+
onShared: () => void refetch()
|
|
2934
|
+
}
|
|
2935
|
+
),
|
|
2936
|
+
/* @__PURE__ */ jsx(
|
|
2937
|
+
WorkflowMoveToProjectDialog,
|
|
2938
|
+
{
|
|
2939
|
+
workflow: moving,
|
|
2940
|
+
onClose: () => setMoving(null),
|
|
2941
|
+
onMoved: () => void refetch()
|
|
2942
|
+
}
|
|
2943
|
+
),
|
|
2698
2944
|
/* @__PURE__ */ jsx(
|
|
2699
2945
|
CreateWorkflowRefusalDialog,
|
|
2700
2946
|
{
|