@burdenoff/fluidgrids-fe-sdk 2026.922.6 → 2026.922.7

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.
Files changed (57) hide show
  1. package/dist/{ExecutionDetailPage-W7OC3JAA.js → ExecutionDetailPage-WLC63RRK.js} +5 -5
  2. package/dist/{ExecutionDetailPage-W7OC3JAA.js.map → ExecutionDetailPage-WLC63RRK.js.map} +1 -1
  3. package/dist/ExecutionsListPage-P5DRISMN.js +10 -0
  4. package/dist/{ExecutionsListPage-OVBWXB2F.js.map → ExecutionsListPage-P5DRISMN.js.map} +1 -1
  5. package/dist/{WorkflowBuilder-UM2BMGEG.js → WorkflowBuilder-LZ7X2M5Y.js} +8 -7
  6. package/dist/{WorkflowBuilder-UM2BMGEG.js.map → WorkflowBuilder-LZ7X2M5Y.js.map} +1 -1
  7. package/dist/WorkflowsList-QDPC2HVV.js +13 -0
  8. package/dist/{WorkflowsList-ARAFHW6J.js.map → WorkflowsList-QDPC2HVV.js.map} +1 -1
  9. package/dist/{chunk-MGLTXIN5.js → chunk-275FCUOI.js} +3 -39
  10. package/dist/chunk-275FCUOI.js.map +1 -0
  11. package/dist/{chunk-P35U2E2H.js → chunk-4KX6I7PA.js} +5 -5
  12. package/dist/{chunk-P35U2E2H.js.map → chunk-4KX6I7PA.js.map} +1 -1
  13. package/dist/{chunk-2JLRCN25.js → chunk-4LJOUX2R.js} +5 -5
  14. package/dist/{chunk-2JLRCN25.js.map → chunk-4LJOUX2R.js.map} +1 -1
  15. package/dist/{chunk-2OJQPUBC.js → chunk-62OZJC2B.js} +4 -4
  16. package/dist/{chunk-2OJQPUBC.js.map → chunk-62OZJC2B.js.map} +1 -1
  17. package/dist/chunk-AANIWER2.js +41 -0
  18. package/dist/chunk-AANIWER2.js.map +1 -0
  19. package/dist/{chunk-VJDLWE5S.js → chunk-CQOQ6A73.js} +3 -3
  20. package/dist/{chunk-VJDLWE5S.js.map → chunk-CQOQ6A73.js.map} +1 -1
  21. package/dist/{chunk-N4URMBJP.js → chunk-CVNW2EUB.js} +3 -3
  22. package/dist/{chunk-N4URMBJP.js.map → chunk-CVNW2EUB.js.map} +1 -1
  23. package/dist/{chunk-FH5QBQXV.js → chunk-KAMWWBX5.js} +3 -3
  24. package/dist/{chunk-FH5QBQXV.js.map → chunk-KAMWWBX5.js.map} +1 -1
  25. package/dist/{chunk-ELB3LXRJ.js → chunk-OZBZS6DM.js} +3 -3
  26. package/dist/{chunk-ELB3LXRJ.js.map → chunk-OZBZS6DM.js.map} +1 -1
  27. package/dist/{chunk-77S64BTI.js → chunk-REM2BQK5.js} +5 -4
  28. package/dist/chunk-REM2BQK5.js.map +1 -0
  29. package/dist/{chunk-35YDFYV2.js → chunk-VTKT6XDA.js} +801 -24
  30. package/dist/chunk-VTKT6XDA.js.map +1 -0
  31. package/dist/{chunk-5GXAHGJV.js → chunk-WJQSPVU5.js} +11 -6
  32. package/dist/chunk-WJQSPVU5.js.map +1 -0
  33. package/dist/{chunk-ACRXNUU2.js → chunk-XA3IJE2D.js} +196 -49
  34. package/dist/chunk-XA3IJE2D.js.map +1 -0
  35. package/dist/{chunk-NOECWBYH.js → chunk-Z4XRVZZ2.js} +4 -4
  36. package/dist/{chunk-NOECWBYH.js.map → chunk-Z4XRVZZ2.js.map} +1 -1
  37. package/dist/executions.js +5 -5
  38. package/dist/history.js +3 -3
  39. package/dist/index.d.ts +51 -3
  40. package/dist/index.js +21 -20
  41. package/dist/index.js.map +1 -1
  42. package/dist/nodes.js +2 -2
  43. package/dist/settings.d.ts +12 -1
  44. package/dist/settings.js +3 -1
  45. package/dist/templates.js +6 -5
  46. package/dist/{workflow-builder-BNWKK8C7.d.ts → workflow-builder-lgLa__fU.d.ts} +102 -0
  47. package/dist/workflow-builder.d.ts +1 -1
  48. package/dist/workflow-builder.js +7 -6
  49. package/dist/workflows-list.js +5 -4
  50. package/package.json +1 -1
  51. package/dist/ExecutionsListPage-OVBWXB2F.js +0 -10
  52. package/dist/WorkflowsList-ARAFHW6J.js +0 -12
  53. package/dist/chunk-35YDFYV2.js.map +0 -1
  54. package/dist/chunk-5GXAHGJV.js.map +0 -1
  55. package/dist/chunk-77S64BTI.js.map +0 -1
  56. package/dist/chunk-ACRXNUU2.js.map +0 -1
  57. package/dist/chunk-MGLTXIN5.js.map +0 -1
@@ -4,14 +4,15 @@ import { Badge as Badge$1, Button as Button$1 } from './chunk-DBOMRIP5.js';
4
4
  import { getGlobalStoreClient, createGlobalStoreClient, setGlobalStoreClient, resetGlobalStoreClient } from './chunk-BQXHJIER.js';
5
5
  import { GetMyNodeInstallationsDocument, BrowseWorkflowTemplatesDocument, InstallWorkflowNodeDocument, InstallPurchasedNodeDocument, BrowseWorkflowNodesDocument, UninstallWorkflowNodeDocument, CreateStoreOrderDocument, GetNodeInstallableVersionsDocument } from './chunk-6LXMUIR3.js';
6
6
  import { deepClone, applyTemplateInputs } from './chunk-XQP33UJR.js';
7
- import { useFlowStore, QuotaExhaustedDialog } from './chunk-MGLTXIN5.js';
7
+ import { QuotaExhaustedDialog } from './chunk-AANIWER2.js';
8
8
  import { SdkPermissionGate, FLUIDGRIDS_PERMISSIONS, SdkPermissionButton } from './chunk-UIY2HBWA.js';
9
9
  import { cn as cn$1 } from './chunk-3ZYUGTIT.js';
10
- import { useWorkflowVersions, useRestoreWorkflowVersion, useActivateWorkflow, useDeleteWorkflow, useDeactivateWorkflow } from './chunk-ELB3LXRJ.js';
10
+ import { useWorkflowVersions, useRestoreWorkflowVersion, useActivateWorkflow, useDeleteWorkflow, useDeactivateWorkflow } from './chunk-OZBZS6DM.js';
11
11
  import { throwIfResultError, describeOperationError } from './chunk-LMO5ASOE.js';
12
12
  import { config, getFluidGridsConfig, validateTrustedOrigin, setFluidGridsConfig, resetFluidGridsConfig } from './chunk-WWU2O2SR.js';
13
- import { NodeEndpointConfigsDocument, NodeManifestDocument, UpdateWorkflowDefinitionDocument, CreateWorkflowDefinitionDocument, CreateWorkflowVersionDocument, TriggerWorkflowDocument, WorkflowRunDocument, FluidgridsEntityTagsDocument, AvailableFluidgridsTagsDocument, SearchFluidgridsTagsDocument, TagFluidgridsEntityDocument, UntagFluidgridsEntityDocument, ReplaceFluidgridsEntityTagsDocument, CreateFluidgridsTagDocument, NodeSchemaIntrospectionDocument, EventRegistrationsDocument, NodeUsageStatusDocument, RemoveNodeFromWorkflowsDocument } from './chunk-WO3AHQVD.js';
14
13
  import { waitForFluidGridsClient, getFluidGridsClient, createFluidGridsClient, setFluidGridsClient, resetFluidGridsClient, getFluidGridsClientSafe } from './chunk-5BDQNSP3.js';
14
+ import { useFlowStore } from './chunk-275FCUOI.js';
15
+ import { NodeEndpointConfigsDocument, NodeManifestDocument, UpdateWorkflowDefinitionDocument, CreateWorkflowDefinitionDocument, CreateWorkflowVersionDocument, TriggerWorkflowDocument, WorkflowRunDocument, FluidgridsEntityTagsDocument, AvailableFluidgridsTagsDocument, SearchFluidgridsTagsDocument, TagFluidgridsEntityDocument, UntagFluidgridsEntityDocument, ReplaceFluidgridsEntityTagsDocument, CreateFluidgridsTagDocument, NodeSchemaIntrospectionDocument, EventRegistrationsDocument, NodeUsageStatusDocument, RemoveNodeFromWorkflowsDocument } from './chunk-WO3AHQVD.js';
15
16
  import { useTr, FluidGridsTranslationProvider, ENGLISH_FALLBACK_TRANSLATOR } from './chunk-7YWBH2A5.js';
16
17
  import * as React2 from 'react';
17
18
  import React2__default, { forwardRef, useState, useImperativeHandle, useRef, useEffect, useMemo, memo, createContext, lazy, useCallback, useContext, useLayoutEffect, Suspense, useDeferredValue } from 'react';
@@ -4349,6 +4350,50 @@ function createNodeWithDefaultData(type, data) {
4349
4350
  const defaultData = NODES.find((node) => node.type === type)?.defaultData ?? {};
4350
4351
  return Object.assign(createNodeData(type, defaultData), data);
4351
4352
  }
4353
+ var NODE_DOCS_URL = gql`
4354
+ query NodeDocsUrlLookup($nodeType: String!, $nodeVersion: String!) {
4355
+ nodeEndpointConfig(nodeType: $nodeType, nodeVersion: $nodeVersion) {
4356
+ docsUrl
4357
+ }
4358
+ }
4359
+ `;
4360
+ var cache = /* @__PURE__ */ new Map();
4361
+ var inFlight = /* @__PURE__ */ new Map();
4362
+ function fetchDocsUrl(nodeType, nodeVersion) {
4363
+ const key = `${nodeType}@${nodeVersion}`;
4364
+ if (cache.has(key)) return Promise.resolve(cache.get(key));
4365
+ const existing = inFlight.get(key);
4366
+ if (existing) return existing;
4367
+ const promise = getFluidGridsClient().query({
4368
+ query: NODE_DOCS_URL,
4369
+ variables: { nodeType, nodeVersion },
4370
+ fetchPolicy: "cache-first"
4371
+ }).then((result) => result.data?.nodeEndpointConfig?.docsUrl ?? void 0).catch(() => void 0).finally(() => inFlight.delete(key));
4372
+ inFlight.set(key, promise);
4373
+ return promise.then((url) => {
4374
+ cache.set(key, url);
4375
+ return url;
4376
+ });
4377
+ }
4378
+ function useNodeDocsUrl(nodeType, nodeVersion) {
4379
+ const [docsUrl, setDocsUrl] = useState(
4380
+ () => nodeType && nodeVersion ? cache.get(`${nodeType}@${nodeVersion}`) : void 0
4381
+ );
4382
+ useEffect(() => {
4383
+ if (!nodeType || !nodeVersion) {
4384
+ setDocsUrl(void 0);
4385
+ return;
4386
+ }
4387
+ let cancelled = false;
4388
+ fetchDocsUrl(nodeType, nodeVersion).then((url) => {
4389
+ if (!cancelled) setDocsUrl(url);
4390
+ });
4391
+ return () => {
4392
+ cancelled = true;
4393
+ };
4394
+ }, [nodeType, nodeVersion]);
4395
+ return docsUrl;
4396
+ }
4352
4397
  function isImageIcon(icon) {
4353
4398
  return !!icon && (/^https?:\/\//.test(icon) || icon.startsWith("data:"));
4354
4399
  }
@@ -6027,7 +6072,23 @@ function NodeInfoButtonWithModal({
6027
6072
  value: metadata.kind && metadata.kind.length > 0 ? metadata.kind.join(", ") : void 0
6028
6073
  }
6029
6074
  )
6030
- ] })
6075
+ ] }),
6076
+ metadata.docsUrl ? /* @__PURE__ */ jsxs(
6077
+ "a",
6078
+ {
6079
+ href: metadata.docsUrl,
6080
+ target: "_blank",
6081
+ rel: "noopener noreferrer",
6082
+ className: "inline-flex items-center gap-1 text-sm text-[var(--color-status-info-text)] hover:underline",
6083
+ children: [
6084
+ tr(
6085
+ "fluidgrids.builder.nodeInfoModal.docsLink",
6086
+ "View documentation"
6087
+ ),
6088
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2197" })
6089
+ ]
6090
+ }
6091
+ ) : null
6031
6092
  ] })
6032
6093
  ] });
6033
6094
  }
@@ -6423,6 +6484,10 @@ var getNodeMetadata = (value) => {
6423
6484
  function NodeComponent(props) {
6424
6485
  const { id, isConnectable, selected, data, dragging } = props;
6425
6486
  const tr = useTr();
6487
+ const docsUrl = useNodeDocsUrl(
6488
+ value?.type,
6489
+ data?.nodeData?.version || data?.version
6490
+ );
6426
6491
  const { edges, nodeLookup } = useStore(({ edges: edges2, nodeLookup: nodeLookup2 }) => ({
6427
6492
  edges: edges2,
6428
6493
  nodeLookup: nodeLookup2
@@ -6594,7 +6659,8 @@ var getNodeMetadata = (value) => {
6594
6659
  nodeType: value?.type,
6595
6660
  version: data?.nodeData?.version || data?.version,
6596
6661
  kind: nodeKinds,
6597
- operation: data?.operation_name
6662
+ operation: data?.operation_name,
6663
+ docsUrl
6598
6664
  };
6599
6665
  const isLogicNode = /(^|[:/])(if|switch|merge|loop|filter|branch|router|condition|aggregate)/.test(
6600
6666
  (value?.type || "").toLowerCase()
@@ -11835,8 +11901,8 @@ function DesktopSidebarFragment({
11835
11901
  }
11836
11902
  const { getFluidGridsClient: getFluidGridsClient2 } = await import('./client-AMUUS7VE.js');
11837
11903
  const { getFluidGridsConfig: getFluidGridsConfig2 } = await import('./config-E4E7M6IN.js');
11838
- const { gql: gql8 } = await import('@apollo/client/core');
11839
- const IMPORT_MUTATION = gql8`
11904
+ const { gql: gql10 } = await import('@apollo/client/core');
11905
+ const IMPORT_MUTATION = gql10`
11840
11906
  mutation ImportWorkflowTemplate(
11841
11907
  $input: ImportWorkflowTemplateInput!
11842
11908
  ) {
@@ -11982,8 +12048,8 @@ function DesktopSidebarFragment({
11982
12048
  { id: "template-load" }
11983
12049
  );
11984
12050
  const { getGlobalStoreClient: getGlobalStoreClient2 } = await import('./global-client-OW43ZRDR.js');
11985
- const { gql: gql8 } = await import('@apollo/client/core');
11986
- const GET_TEMPLATE_DETAIL = gql8`
12051
+ const { gql: gql10 } = await import('@apollo/client/core');
12052
+ const GET_TEMPLATE_DETAIL = gql10`
11987
12053
  query GetWorkflowTemplateDetail($id: ID!) {
11988
12054
  product(id: $id) {
11989
12055
  id
@@ -22127,6 +22193,192 @@ function WebhookUrlField({ webhookUrl, loading }) {
22127
22193
  ) })
22128
22194
  ] });
22129
22195
  }
22196
+ var LOAD_NODE_OPTIONS = gql`
22197
+ query LoadNodeOptions(
22198
+ $nodeType: String!
22199
+ $nodeVersion: String!
22200
+ $operationName: String!
22201
+ $resultPath: String
22202
+ $labelField: String!
22203
+ $valueField: String!
22204
+ $connectionId: ID
22205
+ $args: JSON
22206
+ ) {
22207
+ loadNodeOptions(
22208
+ nodeType: $nodeType
22209
+ nodeVersion: $nodeVersion
22210
+ operationName: $operationName
22211
+ resultPath: $resultPath
22212
+ labelField: $labelField
22213
+ valueField: $valueField
22214
+ connectionId: $connectionId
22215
+ args: $args
22216
+ ) {
22217
+ label
22218
+ value
22219
+ }
22220
+ }
22221
+ `;
22222
+ var CLIENT_CACHE_TTL_MS = 3 * 60 * 1e3;
22223
+ var cache2 = /* @__PURE__ */ new Map();
22224
+ function cacheKey(nodeType, nodeVersion, spec, connectionId) {
22225
+ return [
22226
+ nodeType,
22227
+ nodeVersion,
22228
+ spec.operation,
22229
+ spec.resultPath ?? "",
22230
+ spec.labelField,
22231
+ spec.valueField,
22232
+ connectionId ?? ""
22233
+ ].join("::");
22234
+ }
22235
+ function useLoadNodeOptions(nodeType, nodeVersion, spec, connectionId) {
22236
+ const [options, setOptions] = useState([]);
22237
+ const [loading, setLoading] = useState(false);
22238
+ const [error, setError] = useState(null);
22239
+ const [nonce, setNonce] = useState(0);
22240
+ const mountedRef = useRef(true);
22241
+ useEffect(
22242
+ () => () => {
22243
+ mountedRef.current = false;
22244
+ },
22245
+ []
22246
+ );
22247
+ useEffect(() => {
22248
+ if (!nodeType || !nodeVersion || !spec || !connectionId) {
22249
+ setOptions([]);
22250
+ setError(null);
22251
+ return;
22252
+ }
22253
+ const key = cacheKey(nodeType, nodeVersion, spec, connectionId);
22254
+ const cached = cache2.get(key);
22255
+ if (cached && cached.expiresAt > Date.now()) {
22256
+ setOptions(cached.options);
22257
+ setError(null);
22258
+ return;
22259
+ }
22260
+ let cancelled = false;
22261
+ setLoading(true);
22262
+ setError(null);
22263
+ const client = getFluidGridsClient();
22264
+ client.query({
22265
+ query: LOAD_NODE_OPTIONS,
22266
+ variables: {
22267
+ nodeType,
22268
+ nodeVersion,
22269
+ operationName: spec.operation,
22270
+ resultPath: spec.resultPath ?? null,
22271
+ labelField: spec.labelField,
22272
+ valueField: spec.valueField,
22273
+ connectionId,
22274
+ args: {}
22275
+ },
22276
+ fetchPolicy: "network-only"
22277
+ }).then((result) => {
22278
+ if (cancelled || !mountedRef.current) return;
22279
+ const fetched = result.data?.loadNodeOptions ?? [];
22280
+ cache2.set(key, {
22281
+ options: fetched,
22282
+ expiresAt: Date.now() + CLIENT_CACHE_TTL_MS
22283
+ });
22284
+ setOptions(fetched);
22285
+ }).catch((err) => {
22286
+ if (cancelled || !mountedRef.current) return;
22287
+ setOptions([]);
22288
+ setError(err instanceof Error ? err : new Error(String(err)));
22289
+ }).finally(() => {
22290
+ if (cancelled || !mountedRef.current) return;
22291
+ setLoading(false);
22292
+ });
22293
+ return () => {
22294
+ cancelled = true;
22295
+ };
22296
+ }, [nodeType, nodeVersion, spec, connectionId, nonce]);
22297
+ return {
22298
+ options,
22299
+ loading,
22300
+ error,
22301
+ refetch: () => setNonce((n) => n + 1)
22302
+ };
22303
+ }
22304
+ function NodeLoadOptionsSelect({
22305
+ nodeType,
22306
+ nodeVersion,
22307
+ spec,
22308
+ connectionId,
22309
+ value,
22310
+ onChange,
22311
+ className,
22312
+ testId
22313
+ }) {
22314
+ const tr = useTr();
22315
+ const { options, loading, error } = useLoadNodeOptions(
22316
+ nodeType,
22317
+ nodeVersion,
22318
+ spec,
22319
+ connectionId
22320
+ );
22321
+ const stringValue = typeof value === "string" ? value : "";
22322
+ if (!connectionId) {
22323
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1.5", children: /* @__PURE__ */ jsx(
22324
+ "input",
22325
+ {
22326
+ type: "text",
22327
+ value: stringValue,
22328
+ onChange: (e) => onChange(e.target.value),
22329
+ placeholder: tr(
22330
+ "fluidgrids.builder.nodeParamsForm.loadOptionsNoConnection",
22331
+ "Connect an account above to load options, or type a value"
22332
+ ),
22333
+ "data-testid": testId,
22334
+ className
22335
+ }
22336
+ ) });
22337
+ }
22338
+ if (error) {
22339
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
22340
+ /* @__PURE__ */ jsx(
22341
+ "input",
22342
+ {
22343
+ type: "text",
22344
+ value: stringValue,
22345
+ onChange: (e) => onChange(e.target.value),
22346
+ placeholder: tr(
22347
+ "fluidgrids.builder.nodeParamsForm.loadOptionsErrorPlaceholder",
22348
+ "Enter a value"
22349
+ ),
22350
+ "data-testid": testId,
22351
+ className
22352
+ }
22353
+ ),
22354
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] text-destructive", children: tr(
22355
+ "fluidgrids.builder.nodeParamsForm.loadOptionsError",
22356
+ "Couldn't load options \u2014 enter a value manually."
22357
+ ) })
22358
+ ] });
22359
+ }
22360
+ return /* @__PURE__ */ jsxs(
22361
+ "select",
22362
+ {
22363
+ value: stringValue,
22364
+ onChange: (e) => onChange(e.target.value),
22365
+ disabled: loading,
22366
+ "data-testid": testId,
22367
+ className: cn(className, loading && "opacity-60"),
22368
+ children: [
22369
+ /* @__PURE__ */ jsx("option", { value: "", children: loading ? tr(
22370
+ "fluidgrids.builder.nodeParamsForm.loadOptionsLoading",
22371
+ "Loading\u2026"
22372
+ ) : tr(
22373
+ "fluidgrids.builder.nodeParamsForm.selectPlaceholder",
22374
+ "Select\u2026"
22375
+ ) }),
22376
+ stringValue && !options.some((o) => o.value === stringValue) && /* @__PURE__ */ jsx("option", { value: stringValue, children: stringValue }),
22377
+ options.map((o) => /* @__PURE__ */ jsx("option", { value: o.value, children: o.label }, o.value))
22378
+ ]
22379
+ }
22380
+ );
22381
+ }
22130
22382
  function useWebhookRegistration(workflowKey, triggerNodeId, enabled = true) {
22131
22383
  const [registration, setRegistration] = useState(
22132
22384
  null
@@ -22171,6 +22423,10 @@ function useWebhookRegistration(workflowKey, triggerNodeId, enabled = true) {
22171
22423
  }
22172
22424
 
22173
22425
  // src/builder/components/ndv/use-node-config.ts
22426
+ function errorConfigOf(node) {
22427
+ const config2 = asRecord(node?.data)?.errorConfig;
22428
+ return config2;
22429
+ }
22174
22430
  function coerceNumber(type, raw) {
22175
22431
  if (raw.trim() === "") return void 0;
22176
22432
  const n = type === "integer" ? parseInt(raw, 10) : parseFloat(raw);
@@ -22195,13 +22451,21 @@ function paramsFromOperation(op) {
22195
22451
  const options = Array.isArray(optsRaw) ? optsRaw.map(
22196
22452
  (o) => typeof o === "string" ? o : asRecord(o)?.value ?? asRecord(o)?.name
22197
22453
  ).filter((v) => typeof v === "string") : void 0;
22454
+ const loadOptionsRec = asRecord(rec?.loadOptions);
22455
+ const loadOptions = loadOptionsRec && typeof loadOptionsRec.operation === "string" && typeof loadOptionsRec.labelField === "string" && typeof loadOptionsRec.valueField === "string" ? {
22456
+ operation: loadOptionsRec.operation,
22457
+ labelField: loadOptionsRec.labelField,
22458
+ valueField: loadOptionsRec.valueField,
22459
+ resultPath: typeof loadOptionsRec.resultPath === "string" ? loadOptionsRec.resultPath : void 0
22460
+ } : void 0;
22198
22461
  return {
22199
22462
  name,
22200
22463
  type: typeof spec === "string" ? spec : typeof rec?.type === "string" ? rec.type : "any",
22201
22464
  required: rec?.required === true,
22202
22465
  description: typeof rec?.description === "string" ? rec.description : void 0,
22203
22466
  options,
22204
- defaultValue: rec?.default
22467
+ defaultValue: rec?.default,
22468
+ loadOptions
22205
22469
  };
22206
22470
  });
22207
22471
  }
@@ -22381,6 +22645,58 @@ function useNodeConfig(target, options) {
22381
22645
  store.actions.nodes.setNodes(next);
22382
22646
  clearMappingFromAllIncoming(field);
22383
22647
  };
22648
+ const writeErrorConfig = (patch) => {
22649
+ if (!nodeId) return;
22650
+ const store = useFlowStore.getState();
22651
+ const next = store.workflow.nodes.map((n) => {
22652
+ if (n.id !== nodeId) return n;
22653
+ const data = { ...asRecord(n.data) ?? {} };
22654
+ const prev = errorConfigOf(n) ?? {};
22655
+ const merged = { ...prev, ...patch };
22656
+ if (patch.retryConfig !== void 0) {
22657
+ merged.retryConfig = patch.retryConfig ? { ...prev.retryConfig, ...patch.retryConfig } : void 0;
22658
+ }
22659
+ if (patch.timeout !== void 0) {
22660
+ merged.timeout = patch.timeout ? { ...prev.timeout, ...patch.timeout } : void 0;
22661
+ }
22662
+ data.errorConfig = merged;
22663
+ return { ...n, data };
22664
+ });
22665
+ store.actions.nodes.setNodes(next);
22666
+ };
22667
+ const writeNodeDataField = (field, value) => {
22668
+ if (!nodeId) return;
22669
+ const store = useFlowStore.getState();
22670
+ const next = store.workflow.nodes.map((n) => {
22671
+ if (n.id !== nodeId) return n;
22672
+ const data = { ...asRecord(n.data) ?? {} };
22673
+ if (value === void 0 || value === "" || value === false) {
22674
+ delete data[field];
22675
+ } else {
22676
+ data[field] = value;
22677
+ }
22678
+ return { ...n, data };
22679
+ });
22680
+ store.actions.nodes.setNodes(next);
22681
+ };
22682
+ const writeNotes = (value) => writeNodeDataField("notes", value);
22683
+ const writeExecutionSettings = (patch) => {
22684
+ if (!nodeId) return;
22685
+ const store = useFlowStore.getState();
22686
+ const next = store.workflow.nodes.map((n) => {
22687
+ if (n.id !== nodeId) return n;
22688
+ const data = { ...asRecord(n.data) ?? {} };
22689
+ const prev = asRecord(data.executionSettings) ?? {};
22690
+ const merged = { ...prev, ...patch };
22691
+ if (!merged.alwaysOutputData && !merged.executeOnce) {
22692
+ delete data.executionSettings;
22693
+ } else {
22694
+ data.executionSettings = merged;
22695
+ }
22696
+ return { ...n, data };
22697
+ });
22698
+ store.actions.nodes.setNodes(next);
22699
+ };
22384
22700
  const toggleMode = (field, current) => {
22385
22701
  if (current === "expression") {
22386
22702
  clearMappingFromAllIncoming(field);
@@ -22390,6 +22706,17 @@ function useNodeConfig(target, options) {
22390
22706
  [field]: current === "expression" ? "fixed" : "expression"
22391
22707
  }));
22392
22708
  };
22709
+ const errorConfig = useMemo(() => errorConfigOf(node), [node]);
22710
+ const notes = useMemo(() => {
22711
+ const data = asRecord(node?.data);
22712
+ return typeof data?.notes === "string" ? data.notes : "";
22713
+ }, [node]);
22714
+ const executionSettings = useMemo(
22715
+ () => asRecord(asRecord(node?.data)?.executionSettings),
22716
+ [node]
22717
+ );
22718
+ const alwaysOutputData = executionSettings?.alwaysOutputData === true;
22719
+ const executeOnce = executionSettings?.executeOnce === true;
22393
22720
  const handleDropOnParam = (field) => (e) => {
22394
22721
  e.preventDefault();
22395
22722
  setDragField(null);
@@ -22427,7 +22754,15 @@ function useNodeConfig(target, options) {
22427
22754
  writeMapping,
22428
22755
  handleConnectionsChange,
22429
22756
  toggleMode,
22430
- handleDropOnParam
22757
+ handleDropOnParam,
22758
+ errorConfig,
22759
+ writeErrorConfig,
22760
+ notes,
22761
+ writeNotes,
22762
+ alwaysOutputData,
22763
+ executeOnce,
22764
+ writeExecutionSettings,
22765
+ writeNodeDataField
22431
22766
  };
22432
22767
  }
22433
22768
  var SECTION_LABEL3 = "text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground";
@@ -22458,6 +22793,19 @@ function NodeParamsForm({
22458
22793
  toggleMode,
22459
22794
  handleDropOnParam
22460
22795
  } = config2;
22796
+ const loadOptionsConnectionId = (() => {
22797
+ const adapterNames = new Set(connectionAdapters.map((a) => a.name));
22798
+ return selectedConnections.find((c) => adapterNames.has(c.adapter))?.connectionId ?? selectedConnections[0]?.connectionId;
22799
+ })();
22800
+ const nodeVersion = (() => {
22801
+ const data = asRecord(config2.node?.data);
22802
+ const nodeData = asRecord(data?.nodeData);
22803
+ const fromManifest = nodeData?.version;
22804
+ const fromData = data?.version;
22805
+ if (typeof fromManifest === "string") return fromManifest;
22806
+ if (typeof fromData === "string") return fromData;
22807
+ return "1.0.0";
22808
+ })();
22461
22809
  return /* @__PURE__ */ jsxs(Fragment, { children: [
22462
22810
  isWebhookTrigger && /* @__PURE__ */ jsx(WebhookUrlField, { webhookUrl, loading: webhookUrlLoading }),
22463
22811
  isWebhookWait && /* @__PURE__ */ jsx(WaitResumeUrlField, {}),
@@ -22529,7 +22877,7 @@ function NodeParamsForm({
22529
22877
  const fixedValue = argsState[p.name];
22530
22878
  const isCodeParam = p.type === "code" || nodeType === "internal:code" && p.name === "code";
22531
22879
  const highlight = dragField === p.name;
22532
- const inputCx = cn(
22880
+ const inputCx2 = cn(
22533
22881
  "w-full rounded-md border bg-background px-2.5 py-1.5 text-sm outline-none transition-colors disabled:opacity-50",
22534
22882
  highlight ? "border-primary ring-1 ring-primary" : "border-input focus:border-primary"
22535
22883
  );
@@ -22608,6 +22956,18 @@ function NodeParamsForm({
22608
22956
  onChange: (v) => writeFixed(p.name, v),
22609
22957
  "data-testid": `${testIdPrefix}-param-${p.name}`
22610
22958
  }
22959
+ ) : p.loadOptions ? /* @__PURE__ */ jsx(
22960
+ NodeLoadOptionsSelect,
22961
+ {
22962
+ nodeType,
22963
+ nodeVersion,
22964
+ spec: p.loadOptions,
22965
+ connectionId: loadOptionsConnectionId,
22966
+ value: fixedValue,
22967
+ onChange: (v) => writeFixed(p.name, v),
22968
+ className: inputCx2,
22969
+ testId: `${testIdPrefix}-param-${p.name}`
22970
+ }
22611
22971
  ) : p.type === "boolean" ? /* @__PURE__ */ jsxs("label", { className: "flex w-fit cursor-pointer items-center gap-2 text-sm", children: [
22612
22972
  /* @__PURE__ */ jsx(
22613
22973
  "input",
@@ -22629,7 +22989,7 @@ function NodeParamsForm({
22629
22989
  value: typeof fixedValue === "string" ? fixedValue : "",
22630
22990
  onChange: (e) => writeFixed(p.name, e.target.value),
22631
22991
  "data-testid": `${testIdPrefix}-param-${p.name}`,
22632
- className: inputCx,
22992
+ className: inputCx2,
22633
22993
  children: [
22634
22994
  /* @__PURE__ */ jsx("option", { value: "", children: p.defaultValue !== void 0 ? `Default (${String(p.defaultValue)})` : tr(
22635
22995
  "fluidgrids.builder.nodeParamsForm.selectPlaceholder",
@@ -22650,7 +23010,7 @@ function NodeParamsForm({
22650
23010
  ),
22651
23011
  onChange: (e) => writeFixed(p.name, coerceNumber(p.type, e.target.value)),
22652
23012
  "data-testid": `${testIdPrefix}-param-${p.name}`,
22653
- className: inputCx
23013
+ className: inputCx2
22654
23014
  }
22655
23015
  ) : /* @__PURE__ */ jsx(
22656
23016
  "input",
@@ -22663,7 +23023,7 @@ function NodeParamsForm({
22663
23023
  ),
22664
23024
  onChange: (e) => writeFixed(p.name, e.target.value),
22665
23025
  "data-testid": `${testIdPrefix}-param-${p.name}`,
22666
- className: inputCx
23026
+ className: inputCx2
22667
23027
  }
22668
23028
  ),
22669
23029
  p.description && /* @__PURE__ */ jsx("span", { className: "text-[11px] leading-snug text-muted-foreground", children: p.description })
@@ -22674,6 +23034,419 @@ function NodeParamsForm({
22674
23034
  })
22675
23035
  ] });
22676
23036
  }
23037
+ var SECTION_LABEL4 = "text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground";
23038
+ 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";
23039
+ function msToSeconds(ms, fallbackMs) {
23040
+ return Math.round((ms ?? fallbackMs) / 1e3 * 10) / 10;
23041
+ }
23042
+ function secondsInputToMs(raw, minMs) {
23043
+ const seconds = parseFloat(raw);
23044
+ if (Number.isNaN(seconds)) return minMs;
23045
+ return Math.max(minMs, Math.round(seconds * 1e3));
23046
+ }
23047
+ function NodeSettingsPanel({
23048
+ config: config2
23049
+ }) {
23050
+ const tr = useTr();
23051
+ const {
23052
+ nodes,
23053
+ node,
23054
+ errorConfig,
23055
+ writeErrorConfig,
23056
+ notes,
23057
+ writeNotes,
23058
+ alwaysOutputData,
23059
+ executeOnce,
23060
+ writeExecutionSettings
23061
+ } = config2;
23062
+ const onError = errorConfig?.onError ?? "stop";
23063
+ const retryEnabled = (errorConfig?.retryConfig?.maxRetries ?? 0) > 0;
23064
+ const timeoutEnabled = !!errorConfig?.timeout?.duration;
23065
+ const branchTargets = nodes.filter((n) => n.id !== node?.id);
23066
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-6", "data-testid": "ndv-settings-panel", children: [
23067
+ /* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
23068
+ /* @__PURE__ */ jsx("div", { className: SECTION_LABEL4, children: tr("fluidgrids.builder.nodeSettings.retrySection", "Retry on Fail") }),
23069
+ /* @__PURE__ */ jsxs("label", { className: "flex w-fit cursor-pointer items-center gap-2 text-sm", children: [
23070
+ /* @__PURE__ */ jsx(
23071
+ "input",
23072
+ {
23073
+ type: "checkbox",
23074
+ checked: retryEnabled,
23075
+ onChange: (e) => writeErrorConfig({
23076
+ retryConfig: e.target.checked ? {
23077
+ maxRetries: errorConfig?.retryConfig?.maxRetries || 3,
23078
+ retryDelay: errorConfig?.retryConfig?.retryDelay || 1e3,
23079
+ backoffMultiplier: errorConfig?.retryConfig?.backoffMultiplier ?? 2,
23080
+ maxDelay: errorConfig?.retryConfig?.maxDelay ?? 3e4
23081
+ } : void 0
23082
+ }),
23083
+ "data-testid": "ndv-settings-retry-enabled",
23084
+ className: "size-4"
23085
+ }
23086
+ ),
23087
+ /* @__PURE__ */ jsx("span", { children: tr(
23088
+ "fluidgrids.builder.nodeSettings.retryEnabledLabel",
23089
+ "Retry this node on failure"
23090
+ ) })
23091
+ ] }),
23092
+ retryEnabled && /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 pl-6", children: [
23093
+ /* @__PURE__ */ jsx(
23094
+ Field,
23095
+ {
23096
+ label: tr(
23097
+ "fluidgrids.builder.nodeSettings.maxRetries",
23098
+ "Max tries"
23099
+ ),
23100
+ children: /* @__PURE__ */ jsx(
23101
+ "input",
23102
+ {
23103
+ type: "number",
23104
+ min: 1,
23105
+ max: 20,
23106
+ value: errorConfig?.retryConfig?.maxRetries ?? 3,
23107
+ onChange: (e) => writeErrorConfig({
23108
+ retryConfig: {
23109
+ ...errorConfig?.retryConfig ?? {
23110
+ retryDelay: 1e3,
23111
+ maxRetries: 3
23112
+ },
23113
+ maxRetries: Math.max(
23114
+ 1,
23115
+ parseInt(e.target.value, 10) || 1
23116
+ )
23117
+ }
23118
+ }),
23119
+ "data-testid": "ndv-settings-max-retries",
23120
+ className: inputCx
23121
+ }
23122
+ )
23123
+ }
23124
+ ),
23125
+ /* @__PURE__ */ jsx(
23126
+ Field,
23127
+ {
23128
+ label: tr(
23129
+ "fluidgrids.builder.nodeSettings.retryDelay",
23130
+ "Wait (seconds)"
23131
+ ),
23132
+ children: /* @__PURE__ */ jsx(
23133
+ "input",
23134
+ {
23135
+ type: "number",
23136
+ min: 0,
23137
+ step: 0.1,
23138
+ value: msToSeconds(errorConfig?.retryConfig?.retryDelay, 1e3),
23139
+ onChange: (e) => writeErrorConfig({
23140
+ retryConfig: {
23141
+ ...errorConfig?.retryConfig ?? {
23142
+ maxRetries: 3,
23143
+ retryDelay: 1e3
23144
+ },
23145
+ retryDelay: secondsInputToMs(e.target.value, 0)
23146
+ }
23147
+ }),
23148
+ "data-testid": "ndv-settings-retry-delay",
23149
+ className: inputCx
23150
+ }
23151
+ )
23152
+ }
23153
+ ),
23154
+ /* @__PURE__ */ jsx(
23155
+ Field,
23156
+ {
23157
+ label: tr(
23158
+ "fluidgrids.builder.nodeSettings.backoffMultiplier",
23159
+ "Backoff \xD7"
23160
+ ),
23161
+ children: /* @__PURE__ */ jsx(
23162
+ "input",
23163
+ {
23164
+ type: "number",
23165
+ min: 1,
23166
+ step: 0.5,
23167
+ value: errorConfig?.retryConfig?.backoffMultiplier ?? 2,
23168
+ onChange: (e) => writeErrorConfig({
23169
+ retryConfig: {
23170
+ ...errorConfig?.retryConfig ?? {
23171
+ maxRetries: 3,
23172
+ retryDelay: 1e3
23173
+ },
23174
+ backoffMultiplier: parseFloat(e.target.value) || 1
23175
+ }
23176
+ }),
23177
+ "data-testid": "ndv-settings-backoff-multiplier",
23178
+ className: inputCx
23179
+ }
23180
+ )
23181
+ }
23182
+ ),
23183
+ /* @__PURE__ */ jsx(
23184
+ Field,
23185
+ {
23186
+ label: tr(
23187
+ "fluidgrids.builder.nodeSettings.maxDelay",
23188
+ "Max wait (seconds)"
23189
+ ),
23190
+ children: /* @__PURE__ */ jsx(
23191
+ "input",
23192
+ {
23193
+ type: "number",
23194
+ min: 0,
23195
+ step: 1,
23196
+ value: msToSeconds(errorConfig?.retryConfig?.maxDelay, 3e4),
23197
+ onChange: (e) => writeErrorConfig({
23198
+ retryConfig: {
23199
+ ...errorConfig?.retryConfig ?? {
23200
+ maxRetries: 3,
23201
+ retryDelay: 1e3
23202
+ },
23203
+ maxDelay: secondsInputToMs(e.target.value, 0)
23204
+ }
23205
+ }),
23206
+ "data-testid": "ndv-settings-max-delay",
23207
+ className: inputCx
23208
+ }
23209
+ )
23210
+ }
23211
+ )
23212
+ ] })
23213
+ ] }),
23214
+ /* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
23215
+ /* @__PURE__ */ jsx("div", { className: SECTION_LABEL4, children: tr("fluidgrids.builder.nodeSettings.onErrorSection", "On Error") }),
23216
+ /* @__PURE__ */ jsxs(
23217
+ "select",
23218
+ {
23219
+ value: onError,
23220
+ onChange: (e) => writeErrorConfig({
23221
+ onError: e.target.value,
23222
+ errorBranchId: e.target.value === "branch" ? errorConfig?.errorBranchId : void 0
23223
+ }),
23224
+ "data-testid": "ndv-settings-on-error",
23225
+ className: cn(inputCx, "max-w-xs"),
23226
+ children: [
23227
+ /* @__PURE__ */ jsx("option", { value: "stop", children: tr(
23228
+ "fluidgrids.builder.nodeSettings.onErrorStop",
23229
+ "Stop workflow (default)"
23230
+ ) }),
23231
+ /* @__PURE__ */ jsx("option", { value: "continue", children: tr(
23232
+ "fluidgrids.builder.nodeSettings.onErrorContinue",
23233
+ "Continue on fail"
23234
+ ) }),
23235
+ /* @__PURE__ */ jsx("option", { value: "branch", children: tr(
23236
+ "fluidgrids.builder.nodeSettings.onErrorBranch",
23237
+ "Route to error branch"
23238
+ ) })
23239
+ ]
23240
+ }
23241
+ ),
23242
+ onError === "branch" && /* @__PURE__ */ jsx("div", { className: "pl-2", children: /* @__PURE__ */ jsx(
23243
+ Field,
23244
+ {
23245
+ label: tr(
23246
+ "fluidgrids.builder.nodeSettings.errorBranchTarget",
23247
+ "Error branch target"
23248
+ ),
23249
+ children: /* @__PURE__ */ jsxs(
23250
+ "select",
23251
+ {
23252
+ value: errorConfig?.errorBranchId ?? "",
23253
+ onChange: (e) => writeErrorConfig({
23254
+ errorBranchId: e.target.value || void 0
23255
+ }),
23256
+ "data-testid": "ndv-settings-error-branch-id",
23257
+ className: cn(inputCx, "max-w-xs"),
23258
+ children: [
23259
+ /* @__PURE__ */ jsx("option", { value: "", children: tr(
23260
+ "fluidgrids.builder.nodeSettings.selectNode",
23261
+ "Select a node\u2026"
23262
+ ) }),
23263
+ branchTargets.map((n) => /* @__PURE__ */ jsx("option", { value: n.id, children: nodeTitle(n) }, n.id))
23264
+ ]
23265
+ }
23266
+ )
23267
+ }
23268
+ ) })
23269
+ ] }),
23270
+ /* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
23271
+ /* @__PURE__ */ jsx("div", { className: SECTION_LABEL4, children: tr("fluidgrids.builder.nodeSettings.timeoutSection", "Timeout") }),
23272
+ /* @__PURE__ */ jsxs("label", { className: "flex w-fit cursor-pointer items-center gap-2 text-sm", children: [
23273
+ /* @__PURE__ */ jsx(
23274
+ "input",
23275
+ {
23276
+ type: "checkbox",
23277
+ checked: timeoutEnabled,
23278
+ onChange: (e) => writeErrorConfig({
23279
+ timeout: e.target.checked ? { duration: errorConfig?.timeout?.duration || 3e4 } : void 0
23280
+ }),
23281
+ "data-testid": "ndv-settings-timeout-enabled",
23282
+ className: "size-4"
23283
+ }
23284
+ ),
23285
+ /* @__PURE__ */ jsx("span", { children: tr(
23286
+ "fluidgrids.builder.nodeSettings.timeoutEnabledLabel",
23287
+ "Abort this node if it runs too long"
23288
+ ) })
23289
+ ] }),
23290
+ timeoutEnabled && /* @__PURE__ */ jsxs("div", { className: "space-y-3 pl-6", children: [
23291
+ /* @__PURE__ */ jsx(
23292
+ Field,
23293
+ {
23294
+ label: tr(
23295
+ "fluidgrids.builder.nodeSettings.timeoutDuration",
23296
+ "Timeout (seconds)"
23297
+ ),
23298
+ children: /* @__PURE__ */ jsx(
23299
+ "input",
23300
+ {
23301
+ type: "number",
23302
+ min: 0.1,
23303
+ step: 0.5,
23304
+ value: msToSeconds(errorConfig?.timeout?.duration, 3e4),
23305
+ onChange: (e) => writeErrorConfig({
23306
+ timeout: {
23307
+ ...errorConfig?.timeout ?? { duration: 3e4 },
23308
+ duration: secondsInputToMs(e.target.value, 100)
23309
+ }
23310
+ }),
23311
+ "data-testid": "ndv-settings-timeout-duration",
23312
+ className: cn(inputCx, "max-w-[10rem]")
23313
+ }
23314
+ )
23315
+ }
23316
+ ),
23317
+ /* @__PURE__ */ jsx(
23318
+ Field,
23319
+ {
23320
+ label: tr(
23321
+ "fluidgrids.builder.nodeSettings.onTimeout",
23322
+ "On timeout"
23323
+ ),
23324
+ children: /* @__PURE__ */ jsxs(
23325
+ "select",
23326
+ {
23327
+ value: errorConfig?.timeout?.onTimeout ?? "stop",
23328
+ onChange: (e) => writeErrorConfig({
23329
+ timeout: {
23330
+ ...errorConfig?.timeout ?? { duration: 3e4 },
23331
+ onTimeout: e.target.value,
23332
+ timeoutBranchId: e.target.value === "branch" ? errorConfig?.timeout?.timeoutBranchId : void 0
23333
+ }
23334
+ }),
23335
+ "data-testid": "ndv-settings-on-timeout",
23336
+ className: cn(inputCx, "max-w-xs"),
23337
+ children: [
23338
+ /* @__PURE__ */ jsx("option", { value: "stop", children: tr(
23339
+ "fluidgrids.builder.nodeSettings.onTimeoutStop",
23340
+ "Use Retry/On Error settings above"
23341
+ ) }),
23342
+ /* @__PURE__ */ jsx("option", { value: "continue", children: tr(
23343
+ "fluidgrids.builder.nodeSettings.onTimeoutContinue",
23344
+ "Continue on timeout"
23345
+ ) }),
23346
+ /* @__PURE__ */ jsx("option", { value: "branch", children: tr(
23347
+ "fluidgrids.builder.nodeSettings.onTimeoutBranch",
23348
+ "Route to a specific branch"
23349
+ ) })
23350
+ ]
23351
+ }
23352
+ )
23353
+ }
23354
+ ),
23355
+ errorConfig?.timeout?.onTimeout === "branch" && /* @__PURE__ */ jsx(
23356
+ Field,
23357
+ {
23358
+ label: tr(
23359
+ "fluidgrids.builder.nodeSettings.timeoutBranchTarget",
23360
+ "Timeout branch target"
23361
+ ),
23362
+ children: /* @__PURE__ */ jsxs(
23363
+ "select",
23364
+ {
23365
+ value: errorConfig?.timeout?.timeoutBranchId ?? "",
23366
+ onChange: (e) => writeErrorConfig({
23367
+ timeout: {
23368
+ ...errorConfig?.timeout ?? { duration: 3e4 },
23369
+ timeoutBranchId: e.target.value || void 0
23370
+ }
23371
+ }),
23372
+ "data-testid": "ndv-settings-timeout-branch-id",
23373
+ className: cn(inputCx, "max-w-xs"),
23374
+ children: [
23375
+ /* @__PURE__ */ jsx("option", { value: "", children: tr(
23376
+ "fluidgrids.builder.nodeSettings.selectNode",
23377
+ "Select a node\u2026"
23378
+ ) }),
23379
+ branchTargets.map((n) => /* @__PURE__ */ jsx("option", { value: n.id, children: nodeTitle(n) }, n.id))
23380
+ ]
23381
+ }
23382
+ )
23383
+ }
23384
+ )
23385
+ ] })
23386
+ ] }),
23387
+ /* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
23388
+ /* @__PURE__ */ jsx("div", { className: SECTION_LABEL4, children: tr("fluidgrids.builder.nodeSettings.otherSection", "Other") }),
23389
+ /* @__PURE__ */ jsxs("label", { className: "flex w-fit cursor-pointer items-center gap-2 text-sm", children: [
23390
+ /* @__PURE__ */ jsx(
23391
+ "input",
23392
+ {
23393
+ type: "checkbox",
23394
+ checked: alwaysOutputData,
23395
+ onChange: (e) => writeExecutionSettings({ alwaysOutputData: e.target.checked }),
23396
+ "data-testid": "ndv-settings-always-output-data",
23397
+ className: "size-4"
23398
+ }
23399
+ ),
23400
+ /* @__PURE__ */ jsx("span", { children: tr(
23401
+ "fluidgrids.builder.nodeSettings.alwaysOutputDataLabel",
23402
+ "Always output data"
23403
+ ) })
23404
+ ] }),
23405
+ /* @__PURE__ */ jsxs("label", { className: "flex w-fit cursor-pointer items-center gap-2 text-sm", children: [
23406
+ /* @__PURE__ */ jsx(
23407
+ "input",
23408
+ {
23409
+ type: "checkbox",
23410
+ checked: executeOnce,
23411
+ onChange: (e) => writeExecutionSettings({ executeOnce: e.target.checked }),
23412
+ "data-testid": "ndv-settings-execute-once",
23413
+ className: "size-4"
23414
+ }
23415
+ ),
23416
+ /* @__PURE__ */ jsx("span", { children: tr(
23417
+ "fluidgrids.builder.nodeSettings.executeOnceLabel",
23418
+ "Execute once"
23419
+ ) })
23420
+ ] })
23421
+ ] }),
23422
+ /* @__PURE__ */ jsxs("section", { className: "space-y-2", children: [
23423
+ /* @__PURE__ */ jsx("div", { className: SECTION_LABEL4, children: tr("fluidgrids.builder.nodeSettings.notesSection", "Notes") }),
23424
+ /* @__PURE__ */ jsx(
23425
+ "textarea",
23426
+ {
23427
+ value: notes,
23428
+ onChange: (e) => writeNotes(e.target.value),
23429
+ rows: 4,
23430
+ placeholder: tr(
23431
+ "fluidgrids.builder.nodeSettings.notesPlaceholder",
23432
+ "Leave a note for teammates about what this node does\u2026"
23433
+ ),
23434
+ "data-testid": "ndv-settings-notes",
23435
+ className: cn(inputCx, "resize-y")
23436
+ }
23437
+ )
23438
+ ] })
23439
+ ] });
23440
+ }
23441
+ function Field({
23442
+ label,
23443
+ children
23444
+ }) {
23445
+ return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
23446
+ /* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-foreground", children: label }),
23447
+ children
23448
+ ] });
23449
+ }
22677
23450
  function useMediaQuery(query) {
22678
23451
  const [matches, setMatches] = React2.useState(false);
22679
23452
  React2.useEffect(() => {
@@ -22685,7 +23458,7 @@ function useMediaQuery(query) {
22685
23458
  }, [query]);
22686
23459
  return matches;
22687
23460
  }
22688
- var SECTION_LABEL4 = "text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground";
23461
+ var SECTION_LABEL5 = "text-[11px] font-semibold uppercase tracking-[0.12em] text-muted-foreground";
22689
23462
  function NodeDetailView() {
22690
23463
  const tr = useTr();
22691
23464
  const ndv = useFlowStore((s) => s.workflow.ndv);
@@ -22841,7 +23614,7 @@ function NodeDetailView() {
22841
23614
  ),
22842
23615
  children: [
22843
23616
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-4 py-2.5", children: [
22844
- /* @__PURE__ */ jsx("span", { className: SECTION_LABEL4, children: tr("fluidgrids.builder.nodeDetailView.inputSection", "Input") }),
23617
+ /* @__PURE__ */ jsx("span", { className: SECTION_LABEL5, children: tr("fluidgrids.builder.nodeDetailView.inputSection", "Input") }),
22845
23618
  sourceIds.length > 0 && /* @__PURE__ */ jsx(
22846
23619
  "select",
22847
23620
  {
@@ -22930,10 +23703,14 @@ function NodeDetailView() {
22930
23703
  }
22931
23704
  )
22932
23705
  }
22933
- ) : /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-auto p-4 text-xs text-muted-foreground", children: tr(
22934
- "fluidgrids.builder.nodeDetailView.noSettings",
22935
- "No additional settings for this node."
22936
- ) })
23706
+ ) : /* @__PURE__ */ jsx(
23707
+ "div",
23708
+ {
23709
+ className: "min-h-0 flex-1 overflow-auto p-4",
23710
+ "data-testid": "ndv-settings",
23711
+ children: /* @__PURE__ */ jsx(NodeSettingsPanel, { config: config2 })
23712
+ }
23713
+ )
22937
23714
  ]
22938
23715
  }
22939
23716
  ),
@@ -22948,7 +23725,7 @@ function NodeDetailView() {
22948
23725
  ),
22949
23726
  children: [
22950
23727
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-4 py-2.5", children: [
22951
- /* @__PURE__ */ jsx("span", { className: SECTION_LABEL4, children: tr(
23728
+ /* @__PURE__ */ jsx("span", { className: SECTION_LABEL5, children: tr(
22952
23729
  "fluidgrids.builder.nodeDetailView.outputSection",
22953
23730
  "Output"
22954
23731
  ) }),
@@ -24434,5 +25211,5 @@ var FlowBuilderPage = ({
24434
25211
  };
24435
25212
 
24436
25213
  export { Card2 as Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ConnectionFormDialog, ConnectionSelector, EntityTagPicker, FLUIDGRIDS_ENTITY_TYPES, FlowBuilderPage, FluidGridsProvider, ProviderPicker, SchemaConnectionForm, ScopePicker, TemplateCard, buildNodeCheck, buildRequiredNodeTypes, listCustomBlocks, mergeStickyNotes, refetchStoreNodes, registerCustomBlock, resolveUiSpec, stripSubmitActions, tagLabel, useAvailableTags, useConnection, useConnectionDialog, useConnections, useConnectionsByProvider, useCreateConnection, useCreateTag, useDraftEntityTags, useEntityTags, useFluidGridsContext, useImportWorkflowTemplate, useInitiateOAuth, useInstalledNodes, useNodeExecution, useProviderByKey, useProviderCatalog, useProviders, useReplaceEntityTags, useSearchTags, useTagEntity, useUntagEntity, useWorkflowTemplates };
24437
- //# sourceMappingURL=chunk-35YDFYV2.js.map
24438
- //# sourceMappingURL=chunk-35YDFYV2.js.map
25214
+ //# sourceMappingURL=chunk-VTKT6XDA.js.map
25215
+ //# sourceMappingURL=chunk-VTKT6XDA.js.map