@burdenoff/fluidgrids-fe-sdk 2026.1110.2 → 2026.1110.3
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-UXQFBLF3.js → ExecutionDetailPage-7JT2YODS.js} +3 -4
- package/dist/{ExecutionsListPage-A4GCUNFR.js → ExecutionsListPage-JWQWJL2K.js} +3 -4
- package/dist/{WorkflowBuilder-ZLVMV2UA.js → WorkflowBuilder-D6LOQS4H.js} +8 -9
- package/dist/{agentTools-V26FOMTS.js → agentTools-73W5DJDQ.js} +1 -1
- package/dist/{chunk-PI4AW4T2.js → chunk-24VHW3ZF.js} +18 -17
- package/dist/{chunk-OVZA4IM7.js → chunk-2ZS2HN4T.js} +1 -1
- package/dist/{chunk-D4L5BN64.js → chunk-42PMXPHK.js} +93 -1
- package/dist/{chunk-WGUHISC2.js → chunk-6SEPRHQZ.js} +2 -2
- package/dist/{chunk-ZZBZPBO5.js → chunk-7XJKLVRJ.js} +1 -1
- package/dist/chunk-DZRVA4DL.js +172 -0
- package/dist/{chunk-OZNFRJKC.js → chunk-F4PAT5DP.js} +1 -1
- package/dist/{chunk-7UFE2CHD.js → chunk-H2B2J2PY.js} +23 -97
- package/dist/{chunk-CBX2CXGH.js → chunk-L2WJTIFQ.js} +2 -2
- package/dist/{chunk-5ZAOXCIQ.js → chunk-LCHXXVSV.js} +2 -2
- package/dist/{chunk-5TGPH3CX.js → chunk-M7USD2VH.js} +1 -1
- package/dist/chunk-QUYK5PAZ.js +338 -0
- package/dist/{chunk-XLU63IUB.js → chunk-WYNLB54U.js} +2 -2
- package/dist/{chunk-5V7PMLQN.js → chunk-XIB26SW6.js} +1116 -22
- package/dist/executions.js +4 -5
- package/dist/index.js +22 -23
- package/dist/{node-detail-view-2AFXRNX6.js → node-detail-view-5NBIDBIK.js} +5 -6
- package/dist/quick-config-panel-ETLKCV7H.js +411 -0
- package/dist/settings.js +3 -4
- package/dist/templates.js +8 -9
- package/dist/workflow-builder.js +9 -10
- package/package.json +1 -1
- package/dist/chunk-3JGAI5YC.js +0 -1437
- package/dist/chunk-HORSE7WX.js +0 -54
- package/dist/chunk-WZ3EJVS6.js +0 -93
- package/dist/quick-config-panel-U4AELSCT.js +0 -363
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { asRecord, ConditionTreeBuilder, SwitchRulesEditor, casesFromRules, isStringOptionList, optionText, coerceNumber, paramsFromOperation, resolveLoadOptionsSpec, optionListValues, parseMappingValue, optionListText } from './chunk-
|
|
1
|
+
import { asRecord, ConditionTreeBuilder, SwitchRulesEditor, casesFromRules, isStringOptionList, optionText, coerceNumber, nodeTitle, paramsFromOperation, resolveLoadOptionsSpec, optionListValues, parseMappingValue, optionListText } from './chunk-24VHW3ZF.js';
|
|
2
2
|
import { CodeEditorField, normalizeCodeLanguage } from './chunk-KZCNJAMK.js';
|
|
3
3
|
import { readAssertRulesSetting, rowsFromRules, normaliseAssertRules, ruleFromRow, describeAssertRuleProblem, operatorSpec, ASSERT_OPERATORS, emptyAssertRuleRow } from './chunk-JDLQ6QIB.js';
|
|
4
|
-
import { AgentDefinitionSelectField, ConnectionSelector } from './chunk-
|
|
5
|
-
import { isAgentNodeType } from './chunk-
|
|
4
|
+
import { AgentDefinitionSelectField, ConnectionSelector } from './chunk-7XJKLVRJ.js';
|
|
5
|
+
import { useResource, describeSchedule, NativeSelect, StatusPill, FieldError, isAgentNodeType, triggerSchedule, pauseSchedule, unpauseSchedule, backfillSchedule } from './chunk-42PMXPHK.js';
|
|
6
6
|
import { FluidGridsContext, isParamVisible, structuredParameterType, useRunGuard, formatParameterValue, parseParameterValue, useFluidGridsAnalytics, openRunQuotaUpgradePrompt } from './chunk-DDINUPO3.js';
|
|
7
7
|
import { useBuilderReadOnly } from './chunk-SDZEAIIE.js';
|
|
8
8
|
import { useFlowStore } from './chunk-K2X63CR2.js';
|
|
@@ -10,20 +10,443 @@ import { getGlobalStoreClient } from './chunk-TYI2XOSI.js';
|
|
|
10
10
|
import { cn } from './chunk-JL7CASN5.js';
|
|
11
11
|
import { useRunFromNodeEligibilityQuery, PreviewScheduleDocument, WebhookTestListenerDocument, StopWebhookTestListenerDocument, ListenForWebhookTestEventDocument } from './chunk-A6Q4FWB6.js';
|
|
12
12
|
import { useTr } from './chunk-UULVIT25.js';
|
|
13
|
-
import {
|
|
13
|
+
import { getFluidGridsClient, getFluidGridsClientSafe } from './chunk-PDODDDHY.js';
|
|
14
14
|
import { throwIfResultError, describeOperationError } from './chunk-JKLZ6YZ3.js';
|
|
15
15
|
import { cn as cn$1 } from '@burdenoff/fe-libs/utils';
|
|
16
16
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
17
17
|
import * as React from 'react';
|
|
18
|
-
import { useContext, useId,
|
|
19
|
-
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
18
|
+
import { useState, useContext, useId, useRef, useCallback, useEffect, useMemo } from 'react';
|
|
20
19
|
import { Icon } from '@iconify/react';
|
|
20
|
+
import { Button } from '@burdenoff/fe-libs/button';
|
|
21
|
+
import { Label, Input, Switch, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuItem, Card, Button as Button$1 } from '@burdenoff/fe-libs/ui';
|
|
22
|
+
import { toast } from 'sonner';
|
|
23
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
21
24
|
import { gql } from '@apollo/client';
|
|
22
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuItem, Card, Button } from '@burdenoff/fe-libs/ui';
|
|
23
25
|
import cronstrue from 'cronstrue';
|
|
24
26
|
import { digest } from 'ohash';
|
|
25
27
|
import { X, Plus } from 'lucide-react';
|
|
26
28
|
|
|
29
|
+
function TabButton({
|
|
30
|
+
active,
|
|
31
|
+
onClick,
|
|
32
|
+
children,
|
|
33
|
+
testId
|
|
34
|
+
}) {
|
|
35
|
+
return /* @__PURE__ */ jsx(
|
|
36
|
+
"button",
|
|
37
|
+
{
|
|
38
|
+
type: "button",
|
|
39
|
+
onClick,
|
|
40
|
+
"data-testid": testId,
|
|
41
|
+
className: cn$1(
|
|
42
|
+
"-mb-px border-b-2 py-2.5 text-sm transition-colors",
|
|
43
|
+
active ? "border-primary font-medium text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"
|
|
44
|
+
),
|
|
45
|
+
children
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
var SCHEDULE_NODE_TYPE = "internal:schedule";
|
|
50
|
+
var OVERLAP_POLICIES = [
|
|
51
|
+
"SKIP" /* Skip */,
|
|
52
|
+
"BUFFER_ONE" /* BufferOne */,
|
|
53
|
+
"BUFFER_ALL" /* BufferAll */,
|
|
54
|
+
"CANCEL_OTHER" /* CancelOther */,
|
|
55
|
+
"TERMINATE_OTHER" /* TerminateOther */,
|
|
56
|
+
"ALLOW_ALL" /* AllowAll */
|
|
57
|
+
];
|
|
58
|
+
var MAX_BACKFILL = 1e3;
|
|
59
|
+
function overlapPolicyOf(value) {
|
|
60
|
+
return OVERLAP_POLICIES.find((policy) => policy === value) ?? null;
|
|
61
|
+
}
|
|
62
|
+
function secondsOf(value) {
|
|
63
|
+
if (typeof value === "number" && Number.isFinite(value) && value >= 0)
|
|
64
|
+
return value;
|
|
65
|
+
if (typeof value !== "string") return null;
|
|
66
|
+
const match = /^(\d+)\s*(s|m|h|d)?$/.exec(value.trim());
|
|
67
|
+
if (!match) return null;
|
|
68
|
+
const unit = { s: 1, m: 60, h: 3600, d: 86400 }[match[2] ?? "s"] ?? 1;
|
|
69
|
+
return Number(match[1]) * unit;
|
|
70
|
+
}
|
|
71
|
+
function SchedulePanel({
|
|
72
|
+
state,
|
|
73
|
+
writeField,
|
|
74
|
+
workflowKey,
|
|
75
|
+
triggerNodeId,
|
|
76
|
+
canExecute,
|
|
77
|
+
canUpdate
|
|
78
|
+
}) {
|
|
79
|
+
const tr = useTr();
|
|
80
|
+
const policy = overlapPolicyOf(state.overlapPolicy);
|
|
81
|
+
const catchup = secondsOf(state.catchupWindow);
|
|
82
|
+
const limited = typeof state.limitedActions === "number" ? state.limitedActions : null;
|
|
83
|
+
const describe = useResource(
|
|
84
|
+
workflowKey ? `schedule:${workflowKey}:${triggerNodeId}` : null,
|
|
85
|
+
!!workflowKey,
|
|
86
|
+
() => describeSchedule(workflowKey ?? "", triggerNodeId)
|
|
87
|
+
);
|
|
88
|
+
const [note, setNote] = useState("");
|
|
89
|
+
const [from, setFrom] = useState("");
|
|
90
|
+
const [to, setTo] = useState("");
|
|
91
|
+
const [busy, setBusy] = useState(null);
|
|
92
|
+
const [error, setError] = useState(null);
|
|
93
|
+
const act = async (name, run) => {
|
|
94
|
+
setBusy(name);
|
|
95
|
+
setError(null);
|
|
96
|
+
try {
|
|
97
|
+
await run();
|
|
98
|
+
} catch (err) {
|
|
99
|
+
setError(describeOperationError(err));
|
|
100
|
+
} finally {
|
|
101
|
+
setBusy(null);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const live = describe.data;
|
|
105
|
+
const backfillFrom = from ? new Date(from) : null;
|
|
106
|
+
const backfillTo = to ? new Date(to) : null;
|
|
107
|
+
const backfillValid = !!backfillFrom && !!backfillTo && !Number.isNaN(backfillFrom.getTime()) && !Number.isNaN(backfillTo.getTime()) && backfillFrom < backfillTo && backfillTo.getTime() <= Date.now();
|
|
108
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-5 p-4", "data-testid": "schedule-panel", children: [
|
|
109
|
+
/* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
|
|
110
|
+
/* @__PURE__ */ jsx("h4", { className: "text-sm font-semibold text-foreground", children: tr("fluidgrids.builder.schedule.policy", "Policy") }),
|
|
111
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
112
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "schedule-overlap", children: tr(
|
|
113
|
+
"fluidgrids.builder.schedule.overlap",
|
|
114
|
+
"When the previous run is still open"
|
|
115
|
+
) }),
|
|
116
|
+
/* @__PURE__ */ jsxs(
|
|
117
|
+
NativeSelect,
|
|
118
|
+
{
|
|
119
|
+
id: "schedule-overlap",
|
|
120
|
+
value: policy ?? "",
|
|
121
|
+
disabled: !canUpdate,
|
|
122
|
+
onChange: (value) => writeField("overlapPolicy", overlapPolicyOf(value) ?? void 0),
|
|
123
|
+
testId: "schedule-overlap",
|
|
124
|
+
children: [
|
|
125
|
+
/* @__PURE__ */ jsx("option", { value: "", children: tr(
|
|
126
|
+
"fluidgrids.builder.schedule.overlapLegacy",
|
|
127
|
+
"Start every run (no policy)"
|
|
128
|
+
) }),
|
|
129
|
+
/* @__PURE__ */ jsx("option", { value: "SKIP" /* Skip */, children: tr("fluidgrids.builder.schedule.skip", "Skip the fire") }),
|
|
130
|
+
/* @__PURE__ */ jsx("option", { value: "BUFFER_ONE" /* BufferOne */, children: tr(
|
|
131
|
+
"fluidgrids.builder.schedule.bufferOne",
|
|
132
|
+
"Run once after it ends"
|
|
133
|
+
) }),
|
|
134
|
+
/* @__PURE__ */ jsx("option", { value: "BUFFER_ALL" /* BufferAll */, children: tr(
|
|
135
|
+
"fluidgrids.builder.schedule.bufferAll",
|
|
136
|
+
"Run every missed fire after it ends"
|
|
137
|
+
) }),
|
|
138
|
+
/* @__PURE__ */ jsx("option", { value: "CANCEL_OTHER" /* CancelOther */, children: tr(
|
|
139
|
+
"fluidgrids.builder.schedule.cancelOther",
|
|
140
|
+
"Cancel it and start"
|
|
141
|
+
) }),
|
|
142
|
+
/* @__PURE__ */ jsx("option", { value: "TERMINATE_OTHER" /* TerminateOther */, children: tr(
|
|
143
|
+
"fluidgrids.builder.schedule.terminateOther",
|
|
144
|
+
"Terminate it and start"
|
|
145
|
+
) }),
|
|
146
|
+
/* @__PURE__ */ jsx("option", { value: "ALLOW_ALL" /* AllowAll */, children: tr("fluidgrids.builder.schedule.allowAll", "Start anyway") })
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
),
|
|
150
|
+
!policy && canUpdate && /* @__PURE__ */ jsx(
|
|
151
|
+
Button,
|
|
152
|
+
{
|
|
153
|
+
size: "sm",
|
|
154
|
+
variant: "link",
|
|
155
|
+
className: "h-auto p-0 text-xs",
|
|
156
|
+
onClick: () => writeField("overlapPolicy", "SKIP" /* Skip */),
|
|
157
|
+
"data-testid": "schedule-use-policy",
|
|
158
|
+
children: tr(
|
|
159
|
+
"fluidgrids.builder.schedule.usePolicy",
|
|
160
|
+
"Use a policy (skip while a run is open)"
|
|
161
|
+
)
|
|
162
|
+
}
|
|
163
|
+
)
|
|
164
|
+
] }),
|
|
165
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [
|
|
166
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
167
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "schedule-catchup", children: tr(
|
|
168
|
+
"fluidgrids.builder.schedule.catchup",
|
|
169
|
+
"Catch-up window (seconds)"
|
|
170
|
+
) }),
|
|
171
|
+
/* @__PURE__ */ jsx(
|
|
172
|
+
Input,
|
|
173
|
+
{
|
|
174
|
+
id: "schedule-catchup",
|
|
175
|
+
inputMode: "numeric",
|
|
176
|
+
disabled: !canUpdate,
|
|
177
|
+
value: catchup === null ? "" : String(catchup),
|
|
178
|
+
onChange: (event) => {
|
|
179
|
+
const value = event.target.value.trim();
|
|
180
|
+
writeField(
|
|
181
|
+
"catchupWindow",
|
|
182
|
+
value === "" ? void 0 : /^\d+$/.test(value) ? Math.min(Number(value), 604800) : state.catchupWindow
|
|
183
|
+
);
|
|
184
|
+
},
|
|
185
|
+
"data-testid": "schedule-catchup"
|
|
186
|
+
}
|
|
187
|
+
)
|
|
188
|
+
] }),
|
|
189
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
190
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "schedule-limited", children: tr(
|
|
191
|
+
"fluidgrids.builder.schedule.limited",
|
|
192
|
+
"Stop after this many runs (optional)"
|
|
193
|
+
) }),
|
|
194
|
+
/* @__PURE__ */ jsx(
|
|
195
|
+
Input,
|
|
196
|
+
{
|
|
197
|
+
id: "schedule-limited",
|
|
198
|
+
inputMode: "numeric",
|
|
199
|
+
disabled: !canUpdate,
|
|
200
|
+
value: limited === null ? "" : String(limited),
|
|
201
|
+
onChange: (event) => {
|
|
202
|
+
const value = event.target.value.trim();
|
|
203
|
+
writeField(
|
|
204
|
+
"limitedActions",
|
|
205
|
+
value === "" ? void 0 : /^\d+$/.test(value) ? Number(value) : state.limitedActions
|
|
206
|
+
);
|
|
207
|
+
},
|
|
208
|
+
"data-testid": "schedule-limited"
|
|
209
|
+
}
|
|
210
|
+
)
|
|
211
|
+
] })
|
|
212
|
+
] }),
|
|
213
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center justify-between gap-3 text-sm text-foreground", children: [
|
|
214
|
+
tr(
|
|
215
|
+
"fluidgrids.builder.schedule.pauseOnFailure",
|
|
216
|
+
"Pause the schedule when a run it started fails"
|
|
217
|
+
),
|
|
218
|
+
/* @__PURE__ */ jsx(
|
|
219
|
+
Switch,
|
|
220
|
+
{
|
|
221
|
+
checked: state.pauseOnFailure === true,
|
|
222
|
+
disabled: !canUpdate,
|
|
223
|
+
onCheckedChange: (checked) => writeField("pauseOnFailure", checked ? true : void 0),
|
|
224
|
+
"data-testid": "schedule-pause-on-failure"
|
|
225
|
+
}
|
|
226
|
+
)
|
|
227
|
+
] }),
|
|
228
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: tr(
|
|
229
|
+
"fluidgrids.builder.schedule.saveHint",
|
|
230
|
+
"Policy changes apply when the workflow is saved and activated."
|
|
231
|
+
) })
|
|
232
|
+
] }),
|
|
233
|
+
!workflowKey ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: tr(
|
|
234
|
+
"fluidgrids.builder.schedule.unsaved",
|
|
235
|
+
"Save the workflow to see and control its schedule."
|
|
236
|
+
) }) : /* @__PURE__ */ jsxs("section", { className: "space-y-3", "data-testid": "schedule-live", children: [
|
|
237
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
238
|
+
/* @__PURE__ */ jsx("h4", { className: "text-sm font-semibold text-foreground", children: tr("fluidgrids.builder.schedule.live", "Schedule") }),
|
|
239
|
+
live && /* @__PURE__ */ jsx(
|
|
240
|
+
StatusPill,
|
|
241
|
+
{
|
|
242
|
+
tone: live.state.paused ? "warning" : "success",
|
|
243
|
+
testId: "schedule-state",
|
|
244
|
+
children: live.state.paused ? tr("fluidgrids.builder.schedule.paused", "Paused") : tr("fluidgrids.builder.schedule.active", "Active")
|
|
245
|
+
}
|
|
246
|
+
),
|
|
247
|
+
/* @__PURE__ */ jsx(
|
|
248
|
+
Button,
|
|
249
|
+
{
|
|
250
|
+
size: "sm",
|
|
251
|
+
variant: "ghost",
|
|
252
|
+
className: "ml-auto",
|
|
253
|
+
onClick: () => void describe.refetch(),
|
|
254
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: "mdi:refresh", width: 14 })
|
|
255
|
+
}
|
|
256
|
+
)
|
|
257
|
+
] }),
|
|
258
|
+
/* @__PURE__ */ jsx(
|
|
259
|
+
FieldError,
|
|
260
|
+
{
|
|
261
|
+
message: describe.error,
|
|
262
|
+
testId: "schedule-describe-error"
|
|
263
|
+
}
|
|
264
|
+
),
|
|
265
|
+
live?.state.paused && live.state.note && /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground", "data-testid": "schedule-note", children: live.state.note }),
|
|
266
|
+
live && /* @__PURE__ */ jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [
|
|
267
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
268
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: tr("fluidgrids.builder.schedule.next", "Next fire times") }),
|
|
269
|
+
/* @__PURE__ */ jsxs(
|
|
270
|
+
"ul",
|
|
271
|
+
{
|
|
272
|
+
className: "space-y-0.5 font-mono text-xs text-foreground",
|
|
273
|
+
"data-testid": "schedule-next",
|
|
274
|
+
children: [
|
|
275
|
+
live.nextFireTimes.slice(0, 5).map((time) => /* @__PURE__ */ jsx("li", { children: new Date(time).toLocaleString() }, time)),
|
|
276
|
+
live.nextFireTimes.length === 0 && /* @__PURE__ */ jsx("li", { children: "\u2014" })
|
|
277
|
+
]
|
|
278
|
+
}
|
|
279
|
+
)
|
|
280
|
+
] }),
|
|
281
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
282
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: tr("fluidgrids.builder.schedule.recent", "Recent actions") }),
|
|
283
|
+
/* @__PURE__ */ jsxs(
|
|
284
|
+
"ul",
|
|
285
|
+
{
|
|
286
|
+
className: "space-y-0.5 text-xs text-foreground",
|
|
287
|
+
"data-testid": "schedule-recent",
|
|
288
|
+
children: [
|
|
289
|
+
live.recentActions.slice(0, 5).map((tick) => /* @__PURE__ */ jsxs("li", { children: [
|
|
290
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono", children: new Date(tick.dueAt).toLocaleString() }),
|
|
291
|
+
" ",
|
|
292
|
+
"\xB7 ",
|
|
293
|
+
tick.kind,
|
|
294
|
+
" \xB7 ",
|
|
295
|
+
tick.outcome
|
|
296
|
+
] }, tick.id)),
|
|
297
|
+
live.recentActions.length === 0 && /* @__PURE__ */ jsx("li", { children: "\u2014" })
|
|
298
|
+
]
|
|
299
|
+
}
|
|
300
|
+
)
|
|
301
|
+
] })
|
|
302
|
+
] }),
|
|
303
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
304
|
+
canExecute && /* @__PURE__ */ jsxs(
|
|
305
|
+
Button,
|
|
306
|
+
{
|
|
307
|
+
size: "sm",
|
|
308
|
+
variant: "outline",
|
|
309
|
+
disabled: busy !== null,
|
|
310
|
+
onClick: () => void act("trigger", async () => {
|
|
311
|
+
const result = await triggerSchedule({
|
|
312
|
+
workflowKey,
|
|
313
|
+
triggerNodeId
|
|
314
|
+
});
|
|
315
|
+
toast.success(
|
|
316
|
+
result.runId ? tr(
|
|
317
|
+
"fluidgrids.builder.schedule.triggered",
|
|
318
|
+
"Run started"
|
|
319
|
+
) : tr(
|
|
320
|
+
"fluidgrids.builder.schedule.triggeredOutcome",
|
|
321
|
+
"Tick recorded: {{outcome}}",
|
|
322
|
+
{ outcome: result.tick.outcome }
|
|
323
|
+
)
|
|
324
|
+
);
|
|
325
|
+
await describe.refetch();
|
|
326
|
+
}),
|
|
327
|
+
"data-testid": "schedule-trigger",
|
|
328
|
+
children: [
|
|
329
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:play", className: "mr-1", width: 14 }),
|
|
330
|
+
tr("fluidgrids.builder.schedule.trigger", "Trigger now")
|
|
331
|
+
]
|
|
332
|
+
}
|
|
333
|
+
),
|
|
334
|
+
canUpdate && live && !live.state.paused && /* @__PURE__ */ jsxs(
|
|
335
|
+
Button,
|
|
336
|
+
{
|
|
337
|
+
size: "sm",
|
|
338
|
+
variant: "outline",
|
|
339
|
+
disabled: busy !== null,
|
|
340
|
+
onClick: () => void act("pause", async () => {
|
|
341
|
+
describe.set(
|
|
342
|
+
await pauseSchedule({ workflowKey, triggerNodeId, note })
|
|
343
|
+
);
|
|
344
|
+
setNote("");
|
|
345
|
+
}),
|
|
346
|
+
"data-testid": "schedule-pause",
|
|
347
|
+
children: [
|
|
348
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:pause", className: "mr-1", width: 14 }),
|
|
349
|
+
tr("fluidgrids.builder.schedule.pause", "Pause")
|
|
350
|
+
]
|
|
351
|
+
}
|
|
352
|
+
),
|
|
353
|
+
canUpdate && live?.state.paused && /* @__PURE__ */ jsxs(
|
|
354
|
+
Button,
|
|
355
|
+
{
|
|
356
|
+
size: "sm",
|
|
357
|
+
variant: "outline",
|
|
358
|
+
disabled: busy !== null,
|
|
359
|
+
onClick: () => void act(
|
|
360
|
+
"unpause",
|
|
361
|
+
async () => describe.set(
|
|
362
|
+
await unpauseSchedule({ workflowKey, triggerNodeId })
|
|
363
|
+
)
|
|
364
|
+
),
|
|
365
|
+
"data-testid": "schedule-unpause",
|
|
366
|
+
children: [
|
|
367
|
+
/* @__PURE__ */ jsx(Icon, { icon: "mdi:play-pause", className: "mr-1", width: 14 }),
|
|
368
|
+
tr("fluidgrids.builder.schedule.unpause", "Unpause")
|
|
369
|
+
]
|
|
370
|
+
}
|
|
371
|
+
)
|
|
372
|
+
] }),
|
|
373
|
+
canUpdate && live && !live.state.paused && /* @__PURE__ */ jsx(
|
|
374
|
+
Input,
|
|
375
|
+
{
|
|
376
|
+
value: note,
|
|
377
|
+
maxLength: 1e3,
|
|
378
|
+
placeholder: tr(
|
|
379
|
+
"fluidgrids.builder.schedule.notePlaceholder",
|
|
380
|
+
"Note for the pause (optional)"
|
|
381
|
+
),
|
|
382
|
+
onChange: (event) => setNote(event.target.value),
|
|
383
|
+
"data-testid": "schedule-pause-note"
|
|
384
|
+
}
|
|
385
|
+
),
|
|
386
|
+
canExecute && /* @__PURE__ */ jsxs("div", { className: "space-y-2 rounded-md border border-border p-3", children: [
|
|
387
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: tr("fluidgrids.builder.schedule.backfill", "Backfill") }),
|
|
388
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-2 sm:grid-cols-2", children: [
|
|
389
|
+
/* @__PURE__ */ jsx(
|
|
390
|
+
Input,
|
|
391
|
+
{
|
|
392
|
+
type: "datetime-local",
|
|
393
|
+
value: from,
|
|
394
|
+
onChange: (event) => setFrom(event.target.value),
|
|
395
|
+
"aria-label": tr("fluidgrids.builder.schedule.from", "From"),
|
|
396
|
+
"data-testid": "schedule-backfill-from"
|
|
397
|
+
}
|
|
398
|
+
),
|
|
399
|
+
/* @__PURE__ */ jsx(
|
|
400
|
+
Input,
|
|
401
|
+
{
|
|
402
|
+
type: "datetime-local",
|
|
403
|
+
value: to,
|
|
404
|
+
onChange: (event) => setTo(event.target.value),
|
|
405
|
+
"aria-label": tr("fluidgrids.builder.schedule.to", "To"),
|
|
406
|
+
"data-testid": "schedule-backfill-to"
|
|
407
|
+
}
|
|
408
|
+
)
|
|
409
|
+
] }),
|
|
410
|
+
/* @__PURE__ */ jsx(
|
|
411
|
+
Button,
|
|
412
|
+
{
|
|
413
|
+
size: "sm",
|
|
414
|
+
variant: "outline",
|
|
415
|
+
disabled: !backfillValid || busy !== null,
|
|
416
|
+
onClick: () => void act("backfill", async () => {
|
|
417
|
+
if (!backfillFrom || !backfillTo) return;
|
|
418
|
+
const result = await backfillSchedule({
|
|
419
|
+
workflowKey,
|
|
420
|
+
triggerNodeId,
|
|
421
|
+
from: backfillFrom.toISOString(),
|
|
422
|
+
to: backfillTo.toISOString()
|
|
423
|
+
});
|
|
424
|
+
toast.success(
|
|
425
|
+
tr(
|
|
426
|
+
"fluidgrids.builder.schedule.backfilled",
|
|
427
|
+
"{{queued}} of {{fireTimes}} fire times queued",
|
|
428
|
+
{ queued: result.queued, fireTimes: result.fireTimes }
|
|
429
|
+
)
|
|
430
|
+
);
|
|
431
|
+
await describe.refetch();
|
|
432
|
+
}),
|
|
433
|
+
"data-testid": "schedule-backfill",
|
|
434
|
+
children: tr(
|
|
435
|
+
"fluidgrids.builder.schedule.runBackfill",
|
|
436
|
+
"Run the fire times in this range"
|
|
437
|
+
)
|
|
438
|
+
}
|
|
439
|
+
),
|
|
440
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: tr(
|
|
441
|
+
"fluidgrids.builder.schedule.backfillHint",
|
|
442
|
+
"At most {{max}} past fire times; each started run counts toward the monthly runs.",
|
|
443
|
+
{ max: MAX_BACKFILL }
|
|
444
|
+
) })
|
|
445
|
+
] }),
|
|
446
|
+
/* @__PURE__ */ jsx(FieldError, { message: error, testId: "schedule-error" })
|
|
447
|
+
] })
|
|
448
|
+
] });
|
|
449
|
+
}
|
|
27
450
|
function ReadOnlyFieldset({
|
|
28
451
|
className,
|
|
29
452
|
children
|
|
@@ -4476,7 +4899,7 @@ function ChannelAuthButton({
|
|
|
4476
4899
|
const tr = useTr();
|
|
4477
4900
|
const providerKey = PLATFORM_TO_PROVIDER_KEY[channel.platform] || channel.platform.toLowerCase();
|
|
4478
4901
|
return /* @__PURE__ */ jsxs(
|
|
4479
|
-
Button,
|
|
4902
|
+
Button$1,
|
|
4480
4903
|
{
|
|
4481
4904
|
type: "button",
|
|
4482
4905
|
variant: "outline",
|
|
@@ -4562,7 +4985,7 @@ function ChannelLinkAction({
|
|
|
4562
4985
|
const linking = state.kind === "linking";
|
|
4563
4986
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4564
4987
|
/* @__PURE__ */ jsxs(
|
|
4565
|
-
Button,
|
|
4988
|
+
Button$1,
|
|
4566
4989
|
{
|
|
4567
4990
|
type: "button",
|
|
4568
4991
|
variant: "outline",
|
|
@@ -4884,7 +5307,7 @@ function NodeParamsForm({
|
|
|
4884
5307
|
const highlight = dragField === p.name;
|
|
4885
5308
|
const controlId = `${formId}-param-${p.name}`;
|
|
4886
5309
|
const nativeControl = mode !== "expression" && !isCodeParam && !(structuredType && !optionList) && !p.loadOptions && !isChannelPicker && p.type !== PLATFORM_EVENT_MODULE_FIELD && p.type !== PLATFORM_EVENT_RECORD_TYPE_FIELD && p.type !== TIMECAMPUS_TIME_TRIGGER_FIELD;
|
|
4887
|
-
const
|
|
5310
|
+
const inputCx2 = cn$1(
|
|
4888
5311
|
"w-full rounded-md border bg-background px-2.5 py-1.5 text-sm outline-none transition-colors disabled:opacity-50",
|
|
4889
5312
|
highlight ? "border-primary ring-1 ring-primary" : "border-input focus:border-primary"
|
|
4890
5313
|
);
|
|
@@ -4982,7 +5405,7 @@ function NodeParamsForm({
|
|
|
4982
5405
|
schema: p.schema ?? p.type,
|
|
4983
5406
|
value: fixedValue,
|
|
4984
5407
|
onChange: (value) => writeFixed(p.name, value),
|
|
4985
|
-
className: cn$1(
|
|
5408
|
+
className: cn$1(inputCx2, "font-mono"),
|
|
4986
5409
|
testId: `${testIdPrefix}-param-${p.name}`
|
|
4987
5410
|
},
|
|
4988
5411
|
`${config.node?.id}:${config.currentOp?.name}:${p.name}`
|
|
@@ -5013,7 +5436,7 @@ function NodeParamsForm({
|
|
|
5013
5436
|
connectionId: loadOptionsConnectionId,
|
|
5014
5437
|
value: fixedValue,
|
|
5015
5438
|
onChange: (v) => writeFixed(p.name, v),
|
|
5016
|
-
className:
|
|
5439
|
+
className: inputCx2,
|
|
5017
5440
|
testId: `${testIdPrefix}-param-${p.name}`
|
|
5018
5441
|
}
|
|
5019
5442
|
) : isChannelPicker ? /* @__PURE__ */ jsx(
|
|
@@ -5030,7 +5453,7 @@ function NodeParamsForm({
|
|
|
5030
5453
|
),
|
|
5031
5454
|
nodeId: config.node?.id,
|
|
5032
5455
|
label: p.label ?? p.name,
|
|
5033
|
-
className:
|
|
5456
|
+
className: inputCx2,
|
|
5034
5457
|
testId: `${testIdPrefix}-param-${p.name}`
|
|
5035
5458
|
}
|
|
5036
5459
|
) : p.type === "boolean" ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
@@ -5089,7 +5512,7 @@ function NodeParamsForm({
|
|
|
5089
5512
|
if (typeField && previous !== next)
|
|
5090
5513
|
writeFixed(typeField.name, void 0);
|
|
5091
5514
|
},
|
|
5092
|
-
className:
|
|
5515
|
+
className: inputCx2,
|
|
5093
5516
|
testId: `${testIdPrefix}-param-${p.name}`
|
|
5094
5517
|
}
|
|
5095
5518
|
) : p.type === PLATFORM_EVENT_RECORD_TYPE_FIELD ? /* @__PURE__ */ jsx(
|
|
@@ -5107,7 +5530,7 @@ function NodeParamsForm({
|
|
|
5107
5530
|
required: p.required,
|
|
5108
5531
|
label: p.label,
|
|
5109
5532
|
onChange: (next) => writeFixed(p.name, next || void 0),
|
|
5110
|
-
className:
|
|
5533
|
+
className: inputCx2,
|
|
5111
5534
|
testId: `${testIdPrefix}-param-${p.name}`
|
|
5112
5535
|
}
|
|
5113
5536
|
) : p.type === TIMECAMPUS_TIME_TRIGGER_FIELD ? /* @__PURE__ */ jsx(
|
|
@@ -5116,7 +5539,7 @@ function NodeParamsForm({
|
|
|
5116
5539
|
value: fixedValue,
|
|
5117
5540
|
label: p.label,
|
|
5118
5541
|
onChange: (next) => writeFixed(p.name, next || void 0),
|
|
5119
|
-
className:
|
|
5542
|
+
className: inputCx2,
|
|
5120
5543
|
testId: `${testIdPrefix}-param-${p.name}`
|
|
5121
5544
|
}
|
|
5122
5545
|
) : p.type === "timezone" ? /* @__PURE__ */ jsx(
|
|
@@ -5124,7 +5547,7 @@ function NodeParamsForm({
|
|
|
5124
5547
|
{
|
|
5125
5548
|
value: typeof fixedValue === "string" ? fixedValue : "",
|
|
5126
5549
|
onChange: (zone) => writeFixed(p.name, zone),
|
|
5127
|
-
className:
|
|
5550
|
+
className: inputCx2,
|
|
5128
5551
|
testId: `${testIdPrefix}-param-${p.name}`
|
|
5129
5552
|
}
|
|
5130
5553
|
) : p.type === "multiOptions" && p.options && p.options.length > 0 ? /* @__PURE__ */ jsx(
|
|
@@ -5179,7 +5602,7 @@ function NodeParamsForm({
|
|
|
5179
5602
|
id: controlId,
|
|
5180
5603
|
"data-testid": `${testIdPrefix}-param-${p.name}`,
|
|
5181
5604
|
className: cn$1(
|
|
5182
|
-
|
|
5605
|
+
inputCx2,
|
|
5183
5606
|
"scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary"
|
|
5184
5607
|
),
|
|
5185
5608
|
children: [
|
|
@@ -5204,7 +5627,7 @@ function NodeParamsForm({
|
|
|
5204
5627
|
onChange: (e) => writeFixed(p.name, coerceNumber(p.type, e.target.value)),
|
|
5205
5628
|
id: controlId,
|
|
5206
5629
|
"data-testid": `${testIdPrefix}-param-${p.name}`,
|
|
5207
|
-
className:
|
|
5630
|
+
className: inputCx2
|
|
5208
5631
|
}
|
|
5209
5632
|
) : p.type === "string" && p.isMultiline && !p.secret ? /* @__PURE__ */ jsx(
|
|
5210
5633
|
"textarea",
|
|
@@ -5219,7 +5642,7 @@ function NodeParamsForm({
|
|
|
5219
5642
|
"aria-label": p.label ?? p.name,
|
|
5220
5643
|
id: controlId,
|
|
5221
5644
|
"data-testid": `${testIdPrefix}-param-${p.name}`,
|
|
5222
|
-
className: cn$1(
|
|
5645
|
+
className: cn$1(inputCx2, "min-h-24 resize-y")
|
|
5223
5646
|
}
|
|
5224
5647
|
) : /* @__PURE__ */ jsx(
|
|
5225
5648
|
"input",
|
|
@@ -5236,7 +5659,7 @@ function NodeParamsForm({
|
|
|
5236
5659
|
"aria-label": p.label ?? p.name,
|
|
5237
5660
|
id: controlId,
|
|
5238
5661
|
"data-testid": `${testIdPrefix}-param-${p.name}`,
|
|
5239
|
-
className:
|
|
5662
|
+
className: inputCx2
|
|
5240
5663
|
}
|
|
5241
5664
|
),
|
|
5242
5665
|
p.description && /* @__PURE__ */ jsx("span", { className: "text-[11px] leading-snug text-muted-foreground", children: p.description })
|
|
@@ -5247,6 +5670,677 @@ function NodeParamsForm({
|
|
|
5247
5670
|
})
|
|
5248
5671
|
] });
|
|
5249
5672
|
}
|
|
5673
|
+
var RUNNER_FIELDS = gql`
|
|
5674
|
+
fragment SandboxRunnerFields on SandboxRunner {
|
|
5675
|
+
id
|
|
5676
|
+
name
|
|
5677
|
+
status
|
|
5678
|
+
hostname
|
|
5679
|
+
os
|
|
5680
|
+
arch
|
|
5681
|
+
driver
|
|
5682
|
+
version
|
|
5683
|
+
capacity
|
|
5684
|
+
privateNetwork {
|
|
5685
|
+
target
|
|
5686
|
+
ports
|
|
5687
|
+
nodes
|
|
5688
|
+
}
|
|
5689
|
+
tokenPrefix
|
|
5690
|
+
lastSeenAt
|
|
5691
|
+
connectedAt
|
|
5692
|
+
createdBy
|
|
5693
|
+
createdAt
|
|
5694
|
+
}
|
|
5695
|
+
`;
|
|
5696
|
+
var LIST_RUNNERS = gql`
|
|
5697
|
+
${RUNNER_FIELDS}
|
|
5698
|
+
query SandboxRunners {
|
|
5699
|
+
sandboxRunners(context: {}) {
|
|
5700
|
+
...SandboxRunnerFields
|
|
5701
|
+
}
|
|
5702
|
+
}
|
|
5703
|
+
`;
|
|
5704
|
+
var CREATE_RUNNER = gql`
|
|
5705
|
+
${RUNNER_FIELDS}
|
|
5706
|
+
mutation CreateSandboxRunner($name: String!) {
|
|
5707
|
+
createSandboxRunner(input: { name: $name, context: {} }) {
|
|
5708
|
+
token
|
|
5709
|
+
bridgeUrl
|
|
5710
|
+
runner {
|
|
5711
|
+
...SandboxRunnerFields
|
|
5712
|
+
}
|
|
5713
|
+
}
|
|
5714
|
+
}
|
|
5715
|
+
`;
|
|
5716
|
+
var ROTATE_RUNNER_TOKEN = gql`
|
|
5717
|
+
${RUNNER_FIELDS}
|
|
5718
|
+
mutation RotateSandboxRunnerToken($id: ID!) {
|
|
5719
|
+
rotateSandboxRunnerToken(id: $id, context: {}) {
|
|
5720
|
+
token
|
|
5721
|
+
bridgeUrl
|
|
5722
|
+
runner {
|
|
5723
|
+
...SandboxRunnerFields
|
|
5724
|
+
}
|
|
5725
|
+
}
|
|
5726
|
+
}
|
|
5727
|
+
`;
|
|
5728
|
+
var DELETE_RUNNER = gql`
|
|
5729
|
+
mutation DeleteSandboxRunner($id: ID!) {
|
|
5730
|
+
deleteSandboxRunner(id: $id, context: {})
|
|
5731
|
+
}
|
|
5732
|
+
`;
|
|
5733
|
+
var RUNNER_INSTALL_SCRIPT_URL = "https://www.fluidgrids.ai/downloads/runner/install.sh";
|
|
5734
|
+
function runnerInstallCommand(bridgeUrl) {
|
|
5735
|
+
const base = `curl -fsSL ${RUNNER_INSTALL_SCRIPT_URL} | sh`;
|
|
5736
|
+
return bridgeUrl && bridgeUrl !== DEFAULT_BRIDGE_URL ? `${base} -s -- --url ${bridgeUrl}` : base;
|
|
5737
|
+
}
|
|
5738
|
+
var DEFAULT_BRIDGE_URL = "wss://graphqlworkspaces.burdenoff.com/runner-bridge";
|
|
5739
|
+
function useRunners(options) {
|
|
5740
|
+
const [runners, setRunners] = useState([]);
|
|
5741
|
+
const [loading, setLoading] = useState(!options?.skip);
|
|
5742
|
+
const [error, setError] = useState(null);
|
|
5743
|
+
const mounted = useRef(true);
|
|
5744
|
+
const fetchRunners = useCallback(async () => {
|
|
5745
|
+
if (options?.skip) return;
|
|
5746
|
+
try {
|
|
5747
|
+
const result = await getFluidGridsClient().query({ query: LIST_RUNNERS, fetchPolicy: "network-only" });
|
|
5748
|
+
if (!mounted.current) return;
|
|
5749
|
+
setRunners(result.data?.sandboxRunners ?? []);
|
|
5750
|
+
setError(null);
|
|
5751
|
+
} catch (err) {
|
|
5752
|
+
if (mounted.current) setError(err);
|
|
5753
|
+
} finally {
|
|
5754
|
+
if (mounted.current) setLoading(false);
|
|
5755
|
+
}
|
|
5756
|
+
}, [options?.skip]);
|
|
5757
|
+
useEffect(() => {
|
|
5758
|
+
mounted.current = true;
|
|
5759
|
+
void fetchRunners();
|
|
5760
|
+
const pollMs = options?.pollMs ?? 1e4;
|
|
5761
|
+
const timer = pollMs > 0 ? setInterval(fetchRunners, pollMs) : null;
|
|
5762
|
+
return () => {
|
|
5763
|
+
mounted.current = false;
|
|
5764
|
+
if (timer) clearInterval(timer);
|
|
5765
|
+
};
|
|
5766
|
+
}, [fetchRunners, options?.pollMs]);
|
|
5767
|
+
return { runners, loading, error, refetch: fetchRunners };
|
|
5768
|
+
}
|
|
5769
|
+
function useRunnerActions() {
|
|
5770
|
+
const [busy, setBusy] = useState(false);
|
|
5771
|
+
const run = useCallback(async (fn) => {
|
|
5772
|
+
setBusy(true);
|
|
5773
|
+
try {
|
|
5774
|
+
return await fn();
|
|
5775
|
+
} finally {
|
|
5776
|
+
setBusy(false);
|
|
5777
|
+
}
|
|
5778
|
+
}, []);
|
|
5779
|
+
const createRunner = useCallback(
|
|
5780
|
+
(name) => run(async () => {
|
|
5781
|
+
const result = throwIfResultError(
|
|
5782
|
+
await getFluidGridsClient().mutate({ mutation: CREATE_RUNNER, variables: { name } })
|
|
5783
|
+
);
|
|
5784
|
+
if (!result.data?.createSandboxRunner)
|
|
5785
|
+
throw new Error("No runner returned");
|
|
5786
|
+
return result.data.createSandboxRunner;
|
|
5787
|
+
}),
|
|
5788
|
+
[run]
|
|
5789
|
+
);
|
|
5790
|
+
const rotateToken = useCallback(
|
|
5791
|
+
(id) => run(async () => {
|
|
5792
|
+
const result = throwIfResultError(
|
|
5793
|
+
await getFluidGridsClient().mutate({ mutation: ROTATE_RUNNER_TOKEN, variables: { id } })
|
|
5794
|
+
);
|
|
5795
|
+
if (!result.data?.rotateSandboxRunnerToken)
|
|
5796
|
+
throw new Error("No runner returned");
|
|
5797
|
+
return result.data.rotateSandboxRunnerToken;
|
|
5798
|
+
}),
|
|
5799
|
+
[run]
|
|
5800
|
+
);
|
|
5801
|
+
const deleteRunner = useCallback(
|
|
5802
|
+
(id) => run(async () => {
|
|
5803
|
+
const result = throwIfResultError(
|
|
5804
|
+
await getFluidGridsClient().mutate({
|
|
5805
|
+
mutation: DELETE_RUNNER,
|
|
5806
|
+
variables: { id }
|
|
5807
|
+
})
|
|
5808
|
+
);
|
|
5809
|
+
return result.data?.deleteSandboxRunner === true;
|
|
5810
|
+
}),
|
|
5811
|
+
[run]
|
|
5812
|
+
);
|
|
5813
|
+
return { createRunner, rotateToken, deleteRunner, busy };
|
|
5814
|
+
}
|
|
5815
|
+
var STYLES = {
|
|
5816
|
+
ONLINE: "border-status-success-border bg-status-success-bg-subtle text-status-success-text",
|
|
5817
|
+
OFFLINE: "border-border-default bg-bg-sunken text-text-muted",
|
|
5818
|
+
NEVER_CONNECTED: "border-status-warning-border bg-status-warning-bg-subtle text-status-warning-text"
|
|
5819
|
+
};
|
|
5820
|
+
function RunnerStatusPill({
|
|
5821
|
+
status,
|
|
5822
|
+
className
|
|
5823
|
+
}) {
|
|
5824
|
+
const tr = useTr();
|
|
5825
|
+
const label = status === "ONLINE" ? tr("fluidgrids.runners.online", "Online") : status === "OFFLINE" ? tr("fluidgrids.runners.offline", "Offline") : tr("fluidgrids.runners.neverConnected", "Not connected yet");
|
|
5826
|
+
return /* @__PURE__ */ jsx(
|
|
5827
|
+
"span",
|
|
5828
|
+
{
|
|
5829
|
+
className: cn$1(
|
|
5830
|
+
"inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium",
|
|
5831
|
+
STYLES[status],
|
|
5832
|
+
className
|
|
5833
|
+
),
|
|
5834
|
+
"data-testid": "runner-status",
|
|
5835
|
+
"data-status": status,
|
|
5836
|
+
children: label
|
|
5837
|
+
}
|
|
5838
|
+
);
|
|
5839
|
+
}
|
|
5840
|
+
var CLOUD = "__fluidgrids_cloud__";
|
|
5841
|
+
function RunOnSection({
|
|
5842
|
+
value,
|
|
5843
|
+
onChange,
|
|
5844
|
+
sectionLabelClassName
|
|
5845
|
+
}) {
|
|
5846
|
+
const tr = useTr();
|
|
5847
|
+
const { runners, loading } = useRunners({ pollMs: 15e3 });
|
|
5848
|
+
const selected = value ? runners.find((r) => r.id === value.runnerId) : void 0;
|
|
5849
|
+
return /* @__PURE__ */ jsxs("section", { className: "space-y-2", "data-testid": "ndv-settings-run-on", children: [
|
|
5850
|
+
/* @__PURE__ */ jsx("div", { className: sectionLabelClassName, children: tr("fluidgrids.builder.nodeSettings.runOn", "Run on") }),
|
|
5851
|
+
/* @__PURE__ */ jsxs(
|
|
5852
|
+
Select,
|
|
5853
|
+
{
|
|
5854
|
+
value: value?.runnerId ?? CLOUD,
|
|
5855
|
+
onValueChange: (v) => onChange(v === CLOUD ? null : { kind: "runner", runnerId: v }),
|
|
5856
|
+
children: [
|
|
5857
|
+
/* @__PURE__ */ jsx(
|
|
5858
|
+
SelectTrigger,
|
|
5859
|
+
{
|
|
5860
|
+
className: "w-full",
|
|
5861
|
+
"data-testid": "ndv-settings-run-on-select",
|
|
5862
|
+
children: /* @__PURE__ */ jsx(SelectValue, {})
|
|
5863
|
+
}
|
|
5864
|
+
),
|
|
5865
|
+
/* @__PURE__ */ jsxs(
|
|
5866
|
+
SelectContent,
|
|
5867
|
+
{
|
|
5868
|
+
style: { zIndex: 1100 },
|
|
5869
|
+
"data-testid": "ndv-settings-run-on-options",
|
|
5870
|
+
children: [
|
|
5871
|
+
/* @__PURE__ */ jsx(SelectItem, { value: CLOUD, "data-testid": "run-on-cloud", children: tr(
|
|
5872
|
+
"fluidgrids.builder.nodeSettings.runOnCloud",
|
|
5873
|
+
"FluidGrids Cloud (default)"
|
|
5874
|
+
) }),
|
|
5875
|
+
runners.map((runner) => /* @__PURE__ */ jsxs(
|
|
5876
|
+
SelectItem,
|
|
5877
|
+
{
|
|
5878
|
+
value: runner.id,
|
|
5879
|
+
"data-testid": "run-on-runner-option",
|
|
5880
|
+
children: [
|
|
5881
|
+
runner.name,
|
|
5882
|
+
runner.status !== "ONLINE" ? ` (${runner.status === "OFFLINE" ? tr("fluidgrids.runners.offline", "Offline") : tr("fluidgrids.runners.neverConnected", "Not connected yet")})` : ""
|
|
5883
|
+
]
|
|
5884
|
+
},
|
|
5885
|
+
runner.id
|
|
5886
|
+
)),
|
|
5887
|
+
value && !loading && !selected && /* @__PURE__ */ jsx(SelectItem, { value: value.runnerId, disabled: true, children: tr(
|
|
5888
|
+
"fluidgrids.builder.nodeSettings.runOnMissing",
|
|
5889
|
+
"Removed runner"
|
|
5890
|
+
) })
|
|
5891
|
+
]
|
|
5892
|
+
}
|
|
5893
|
+
)
|
|
5894
|
+
]
|
|
5895
|
+
}
|
|
5896
|
+
),
|
|
5897
|
+
value ? /* @__PURE__ */ jsxs("div", { className: "space-y-1 text-xs text-text-secondary", children: [
|
|
5898
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
|
|
5899
|
+
selected && /* @__PURE__ */ jsx(RunnerStatusPill, { status: selected.status }),
|
|
5900
|
+
/* @__PURE__ */ jsx("span", { children: tr(
|
|
5901
|
+
"fluidgrids.builder.nodeSettings.runOnRunnerHint",
|
|
5902
|
+
"This node runs on your runner, in a local sandbox. If the runner is offline the node fails \u2014 it never falls back to FluidGrids Cloud. The node's input and the credentials it uses are sent to that machine."
|
|
5903
|
+
) })
|
|
5904
|
+
] }),
|
|
5905
|
+
selected && /* @__PURE__ */ jsx("p", { "data-testid": "run-on-private-network", children: (selected.privateNetwork ?? []).length === 0 ? tr(
|
|
5906
|
+
"fluidgrids.builder.nodeSettings.runOnPublicOnly",
|
|
5907
|
+
"On this runner, nodes reach the public internet only. Private destinations are opened on the runner machine (fluidgrids-runner network allow)."
|
|
5908
|
+
) : tr(
|
|
5909
|
+
"fluidgrids.builder.nodeSettings.runOnPrivateNetwork",
|
|
5910
|
+
"This runner opens {{count}} private destination(s) \u2014 see Runners for which nodes may use them.",
|
|
5911
|
+
{ count: (selected.privateNetwork ?? []).length }
|
|
5912
|
+
) })
|
|
5913
|
+
] }) : /* @__PURE__ */ jsx("p", { className: "text-xs text-text-secondary", children: runners.length === 0 && !loading ? tr(
|
|
5914
|
+
"fluidgrids.builder.nodeSettings.runOnNoRunners",
|
|
5915
|
+
"Runs in FluidGrids Cloud. Add a runner under Workflows \u2192 Runners to run nodes on your own machine."
|
|
5916
|
+
) : tr(
|
|
5917
|
+
"fluidgrids.builder.nodeSettings.runOnCloudHint",
|
|
5918
|
+
"Runs in FluidGrids Cloud."
|
|
5919
|
+
) })
|
|
5920
|
+
] });
|
|
5921
|
+
}
|
|
5922
|
+
var SECTION_LABEL4 = "text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground";
|
|
5923
|
+
var inputCx = "w-full rounded-md border border-input bg-background px-2.5 py-1.5 text-sm outline-none transition-colors focus:border-primary disabled:opacity-50";
|
|
5924
|
+
function msToSeconds(ms, fallbackMs) {
|
|
5925
|
+
return Math.round((ms ?? fallbackMs) / 1e3 * 10) / 10;
|
|
5926
|
+
}
|
|
5927
|
+
function secondsInputToMs(raw, minMs) {
|
|
5928
|
+
const seconds = parseFloat(raw);
|
|
5929
|
+
if (Number.isNaN(seconds)) return minMs;
|
|
5930
|
+
return Math.max(minMs, Math.round(seconds * 1e3));
|
|
5931
|
+
}
|
|
5932
|
+
function NodeSettingsPanel({
|
|
5933
|
+
config
|
|
5934
|
+
}) {
|
|
5935
|
+
const tr = useTr();
|
|
5936
|
+
const {
|
|
5937
|
+
nodes,
|
|
5938
|
+
node,
|
|
5939
|
+
errorConfig,
|
|
5940
|
+
writeErrorConfig,
|
|
5941
|
+
notes,
|
|
5942
|
+
writeNotes,
|
|
5943
|
+
alwaysOutputData,
|
|
5944
|
+
executeOnce,
|
|
5945
|
+
runOn,
|
|
5946
|
+
writeExecutionSettings
|
|
5947
|
+
} = config;
|
|
5948
|
+
const onError = errorConfig?.onError ?? "stop";
|
|
5949
|
+
const retryEnabled = (errorConfig?.retryConfig?.maxRetries ?? 0) > 0;
|
|
5950
|
+
const timeoutEnabled = !!errorConfig?.timeout?.duration;
|
|
5951
|
+
const branchTargets = nodes.filter((n) => n.id !== node?.id);
|
|
5952
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-6", "data-testid": "ndv-settings-panel", children: [
|
|
5953
|
+
/* @__PURE__ */ jsx(
|
|
5954
|
+
RunOnSection,
|
|
5955
|
+
{
|
|
5956
|
+
value: runOn,
|
|
5957
|
+
onChange: (next) => writeExecutionSettings({ runOn: next }),
|
|
5958
|
+
sectionLabelClassName: SECTION_LABEL4
|
|
5959
|
+
}
|
|
5960
|
+
),
|
|
5961
|
+
/* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
|
|
5962
|
+
/* @__PURE__ */ jsx("div", { className: SECTION_LABEL4, children: tr("fluidgrids.builder.nodeSettings.retrySection", "Retry on Fail") }),
|
|
5963
|
+
/* @__PURE__ */ jsxs("label", { className: "flex w-fit cursor-pointer items-center gap-2 text-sm", children: [
|
|
5964
|
+
/* @__PURE__ */ jsx(
|
|
5965
|
+
"input",
|
|
5966
|
+
{
|
|
5967
|
+
type: "checkbox",
|
|
5968
|
+
checked: retryEnabled,
|
|
5969
|
+
onChange: (e) => writeErrorConfig({
|
|
5970
|
+
retryConfig: e.target.checked ? {
|
|
5971
|
+
maxRetries: errorConfig?.retryConfig?.maxRetries || 3,
|
|
5972
|
+
retryDelay: errorConfig?.retryConfig?.retryDelay || 1e3,
|
|
5973
|
+
backoffMultiplier: errorConfig?.retryConfig?.backoffMultiplier ?? 2,
|
|
5974
|
+
maxDelay: errorConfig?.retryConfig?.maxDelay ?? 3e4
|
|
5975
|
+
} : void 0
|
|
5976
|
+
}),
|
|
5977
|
+
"data-testid": "ndv-settings-retry-enabled",
|
|
5978
|
+
className: "size-4"
|
|
5979
|
+
}
|
|
5980
|
+
),
|
|
5981
|
+
/* @__PURE__ */ jsx("span", { children: tr(
|
|
5982
|
+
"fluidgrids.builder.nodeSettings.retryEnabledLabel",
|
|
5983
|
+
"Retry this node on failure"
|
|
5984
|
+
) })
|
|
5985
|
+
] }),
|
|
5986
|
+
retryEnabled && /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 pl-6", children: [
|
|
5987
|
+
/* @__PURE__ */ jsx(
|
|
5988
|
+
Field,
|
|
5989
|
+
{
|
|
5990
|
+
label: tr(
|
|
5991
|
+
"fluidgrids.builder.nodeSettings.maxRetries",
|
|
5992
|
+
"Max tries"
|
|
5993
|
+
),
|
|
5994
|
+
children: /* @__PURE__ */ jsx(
|
|
5995
|
+
"input",
|
|
5996
|
+
{
|
|
5997
|
+
type: "number",
|
|
5998
|
+
min: 1,
|
|
5999
|
+
max: 20,
|
|
6000
|
+
value: errorConfig?.retryConfig?.maxRetries ?? 3,
|
|
6001
|
+
onChange: (e) => writeErrorConfig({
|
|
6002
|
+
retryConfig: {
|
|
6003
|
+
...errorConfig?.retryConfig ?? {
|
|
6004
|
+
retryDelay: 1e3,
|
|
6005
|
+
maxRetries: 3
|
|
6006
|
+
},
|
|
6007
|
+
maxRetries: Math.max(
|
|
6008
|
+
1,
|
|
6009
|
+
parseInt(e.target.value, 10) || 1
|
|
6010
|
+
)
|
|
6011
|
+
}
|
|
6012
|
+
}),
|
|
6013
|
+
"data-testid": "ndv-settings-max-retries",
|
|
6014
|
+
className: inputCx
|
|
6015
|
+
}
|
|
6016
|
+
)
|
|
6017
|
+
}
|
|
6018
|
+
),
|
|
6019
|
+
/* @__PURE__ */ jsx(
|
|
6020
|
+
Field,
|
|
6021
|
+
{
|
|
6022
|
+
label: tr(
|
|
6023
|
+
"fluidgrids.builder.nodeSettings.retryDelay",
|
|
6024
|
+
"Wait (seconds)"
|
|
6025
|
+
),
|
|
6026
|
+
children: /* @__PURE__ */ jsx(
|
|
6027
|
+
"input",
|
|
6028
|
+
{
|
|
6029
|
+
type: "number",
|
|
6030
|
+
min: 0,
|
|
6031
|
+
step: 0.1,
|
|
6032
|
+
value: msToSeconds(errorConfig?.retryConfig?.retryDelay, 1e3),
|
|
6033
|
+
onChange: (e) => writeErrorConfig({
|
|
6034
|
+
retryConfig: {
|
|
6035
|
+
...errorConfig?.retryConfig ?? {
|
|
6036
|
+
maxRetries: 3,
|
|
6037
|
+
retryDelay: 1e3
|
|
6038
|
+
},
|
|
6039
|
+
retryDelay: secondsInputToMs(e.target.value, 0)
|
|
6040
|
+
}
|
|
6041
|
+
}),
|
|
6042
|
+
"data-testid": "ndv-settings-retry-delay",
|
|
6043
|
+
className: inputCx
|
|
6044
|
+
}
|
|
6045
|
+
)
|
|
6046
|
+
}
|
|
6047
|
+
),
|
|
6048
|
+
/* @__PURE__ */ jsx(
|
|
6049
|
+
Field,
|
|
6050
|
+
{
|
|
6051
|
+
label: tr(
|
|
6052
|
+
"fluidgrids.builder.nodeSettings.backoffMultiplier",
|
|
6053
|
+
"Backoff \xD7"
|
|
6054
|
+
),
|
|
6055
|
+
children: /* @__PURE__ */ jsx(
|
|
6056
|
+
"input",
|
|
6057
|
+
{
|
|
6058
|
+
type: "number",
|
|
6059
|
+
min: 1,
|
|
6060
|
+
step: 0.5,
|
|
6061
|
+
value: errorConfig?.retryConfig?.backoffMultiplier ?? 2,
|
|
6062
|
+
onChange: (e) => writeErrorConfig({
|
|
6063
|
+
retryConfig: {
|
|
6064
|
+
...errorConfig?.retryConfig ?? {
|
|
6065
|
+
maxRetries: 3,
|
|
6066
|
+
retryDelay: 1e3
|
|
6067
|
+
},
|
|
6068
|
+
backoffMultiplier: parseFloat(e.target.value) || 1
|
|
6069
|
+
}
|
|
6070
|
+
}),
|
|
6071
|
+
"data-testid": "ndv-settings-backoff-multiplier",
|
|
6072
|
+
className: inputCx
|
|
6073
|
+
}
|
|
6074
|
+
)
|
|
6075
|
+
}
|
|
6076
|
+
),
|
|
6077
|
+
/* @__PURE__ */ jsx(
|
|
6078
|
+
Field,
|
|
6079
|
+
{
|
|
6080
|
+
label: tr(
|
|
6081
|
+
"fluidgrids.builder.nodeSettings.maxDelay",
|
|
6082
|
+
"Max wait (seconds)"
|
|
6083
|
+
),
|
|
6084
|
+
children: /* @__PURE__ */ jsx(
|
|
6085
|
+
"input",
|
|
6086
|
+
{
|
|
6087
|
+
type: "number",
|
|
6088
|
+
min: 0,
|
|
6089
|
+
step: 1,
|
|
6090
|
+
value: msToSeconds(errorConfig?.retryConfig?.maxDelay, 3e4),
|
|
6091
|
+
onChange: (e) => writeErrorConfig({
|
|
6092
|
+
retryConfig: {
|
|
6093
|
+
...errorConfig?.retryConfig ?? {
|
|
6094
|
+
maxRetries: 3,
|
|
6095
|
+
retryDelay: 1e3
|
|
6096
|
+
},
|
|
6097
|
+
maxDelay: secondsInputToMs(e.target.value, 0)
|
|
6098
|
+
}
|
|
6099
|
+
}),
|
|
6100
|
+
"data-testid": "ndv-settings-max-delay",
|
|
6101
|
+
className: inputCx
|
|
6102
|
+
}
|
|
6103
|
+
)
|
|
6104
|
+
}
|
|
6105
|
+
)
|
|
6106
|
+
] })
|
|
6107
|
+
] }),
|
|
6108
|
+
/* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
|
|
6109
|
+
/* @__PURE__ */ jsx("div", { className: SECTION_LABEL4, children: tr("fluidgrids.builder.nodeSettings.onErrorSection", "On Error") }),
|
|
6110
|
+
/* @__PURE__ */ jsxs(
|
|
6111
|
+
"select",
|
|
6112
|
+
{
|
|
6113
|
+
value: onError,
|
|
6114
|
+
onChange: (e) => writeErrorConfig({
|
|
6115
|
+
onError: e.target.value,
|
|
6116
|
+
errorBranchId: e.target.value === "branch" ? errorConfig?.errorBranchId : void 0
|
|
6117
|
+
}),
|
|
6118
|
+
"data-testid": "ndv-settings-on-error",
|
|
6119
|
+
className: cn$1(inputCx, "max-w-xs"),
|
|
6120
|
+
children: [
|
|
6121
|
+
/* @__PURE__ */ jsx("option", { value: "stop", children: tr(
|
|
6122
|
+
"fluidgrids.builder.nodeSettings.onErrorStop",
|
|
6123
|
+
"Stop workflow (default)"
|
|
6124
|
+
) }),
|
|
6125
|
+
/* @__PURE__ */ jsx("option", { value: "continue", children: tr(
|
|
6126
|
+
"fluidgrids.builder.nodeSettings.onErrorContinue",
|
|
6127
|
+
"Continue on fail"
|
|
6128
|
+
) }),
|
|
6129
|
+
/* @__PURE__ */ jsx("option", { value: "branch", children: tr(
|
|
6130
|
+
"fluidgrids.builder.nodeSettings.onErrorBranch",
|
|
6131
|
+
"Route to error branch"
|
|
6132
|
+
) })
|
|
6133
|
+
]
|
|
6134
|
+
}
|
|
6135
|
+
),
|
|
6136
|
+
onError === "branch" && /* @__PURE__ */ jsx("div", { className: "pl-2", children: /* @__PURE__ */ jsx(
|
|
6137
|
+
Field,
|
|
6138
|
+
{
|
|
6139
|
+
label: tr(
|
|
6140
|
+
"fluidgrids.builder.nodeSettings.errorBranchTarget",
|
|
6141
|
+
"Error branch target"
|
|
6142
|
+
),
|
|
6143
|
+
children: /* @__PURE__ */ jsxs(
|
|
6144
|
+
"select",
|
|
6145
|
+
{
|
|
6146
|
+
value: errorConfig?.errorBranchId ?? "",
|
|
6147
|
+
onChange: (e) => writeErrorConfig({
|
|
6148
|
+
errorBranchId: e.target.value || void 0
|
|
6149
|
+
}),
|
|
6150
|
+
"data-testid": "ndv-settings-error-branch-id",
|
|
6151
|
+
className: cn$1(inputCx, "max-w-xs"),
|
|
6152
|
+
children: [
|
|
6153
|
+
/* @__PURE__ */ jsx("option", { value: "", children: tr(
|
|
6154
|
+
"fluidgrids.builder.nodeSettings.selectNode",
|
|
6155
|
+
"Select a node\u2026"
|
|
6156
|
+
) }),
|
|
6157
|
+
branchTargets.map((n) => /* @__PURE__ */ jsx("option", { value: n.id, children: nodeTitle(n) }, n.id))
|
|
6158
|
+
]
|
|
6159
|
+
}
|
|
6160
|
+
)
|
|
6161
|
+
}
|
|
6162
|
+
) })
|
|
6163
|
+
] }),
|
|
6164
|
+
/* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
|
|
6165
|
+
/* @__PURE__ */ jsx("div", { className: SECTION_LABEL4, children: tr("fluidgrids.builder.nodeSettings.timeoutSection", "Timeout") }),
|
|
6166
|
+
/* @__PURE__ */ jsxs("label", { className: "flex w-fit cursor-pointer items-center gap-2 text-sm", children: [
|
|
6167
|
+
/* @__PURE__ */ jsx(
|
|
6168
|
+
"input",
|
|
6169
|
+
{
|
|
6170
|
+
type: "checkbox",
|
|
6171
|
+
checked: timeoutEnabled,
|
|
6172
|
+
onChange: (e) => writeErrorConfig({
|
|
6173
|
+
timeout: e.target.checked ? { duration: errorConfig?.timeout?.duration || 3e4 } : void 0
|
|
6174
|
+
}),
|
|
6175
|
+
"data-testid": "ndv-settings-timeout-enabled",
|
|
6176
|
+
className: "size-4"
|
|
6177
|
+
}
|
|
6178
|
+
),
|
|
6179
|
+
/* @__PURE__ */ jsx("span", { children: tr(
|
|
6180
|
+
"fluidgrids.builder.nodeSettings.timeoutEnabledLabel",
|
|
6181
|
+
"Abort this node if it runs too long"
|
|
6182
|
+
) })
|
|
6183
|
+
] }),
|
|
6184
|
+
timeoutEnabled && /* @__PURE__ */ jsxs("div", { className: "space-y-3 pl-6", children: [
|
|
6185
|
+
/* @__PURE__ */ jsx(
|
|
6186
|
+
Field,
|
|
6187
|
+
{
|
|
6188
|
+
label: tr(
|
|
6189
|
+
"fluidgrids.builder.nodeSettings.timeoutDuration",
|
|
6190
|
+
"Timeout (seconds)"
|
|
6191
|
+
),
|
|
6192
|
+
children: /* @__PURE__ */ jsx(
|
|
6193
|
+
"input",
|
|
6194
|
+
{
|
|
6195
|
+
type: "number",
|
|
6196
|
+
min: 0.1,
|
|
6197
|
+
step: 0.5,
|
|
6198
|
+
value: msToSeconds(errorConfig?.timeout?.duration, 3e4),
|
|
6199
|
+
onChange: (e) => writeErrorConfig({
|
|
6200
|
+
timeout: {
|
|
6201
|
+
...errorConfig?.timeout ?? { duration: 3e4 },
|
|
6202
|
+
duration: secondsInputToMs(e.target.value, 100)
|
|
6203
|
+
}
|
|
6204
|
+
}),
|
|
6205
|
+
"data-testid": "ndv-settings-timeout-duration",
|
|
6206
|
+
className: cn$1(inputCx, "max-w-[10rem]")
|
|
6207
|
+
}
|
|
6208
|
+
)
|
|
6209
|
+
}
|
|
6210
|
+
),
|
|
6211
|
+
/* @__PURE__ */ jsx(
|
|
6212
|
+
Field,
|
|
6213
|
+
{
|
|
6214
|
+
label: tr(
|
|
6215
|
+
"fluidgrids.builder.nodeSettings.onTimeout",
|
|
6216
|
+
"On timeout"
|
|
6217
|
+
),
|
|
6218
|
+
children: /* @__PURE__ */ jsxs(
|
|
6219
|
+
"select",
|
|
6220
|
+
{
|
|
6221
|
+
value: errorConfig?.timeout?.onTimeout ?? "stop",
|
|
6222
|
+
onChange: (e) => writeErrorConfig({
|
|
6223
|
+
timeout: {
|
|
6224
|
+
...errorConfig?.timeout ?? { duration: 3e4 },
|
|
6225
|
+
onTimeout: e.target.value,
|
|
6226
|
+
timeoutBranchId: e.target.value === "branch" ? errorConfig?.timeout?.timeoutBranchId : void 0
|
|
6227
|
+
}
|
|
6228
|
+
}),
|
|
6229
|
+
"data-testid": "ndv-settings-on-timeout",
|
|
6230
|
+
className: cn$1(inputCx, "max-w-xs"),
|
|
6231
|
+
children: [
|
|
6232
|
+
/* @__PURE__ */ jsx("option", { value: "stop", children: tr(
|
|
6233
|
+
"fluidgrids.builder.nodeSettings.onTimeoutStop",
|
|
6234
|
+
"Use Retry/On Error settings above"
|
|
6235
|
+
) }),
|
|
6236
|
+
/* @__PURE__ */ jsx("option", { value: "continue", children: tr(
|
|
6237
|
+
"fluidgrids.builder.nodeSettings.onTimeoutContinue",
|
|
6238
|
+
"Continue on timeout"
|
|
6239
|
+
) }),
|
|
6240
|
+
/* @__PURE__ */ jsx("option", { value: "branch", children: tr(
|
|
6241
|
+
"fluidgrids.builder.nodeSettings.onTimeoutBranch",
|
|
6242
|
+
"Route to a specific branch"
|
|
6243
|
+
) })
|
|
6244
|
+
]
|
|
6245
|
+
}
|
|
6246
|
+
)
|
|
6247
|
+
}
|
|
6248
|
+
),
|
|
6249
|
+
errorConfig?.timeout?.onTimeout === "branch" && /* @__PURE__ */ jsx(
|
|
6250
|
+
Field,
|
|
6251
|
+
{
|
|
6252
|
+
label: tr(
|
|
6253
|
+
"fluidgrids.builder.nodeSettings.timeoutBranchTarget",
|
|
6254
|
+
"Timeout branch target"
|
|
6255
|
+
),
|
|
6256
|
+
children: /* @__PURE__ */ jsxs(
|
|
6257
|
+
"select",
|
|
6258
|
+
{
|
|
6259
|
+
value: errorConfig?.timeout?.timeoutBranchId ?? "",
|
|
6260
|
+
onChange: (e) => writeErrorConfig({
|
|
6261
|
+
timeout: {
|
|
6262
|
+
...errorConfig?.timeout ?? { duration: 3e4 },
|
|
6263
|
+
timeoutBranchId: e.target.value || void 0
|
|
6264
|
+
}
|
|
6265
|
+
}),
|
|
6266
|
+
"data-testid": "ndv-settings-timeout-branch-id",
|
|
6267
|
+
className: cn$1(inputCx, "max-w-xs"),
|
|
6268
|
+
children: [
|
|
6269
|
+
/* @__PURE__ */ jsx("option", { value: "", children: tr(
|
|
6270
|
+
"fluidgrids.builder.nodeSettings.selectNode",
|
|
6271
|
+
"Select a node\u2026"
|
|
6272
|
+
) }),
|
|
6273
|
+
branchTargets.map((n) => /* @__PURE__ */ jsx("option", { value: n.id, children: nodeTitle(n) }, n.id))
|
|
6274
|
+
]
|
|
6275
|
+
}
|
|
6276
|
+
)
|
|
6277
|
+
}
|
|
6278
|
+
)
|
|
6279
|
+
] })
|
|
6280
|
+
] }),
|
|
6281
|
+
/* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
|
|
6282
|
+
/* @__PURE__ */ jsx("div", { className: SECTION_LABEL4, children: tr("fluidgrids.builder.nodeSettings.otherSection", "Other") }),
|
|
6283
|
+
/* @__PURE__ */ jsxs("label", { className: "flex w-fit cursor-pointer items-center gap-2 text-sm", children: [
|
|
6284
|
+
/* @__PURE__ */ jsx(
|
|
6285
|
+
"input",
|
|
6286
|
+
{
|
|
6287
|
+
type: "checkbox",
|
|
6288
|
+
checked: alwaysOutputData,
|
|
6289
|
+
onChange: (e) => writeExecutionSettings({ alwaysOutputData: e.target.checked }),
|
|
6290
|
+
"data-testid": "ndv-settings-always-output-data",
|
|
6291
|
+
className: "size-4"
|
|
6292
|
+
}
|
|
6293
|
+
),
|
|
6294
|
+
/* @__PURE__ */ jsx("span", { children: tr(
|
|
6295
|
+
"fluidgrids.builder.nodeSettings.alwaysOutputDataLabel",
|
|
6296
|
+
"Always output data"
|
|
6297
|
+
) })
|
|
6298
|
+
] }),
|
|
6299
|
+
/* @__PURE__ */ jsxs("label", { className: "flex w-fit cursor-pointer items-center gap-2 text-sm", children: [
|
|
6300
|
+
/* @__PURE__ */ jsx(
|
|
6301
|
+
"input",
|
|
6302
|
+
{
|
|
6303
|
+
type: "checkbox",
|
|
6304
|
+
checked: executeOnce,
|
|
6305
|
+
onChange: (e) => writeExecutionSettings({ executeOnce: e.target.checked }),
|
|
6306
|
+
"data-testid": "ndv-settings-execute-once",
|
|
6307
|
+
className: "size-4"
|
|
6308
|
+
}
|
|
6309
|
+
),
|
|
6310
|
+
/* @__PURE__ */ jsx("span", { children: tr(
|
|
6311
|
+
"fluidgrids.builder.nodeSettings.executeOnceLabel",
|
|
6312
|
+
"Execute once"
|
|
6313
|
+
) })
|
|
6314
|
+
] })
|
|
6315
|
+
] }),
|
|
6316
|
+
/* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
|
|
6317
|
+
/* @__PURE__ */ jsx("div", { className: SECTION_LABEL4, children: tr("fluidgrids.builder.nodeSettings.notesSection", "Notes") }),
|
|
6318
|
+
/* @__PURE__ */ jsx(
|
|
6319
|
+
"textarea",
|
|
6320
|
+
{
|
|
6321
|
+
value: notes,
|
|
6322
|
+
onChange: (e) => writeNotes(e.target.value),
|
|
6323
|
+
rows: 4,
|
|
6324
|
+
placeholder: tr(
|
|
6325
|
+
"fluidgrids.builder.nodeSettings.notesPlaceholder",
|
|
6326
|
+
"Leave a note for teammates about what this node does\u2026"
|
|
6327
|
+
),
|
|
6328
|
+
"data-testid": "ndv-settings-notes",
|
|
6329
|
+
className: cn$1(inputCx, "resize-y")
|
|
6330
|
+
}
|
|
6331
|
+
)
|
|
6332
|
+
] })
|
|
6333
|
+
] });
|
|
6334
|
+
}
|
|
6335
|
+
function Field({
|
|
6336
|
+
label,
|
|
6337
|
+
children
|
|
6338
|
+
}) {
|
|
6339
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
6340
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-foreground", children: label }),
|
|
6341
|
+
children
|
|
6342
|
+
] });
|
|
6343
|
+
}
|
|
5250
6344
|
|
|
5251
6345
|
// src/builder/lib/continuation.ts
|
|
5252
6346
|
var BLOCKED = {
|
|
@@ -5591,4 +6685,4 @@ function NodeExecutionActions({
|
|
|
5591
6685
|
);
|
|
5592
6686
|
}
|
|
5593
6687
|
|
|
5594
|
-
export { NDV_Z_INDEX, NodeExecutionActions, NodeParamsForm, Popover, PopoverContent, PopoverTrigger, ReadOnlyFieldset, useGlobalStoreClient };
|
|
6688
|
+
export { NDV_Z_INDEX, NodeExecutionActions, NodeParamsForm, NodeSettingsPanel, Popover, PopoverContent, PopoverTrigger, RUNNER_INSTALL_SCRIPT_URL, ReadOnlyFieldset, RunOnSection, RunnerStatusPill, SCHEDULE_NODE_TYPE, SchedulePanel, TabButton, runnerInstallCommand, useGlobalStoreClient, useRunnerActions, useRunners };
|