@burdenoff/fluidgrids-fe-sdk 2026.706.2 → 2026.707.1

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.
@@ -1,4 +1,4 @@
1
- export { WorkflowBuilder } from './chunk-NSK663QW.js';
1
+ export { WorkflowBuilder } from './chunk-VJRIO6JW.js';
2
2
  import './chunk-7VEOUEIN.js';
3
3
  import './chunk-BQXHJIER.js';
4
4
  import './chunk-LUGJJ7LL.js';
@@ -9,5 +9,5 @@ import './chunk-5BDQNSP3.js';
9
9
  import './chunk-WWU2O2SR.js';
10
10
  import './chunk-XQP33UJR.js';
11
11
  import './chunk-Z54K22LP.js';
12
- //# sourceMappingURL=WorkflowBuilder-2QAGGCA3.js.map
13
- //# sourceMappingURL=WorkflowBuilder-2QAGGCA3.js.map
12
+ //# sourceMappingURL=WorkflowBuilder-HCFEF5VJ.js.map
13
+ //# sourceMappingURL=WorkflowBuilder-HCFEF5VJ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"WorkflowBuilder-2QAGGCA3.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"WorkflowBuilder-HCFEF5VJ.js"}
@@ -7979,12 +7979,14 @@ function useSaveWorkflow() {
7979
7979
  }
7980
7980
  }
7981
7981
  }
7982
+ return true;
7982
7983
  } catch (error) {
7983
7984
  const message = error instanceof Error ? error.message : "Unknown error";
7984
7985
  console.error("Error saving workflow:", message);
7985
7986
  toast.error("Failed to save workflow", {
7986
7987
  description: message
7987
7988
  });
7989
+ return false;
7988
7990
  } finally {
7989
7991
  setIsSaving(false);
7990
7992
  }
@@ -8011,6 +8013,11 @@ function NodePropertyPanel({
8011
8013
  const [filteredJobs, setFilteredJobs] = useState([]);
8012
8014
  const [searchTerm, setSearchTerm] = useState("");
8013
8015
  const [isLoading, setIsLoading] = useState(false);
8016
+ const [dataSinkSaveState, setDataSinkSaveState] = useState("idle");
8017
+ const [dataSinkSaveMessage, setDataSinkSaveMessage] = useState("");
8018
+ const [dataSinkKeyDraft, setDataSinkKeyDraft] = useState("");
8019
+ const dataSinkSaveInFlightRef = useRef(false);
8020
+ const dataSinkSaveNodeIdRef = useRef(null);
8014
8021
  useFlowStore((s) => s.workflow.id);
8015
8022
  const { saveToBackend, isSaving } = useSaveWorkflow();
8016
8023
  const operationsArray = useMemo(() => {
@@ -8098,6 +8105,20 @@ function NodePropertyPanel({
8098
8105
  () => String(type) === "store/bigconsole_datasink" && effectiveCurrentOperation?.name === "postDataToDataSink",
8099
8106
  [effectiveCurrentOperation?.name, type]
8100
8107
  );
8108
+ useEffect(() => {
8109
+ if (!shouldSaveConfigurationToBackend) {
8110
+ setDataSinkKeyDraft("");
8111
+ setDataSinkSaveState("idle");
8112
+ setDataSinkSaveMessage("");
8113
+ return;
8114
+ }
8115
+ setDataSinkKeyDraft(String(data?.args?.state?.dataSinkKey ?? ""));
8116
+ if (dataSinkSaveInFlightRef.current && dataSinkSaveNodeIdRef.current === id) {
8117
+ return;
8118
+ }
8119
+ setDataSinkSaveState("idle");
8120
+ setDataSinkSaveMessage("");
8121
+ }, [data?.args?.state?.dataSinkKey, id, shouldSaveConfigurationToBackend]);
8101
8122
  const connectionAdapters = useMemo(
8102
8123
  () => effectiveCurrentOperation?.connectionAdapters || effectiveCurrentOperation?.credentialAdapters || data?.nodeData?.connectionAdapters || data?.nodeData?.credentialAdapters || [],
8103
8124
  [
@@ -8168,18 +8189,73 @@ function NodePropertyPanel({
8168
8189
  }
8169
8190
  current[keys[keys.length - 1]] = value;
8170
8191
  }
8192
+ if (shouldSaveConfigurationToBackend && (isSaving || dataSinkSaveInFlightRef.current)) {
8193
+ setDataSinkSaveState("saving");
8194
+ setDataSinkSaveMessage("A workflow save is already in progress\u2026");
8195
+ toast.info("A workflow save is already in progress");
8196
+ return;
8197
+ }
8198
+ if (shouldSaveConfigurationToBackend) {
8199
+ const dataSinkKey = String(newState.dataSinkKey ?? "").trim();
8200
+ if (!dataSinkKey) {
8201
+ setDataSinkSaveState("error");
8202
+ setDataSinkSaveMessage("Enter a DataSink Key before saving.");
8203
+ toast.error("Enter a DataSink Key before saving");
8204
+ return;
8205
+ }
8206
+ dataSinkSaveInFlightRef.current = true;
8207
+ dataSinkSaveNodeIdRef.current = id;
8208
+ setDataSinkKeyDraft(dataSinkKey);
8209
+ newState.dataSinkKey = dataSinkKey;
8210
+ }
8171
8211
  updateData({
8172
8212
  args: {
8173
8213
  ...data?.args ?? {},
8174
8214
  state: newState
8175
8215
  }
8176
8216
  });
8177
- if (shouldSaveConfigurationToBackend && !isSaving) {
8217
+ if (shouldSaveConfigurationToBackend) {
8218
+ const dataSinkKey = String(newState.dataSinkKey ?? "");
8219
+ setDataSinkSaveState("saving");
8220
+ setDataSinkSaveMessage(`Saving DataSink key \u201C${dataSinkKey}\u201D\u2026`);
8221
+ const toastId = toast.loading("Saving DataSink key", {
8222
+ description: dataSinkKey
8223
+ });
8178
8224
  window.setTimeout(() => {
8179
- void saveToBackend().catch((error) => {
8225
+ void saveToBackend().then((saved) => {
8226
+ if (!saved) {
8227
+ setDataSinkSaveState("error");
8228
+ setDataSinkSaveMessage(
8229
+ "Workflow save failed. The DataSink key was not persisted."
8230
+ );
8231
+ toast.error("Failed to save DataSink key", {
8232
+ id: toastId,
8233
+ description: "Workflow save failed."
8234
+ });
8235
+ return;
8236
+ }
8237
+ setDataSinkSaveState("saved");
8238
+ setDataSinkSaveMessage(
8239
+ `DataSink key \u201C${dataSinkKey}\u201D saved to the workflow.`
8240
+ );
8241
+ toast.success("DataSink key saved", {
8242
+ id: toastId,
8243
+ description: "Workflow configuration was saved successfully."
8244
+ });
8245
+ }).catch((error) => {
8246
+ const message = error instanceof Error ? error.message : "Failed to save DataSink configuration";
8247
+ setDataSinkSaveState("error");
8248
+ setDataSinkSaveMessage(message);
8180
8249
  console.error("Error saving DataSink configuration:", error);
8250
+ toast.error("Failed to save DataSink key", {
8251
+ id: toastId,
8252
+ description: message
8253
+ });
8254
+ }).finally(() => {
8255
+ dataSinkSaveInFlightRef.current = false;
8256
+ dataSinkSaveNodeIdRef.current = null;
8181
8257
  });
8182
- }, 0);
8258
+ }, 100);
8183
8259
  }
8184
8260
  };
8185
8261
  const resolvedUi = useMemo(
@@ -8256,7 +8332,56 @@ function NodePropertyPanel({
8256
8332
  ] }),
8257
8333
  /* @__PURE__ */ jsxs("div", { className: "flex pt-5 flex-col", children: [
8258
8334
  /* @__PURE__ */ jsx("div", { className: "text-xs text-card-foreground/60 font-semibold", children: "Properties" }),
8259
- resolvedUi ? /* @__PURE__ */ jsx(
8335
+ shouldSaveConfigurationToBackend ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 pt-2", children: [
8336
+ /* @__PURE__ */ jsxs("div", { children: [
8337
+ /* @__PURE__ */ jsx("div", { className: "text-lg font-semibold text-card-foreground", children: "Send Data to BigConsole DataSink" }),
8338
+ /* @__PURE__ */ jsx("p", { className: "mt-3 text-sm text-muted-foreground", children: "Choose the DataSink key. Data is taken automatically from the previous node, and the BigConsole connection is handled automatically." })
8339
+ ] }),
8340
+ /* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-2 text-sm font-medium text-card-foreground", children: [
8341
+ /* @__PURE__ */ jsxs("span", { children: [
8342
+ "DataSink Key",
8343
+ " ",
8344
+ /* @__PURE__ */ jsx("span", { className: "text-[var(--color-status-error-text)]", children: "*" })
8345
+ ] }),
8346
+ /* @__PURE__ */ jsx(
8347
+ "input",
8348
+ {
8349
+ type: "text",
8350
+ value: dataSinkKeyDraft,
8351
+ onChange: (event) => {
8352
+ setDataSinkKeyDraft(event.target.value);
8353
+ if (dataSinkSaveState !== "idle") {
8354
+ setDataSinkSaveState("idle");
8355
+ setDataSinkSaveMessage("");
8356
+ }
8357
+ },
8358
+ placeholder: "Target DataSink key (e.g., users_analytics)",
8359
+ className: "w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground outline-none transition-colors placeholder:text-muted-foreground focus:border-primary focus:ring-2 focus:ring-primary/20 disabled:opacity-50",
8360
+ disabled: dataSinkSaveState === "saving" || isSaving
8361
+ }
8362
+ )
8363
+ ] }),
8364
+ /* @__PURE__ */ jsx(
8365
+ "button",
8366
+ {
8367
+ type: "button",
8368
+ onClick: () => submittedData({ dataSinkKey: dataSinkKeyDraft }),
8369
+ disabled: dataSinkSaveState === "saving" || isSaving,
8370
+ className: "self-start rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-50",
8371
+ children: dataSinkSaveState === "saving" || isSaving ? "Saving\u2026" : "Save Configuration"
8372
+ }
8373
+ ),
8374
+ dataSinkSaveMessage ? /* @__PURE__ */ jsx(
8375
+ "div",
8376
+ {
8377
+ className: [
8378
+ "rounded-md border px-3 py-2 text-xs",
8379
+ dataSinkSaveState === "saved" ? "border-[var(--color-status-success-border)] bg-[var(--color-status-success-bg-subtle)] text-[var(--color-status-success-text)]" : dataSinkSaveState === "error" ? "border-[var(--color-status-error-border)] bg-[var(--color-status-error-bg-subtle)] text-[var(--color-status-error-text)]" : "border-border bg-muted/30 text-muted-foreground"
8380
+ ].join(" "),
8381
+ children: dataSinkSaveMessage
8382
+ }
8383
+ ) : null
8384
+ ] }) : resolvedUi ? /* @__PURE__ */ jsx(
8260
8385
  BlocksRenderer,
8261
8386
  {
8262
8387
  spec: resolvedUi.spec,
@@ -11806,6 +11931,23 @@ gql$1`
11806
11931
  }
11807
11932
  `;
11808
11933
 
11934
+ // src/builder/components/flow-builder/components/store/store-node-availability.ts
11935
+ function getStoreNodeType(node, isInstalled) {
11936
+ const manifestNodeType = node.manifest?.nodeType;
11937
+ return manifestNodeType ?? (isInstalled ? `store/${node.slug}` : void 0);
11938
+ }
11939
+ function getStoreNodeAvailability(node, isInstalled) {
11940
+ const nodeType = getStoreNodeType(node, isInstalled);
11941
+ const isInternalBuiltin = !!nodeType && nodeType.startsWith("internal:");
11942
+ const isRegistryBacked = !!nodeType && AVAILABLE_NODES.some((availableNode) => availableNode.type === nodeType);
11943
+ const isPrebuilt = !isInstalled && (isInternalBuiltin || isRegistryBacked);
11944
+ return {
11945
+ nodeType,
11946
+ isPrebuilt,
11947
+ isDraggable: !!nodeType && (isInstalled || isPrebuilt)
11948
+ };
11949
+ }
11950
+
11809
11951
  // src/builder/contants/symbols.ts
11810
11952
  var NODE_TYPE_DRAG_DATA_FORMAT = "application/flow-builder.node-type";
11811
11953
  var NODE_OPERATION_DRAG_DATA_FORMAT = "application/flow-builder.node-operation";
@@ -11814,6 +11956,7 @@ function StoreNodeListItem({
11814
11956
  description,
11815
11957
  icon,
11816
11958
  isInstalled,
11959
+ isPrebuilt,
11817
11960
  hasUpdate,
11818
11961
  nodeType,
11819
11962
  isDraggable,
@@ -11871,6 +12014,26 @@ function StoreNodeListItem({
11871
12014
  "Installed"
11872
12015
  ]
11873
12016
  }
12017
+ ),
12018
+ isPrebuilt && !isInstalled && !hasUpdate && /* @__PURE__ */ jsxs(
12019
+ "span",
12020
+ {
12021
+ className: "shrink-0 inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded text-[10px] font-semibold",
12022
+ style: {
12023
+ background: "var(--color-status-info-bgSubtle)",
12024
+ color: "var(--color-status-info-text)"
12025
+ },
12026
+ children: [
12027
+ /* @__PURE__ */ jsx(
12028
+ "span",
12029
+ {
12030
+ className: "size-1.5 rounded-full inline-block",
12031
+ style: { background: "var(--color-status-info-bg)" }
12032
+ }
12033
+ ),
12034
+ "Prebuilt"
12035
+ ]
12036
+ }
11874
12037
  )
11875
12038
  ] }),
11876
12039
  description && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground truncate mt-0.5 leading-snug", children: description })
@@ -11956,9 +12119,7 @@ function StoreCategoryList({
11956
12119
  const installation = installationsMap.get(node.id);
11957
12120
  const isInstalled = installedAppIds.has(node.id);
11958
12121
  const hasUpdate = isInstalled && !!installation?.installedVersion && !!node.manifestVersion && installation.installedVersion !== node.manifestVersion;
11959
- const manifestNodeType = node.manifest?.nodeType;
11960
- const nodeType = manifestNodeType ?? (isInstalled ? `store/${node.slug}` : void 0);
11961
- const isDraggable = !!nodeType && (isInstalled || AVAILABLE_NODES.some((n) => n.type === nodeType));
12122
+ const { nodeType, isPrebuilt, isDraggable } = getStoreNodeAvailability(node, isInstalled);
11962
12123
  return /* @__PURE__ */ jsx(
11963
12124
  StoreNodeListItem,
11964
12125
  {
@@ -11966,6 +12127,7 @@ function StoreCategoryList({
11966
12127
  description: node.description,
11967
12128
  icon: node.icon,
11968
12129
  isInstalled,
12130
+ isPrebuilt,
11969
12131
  hasUpdate,
11970
12132
  nodeType,
11971
12133
  isDraggable,
@@ -12089,9 +12251,7 @@ function StoreCategoryNodes({
12089
12251
  const installation = installationsMap.get(node.id);
12090
12252
  const isInstalled = installedAppIds.has(node.id);
12091
12253
  const hasUpdate = isInstalled && !!installation?.installedVersion && !!node.manifestVersion && installation.installedVersion !== node.manifestVersion;
12092
- const manifestNodeType = node.manifest?.nodeType;
12093
- const nodeType = manifestNodeType ?? (isInstalled ? `store/${node.slug}` : void 0);
12094
- const isDraggable = !!nodeType && (isInstalled || AVAILABLE_NODES.some((n) => n.type === nodeType));
12254
+ const { nodeType, isPrebuilt, isDraggable } = getStoreNodeAvailability(node, isInstalled);
12095
12255
  return /* @__PURE__ */ jsx(
12096
12256
  StoreNodeListItem,
12097
12257
  {
@@ -12099,6 +12259,7 @@ function StoreCategoryNodes({
12099
12259
  description: node.description,
12100
12260
  icon: node.icon,
12101
12261
  isInstalled,
12262
+ isPrebuilt,
12102
12263
  hasUpdate,
12103
12264
  nodeType,
12104
12265
  isDraggable,
@@ -12326,8 +12487,7 @@ function StoreNodeDetail({ node, onBack }) {
12326
12487
  const context = useContext(FluidGridsContext);
12327
12488
  const workspaceId = context?.workspaceId ?? getFluidGridsConfig().workspaceId;
12328
12489
  const isInstalled = installedAppIds.has(node.id);
12329
- const manifestNodeType = node.manifest?.nodeType;
12330
- const nodeType = manifestNodeType ?? (isInstalled ? `store/${node.slug}` : void 0);
12490
+ const { nodeType, isPrebuilt } = getStoreNodeAvailability(node, isInstalled);
12331
12491
  const installation = installationsMap.get(node.id);
12332
12492
  const installedVersion = installation?.installedVersion;
12333
12493
  const installationId = installation?.installationId;
@@ -12335,7 +12495,7 @@ function StoreNodeDetail({ node, onBack }) {
12335
12495
  const hasUpdate = isInstalled && !!installedVersion && !!latestVersion && installedVersion !== latestVersion;
12336
12496
  const isFree = node.pricingModel === "FREE";
12337
12497
  const isPurchased = node.isPurchased === true;
12338
- const canInstall = isFree || isPurchased;
12498
+ const canInstall = !isPrebuilt && (isFree || isPurchased);
12339
12499
  const isInstalling = installing === node.id;
12340
12500
  const isUpdating = updating === node.id;
12341
12501
  const handleInstall = async () => {
@@ -12485,7 +12645,7 @@ function StoreNodeDetail({ node, onBack }) {
12485
12645
  node.publisher?.isVerified && /* @__PURE__ */ jsx(BadgeCheck, { className: "size-3.5 text-primary" })
12486
12646
  ] })
12487
12647
  ] }),
12488
- (isInstalled || hasUpdate || node.featured) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-2 mb-4 flex-wrap", children: [
12648
+ (isInstalled || isPrebuilt || hasUpdate || node.featured) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-2 mb-4 flex-wrap", children: [
12489
12649
  hasUpdate && /* @__PURE__ */ jsxs(
12490
12650
  "span",
12491
12651
  {
@@ -12522,6 +12682,26 @@ function StoreNodeDetail({ node, onBack }) {
12522
12682
  ]
12523
12683
  }
12524
12684
  ),
12685
+ isPrebuilt && /* @__PURE__ */ jsxs(
12686
+ "span",
12687
+ {
12688
+ className: "inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-semibold",
12689
+ style: {
12690
+ background: "var(--color-status-info-bgSubtle)",
12691
+ color: "var(--color-status-info-text)"
12692
+ },
12693
+ children: [
12694
+ /* @__PURE__ */ jsx(
12695
+ "span",
12696
+ {
12697
+ className: "size-1.5 rounded-full",
12698
+ style: { background: "var(--color-status-info-bg)" }
12699
+ }
12700
+ ),
12701
+ "Prebuilt"
12702
+ ]
12703
+ }
12704
+ ),
12525
12705
  node.featured && !isInstalled && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs font-semibold bg-primary/10 text-primary", children: "Featured" })
12526
12706
  ] }),
12527
12707
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-4 text-xs text-muted-foreground mb-4", children: [
@@ -12544,7 +12724,7 @@ function StoreNodeDetail({ node, onBack }) {
12544
12724
  ] })
12545
12725
  ] }),
12546
12726
  node.description && /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground/80 leading-relaxed mb-4", children: node.description }),
12547
- isInstalled && /* @__PURE__ */ jsx("div", { className: "mb-4 -mx-3 rounded-lg border border-border/50", children: /* @__PURE__ */ jsx(StoreNodeOperations, { nodeType }) }),
12727
+ (isInstalled || isPrebuilt) && /* @__PURE__ */ jsx("div", { className: "mb-4 -mx-3 rounded-lg border border-border/50", children: /* @__PURE__ */ jsx(StoreNodeOperations, { nodeType }) }),
12548
12728
  node.publisher && /* @__PURE__ */ jsxs("div", { className: "mb-4 p-2.5 rounded-lg bg-muted/50 flex items-center gap-2", children: [
12549
12729
  /* @__PURE__ */ jsx("div", { className: "size-6 rounded bg-muted flex items-center justify-center shrink-0", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-bold text-muted-foreground", children: node.publisher.name.charAt(0) }) }),
12550
12730
  /* @__PURE__ */ jsx("span", { className: "text-xs text-foreground font-medium flex-1 min-w-0 truncate", children: node.publisher.name }),
@@ -12605,6 +12785,16 @@ function StoreNodeDetail({ node, onBack }) {
12605
12785
  "Uninstall"
12606
12786
  ] })
12607
12787
  }
12788
+ ) : isPrebuilt ? /* @__PURE__ */ jsx(
12789
+ "div",
12790
+ {
12791
+ className: "w-full rounded-md px-3 py-2 text-center text-sm font-medium",
12792
+ style: {
12793
+ background: "var(--color-status-info-bgSubtle)",
12794
+ color: "var(--color-status-info-text)"
12795
+ },
12796
+ children: "Prebuilt \u2014 drag operations above onto the canvas"
12797
+ }
12608
12798
  ) : canInstall ? /* @__PURE__ */ jsx(
12609
12799
  Button$1,
12610
12800
  {
@@ -23039,5 +23229,5 @@ function WorkflowBuilder() {
23039
23229
  }
23040
23230
 
23041
23231
  export { Card2 as Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ConfigSchemaForm, ConnectionFormDialog, ConnectionSelector, FlowBuilderPage, FluidGridsProvider, ProviderPicker, TemplateCard, ThemeProvider, WorkflowBuilder, getProviderForm, listCustomBlocks, refetchStoreNodes, registerCustomBlock, resolveUiSpec, stripSubmitActions, useConnection, useConnectionDialog, useConnections, useConnectionsByProvider, useCreateConnection, useFluidGridsContext, useImportWorkflowTemplate, useInitiateOAuth, useNodeExecution, useProviderByKey, useProviderCatalog, useProviders, useWorkflowTemplates };
23042
- //# sourceMappingURL=chunk-NSK663QW.js.map
23043
- //# sourceMappingURL=chunk-NSK663QW.js.map
23232
+ //# sourceMappingURL=chunk-VJRIO6JW.js.map
23233
+ //# sourceMappingURL=chunk-VJRIO6JW.js.map