@trops/dash-core 0.1.456 → 0.1.458

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/index.js CHANGED
@@ -22126,13 +22126,26 @@ var LayoutBuilder = function LayoutBuilder(_ref) {
22126
22126
  // Listen for AI widget builder placement — modifies layout state directly
22127
22127
  React.useEffect(function () {
22128
22128
  var handler = function handler(e) {
22129
+ var _wsRef$current;
22129
22130
  var _ref4 = e.detail || {},
22130
22131
  widgetComponentName = _ref4.widgetComponentName,
22131
22132
  cellNumber = _ref4.cellNumber,
22132
- gridItemId = _ref4.gridItemId;
22133
+ gridItemId = _ref4.gridItemId,
22134
+ workspaceId = _ref4.workspaceId;
22133
22135
  if (!widgetComponentName || !cellNumber || !gridItemId) return;
22134
22136
  var ws = wsRef.current;
22135
22137
  if (!(ws !== null && ws !== void 0 && ws.layout)) return;
22138
+
22139
+ // Workspace-id guard: multiple LayoutBuilders are mounted (one per
22140
+ // open dashboard tab) and all listen to this global event. If the
22141
+ // event carries a workspaceId, only the matching workspace acts —
22142
+ // otherwise gridItemId collisions across workspaces (small ints)
22143
+ // would let the wrong dashboard handle the placement and silently
22144
+ // overwrite a cell. Older dash-electron versions that don't yet
22145
+ // pass workspaceId fall through (opt-in guard, backward-compatible).
22146
+ if (workspaceId && ((_wsRef$current = wsRef.current) === null || _wsRef$current === void 0 ? void 0 : _wsRef$current.id) !== workspaceId) {
22147
+ return;
22148
+ }
22136
22149
  var gridItem = ws.layout.find(function (item) {
22137
22150
  return item.id === gridItemId;
22138
22151
  });
@@ -22176,12 +22189,21 @@ var LayoutBuilder = function LayoutBuilder(_ref) {
22176
22189
  // Listen for AI widget remix — swaps existing widget component in-place
22177
22190
  React.useEffect(function () {
22178
22191
  var handler = function handler(e) {
22192
+ var _wsRef$current3;
22179
22193
  var _ref5 = e.detail || {},
22180
22194
  widgetComponentName = _ref5.widgetComponentName,
22181
- widgetId = _ref5.widgetId;
22195
+ widgetId = _ref5.widgetId,
22196
+ workspaceId = _ref5.workspaceId;
22182
22197
  if (!widgetComponentName || !widgetId) return;
22183
22198
  var ws = wsRef.current;
22184
22199
  if (!(ws !== null && ws !== void 0 && ws.layout)) return;
22200
+
22201
+ // Same workspace-id guard as the place-widget handler — keeps
22202
+ // the swap from acting on a different open dashboard's widget
22203
+ // when widgetIds collide across workspaces.
22204
+ if (workspaceId && ((_wsRef$current3 = wsRef.current) === null || _wsRef$current3 === void 0 ? void 0 : _wsRef$current3.id) !== workspaceId) {
22205
+ return;
22206
+ }
22185
22207
  var config = ComponentManager.config(widgetComponentName);
22186
22208
  if (!config) {
22187
22209
  return;
@@ -47227,71 +47249,75 @@ var ProvidersSection = function ProvidersSection(_ref) {
47227
47249
  if (result !== null && result !== void 0 && result.catalog) setCatalog(result.catalog);
47228
47250
  }, function () {});
47229
47251
  }, [dashApi]);
47230
- var _useState3 = React.useState("credentials"),
47252
+ var _useState3 = React.useState("all"),
47231
47253
  _useState4 = _slicedToArray(_useState3, 2),
47232
47254
  providerTab = _useState4[0],
47233
47255
  setProviderTab = _useState4[1];
47234
- var _useState5 = React.useState(null),
47256
+ var _useState5 = React.useState(""),
47235
47257
  _useState6 = _slicedToArray(_useState5, 2),
47236
- selectedName = _useState6[0],
47237
- setSelectedName = _useState6[1];
47238
- var _useState7 = React.useState(false),
47258
+ searchQuery = _useState6[0],
47259
+ setSearchQuery = _useState6[1];
47260
+ var _useState7 = React.useState(null),
47239
47261
  _useState8 = _slicedToArray(_useState7, 2),
47240
- isCreating = _useState8[0],
47241
- setIsCreating = _useState8[1];
47262
+ selectedName = _useState8[0],
47263
+ setSelectedName = _useState8[1];
47264
+ var _useState9 = React.useState(false),
47265
+ _useState0 = _slicedToArray(_useState9, 2),
47266
+ isCreating = _useState0[0],
47267
+ setIsCreating = _useState0[1];
47242
47268
  // When the user clicks "+ New Provider" without a pre-selected
47243
47269
  // class (Settings header button), show the class chooser
47244
47270
  // (Credential / MCP / WebSocket) instead of defaulting to the
47245
47271
  // credential form. Widget Builder's deep-link path passes a class
47246
47272
  // explicitly and bypasses this chooser.
47247
- var _useState9 = React.useState(false),
47248
- _useState0 = _slicedToArray(_useState9, 2),
47249
- isShowingClassChooser = _useState0[0],
47250
- setIsShowingClassChooser = _useState0[1];
47273
+ var _useState1 = React.useState(false),
47274
+ _useState10 = _slicedToArray(_useState1, 2),
47275
+ isShowingClassChooser = _useState10[0],
47276
+ setIsShowingClassChooser = _useState10[1];
47251
47277
  // Tracks whether the current create-flow detail was reached via the
47252
47278
  // chooser (vs. the Widget Builder deep-link or list-edit). Only the
47253
47279
  // chooser-entry path renders the "← Back" affordance, since that's
47254
47280
  // the only path that has somewhere to go back to.
47255
- var _useState1 = React.useState(false),
47256
- _useState10 = _slicedToArray(_useState1, 2),
47257
- cameFromClassChooser = _useState10[0],
47258
- setCameFromClassChooser = _useState10[1];
47259
47281
  var _useState11 = React.useState(false),
47260
47282
  _useState12 = _slicedToArray(_useState11, 2),
47261
- isEditing = _useState12[0],
47262
- setIsEditing = _useState12[1];
47263
- var _useState13 = React.useState(""),
47283
+ cameFromClassChooser = _useState12[0],
47284
+ setCameFromClassChooser = _useState12[1];
47285
+ var _useState13 = React.useState(false),
47264
47286
  _useState14 = _slicedToArray(_useState13, 2),
47265
- formName = _useState14[0],
47266
- setFormName = _useState14[1];
47287
+ isEditing = _useState14[0],
47288
+ setIsEditing = _useState14[1];
47267
47289
  var _useState15 = React.useState(""),
47268
47290
  _useState16 = _slicedToArray(_useState15, 2),
47269
- formType = _useState16[0],
47270
- setFormType = _useState16[1];
47271
- var _useState17 = React.useState({}),
47291
+ formName = _useState16[0],
47292
+ setFormName = _useState16[1];
47293
+ var _useState17 = React.useState(""),
47272
47294
  _useState18 = _slicedToArray(_useState17, 2),
47273
- formCredentials = _useState18[0],
47274
- setFormCredentials = _useState18[1];
47275
- var _useState19 = React.useState(null),
47295
+ formType = _useState18[0],
47296
+ setFormType = _useState18[1];
47297
+ var _useState19 = React.useState({}),
47276
47298
  _useState20 = _slicedToArray(_useState19, 2),
47277
- deleteTarget = _useState20[0],
47278
- setDeleteTarget = _useState20[1];
47279
- var _useState21 = React.useState(false),
47299
+ formCredentials = _useState20[0],
47300
+ setFormCredentials = _useState20[1];
47301
+ var _useState21 = React.useState(null),
47280
47302
  _useState22 = _slicedToArray(_useState21, 2),
47281
- isAddingMcp = _useState22[0],
47282
- setIsAddingMcp = _useState22[1];
47303
+ deleteTarget = _useState22[0],
47304
+ setDeleteTarget = _useState22[1];
47283
47305
  var _useState23 = React.useState(false),
47284
47306
  _useState24 = _slicedToArray(_useState23, 2),
47285
- isEditingMcp = _useState24[0],
47286
- setIsEditingMcp = _useState24[1];
47307
+ isAddingMcp = _useState24[0],
47308
+ setIsAddingMcp = _useState24[1];
47287
47309
  var _useState25 = React.useState(false),
47288
47310
  _useState26 = _slicedToArray(_useState25, 2),
47289
- isAddingWs = _useState26[0],
47290
- setIsAddingWs = _useState26[1];
47311
+ isEditingMcp = _useState26[0],
47312
+ setIsEditingMcp = _useState26[1];
47291
47313
  var _useState27 = React.useState(false),
47292
47314
  _useState28 = _slicedToArray(_useState27, 2),
47293
- isEditingWs = _useState28[0],
47294
- setIsEditingWs = _useState28[1];
47315
+ isAddingWs = _useState28[0],
47316
+ setIsAddingWs = _useState28[1];
47317
+ var _useState29 = React.useState(false),
47318
+ _useState30 = _slicedToArray(_useState29, 2),
47319
+ isEditingWs = _useState30[0],
47320
+ setIsEditingWs = _useState30[1];
47295
47321
 
47296
47322
  // Row ID counter for env/header rows in MCP edit mode
47297
47323
  var nextRowIdRef = React.useRef(0);
@@ -47615,11 +47641,42 @@ var ProvidersSection = function ProvidersSection(_ref) {
47615
47641
  // eslint-disable-next-line react-hooks/exhaustive-deps
47616
47642
  }, [createRequested]);
47617
47643
  var selectedProvider = selectedName && providers[selectedName] ? providers[selectedName] : null;
47618
- var activeProviders = providerTab === "credentials" ? credentialProviders : providerTab === "mcp" ? mcpProviders : wsProviders;
47619
- var activeIcon = providerTab === "credentials" ? "key" : providerTab === "mcp" ? "server" : "plug";
47644
+
47645
+ // Class filter (All + 3 classes). "All" merges every group so the
47646
+ // user gets one alphabetized list by default — mirrors the Widgets
47647
+ // sidebar pattern.
47648
+ var tabFilteredProviders = providerTab === "all" ? [].concat(_toConsumableArray(credentialProviders), _toConsumableArray(mcpProviders), _toConsumableArray(wsProviders)) : providerTab === "credentials" ? credentialProviders : providerTab === "mcp" ? mcpProviders : wsProviders;
47649
+ var trimmedQuery = searchQuery.trim().toLowerCase();
47650
+ var visibleProviders = tabFilteredProviders.filter(function (_ref0) {
47651
+ var _ref1 = _slicedToArray(_ref0, 2),
47652
+ name = _ref1[0],
47653
+ provider = _ref1[1];
47654
+ if (!trimmedQuery) return true;
47655
+ return name.toLowerCase().includes(trimmedQuery) || (provider.type || "").toLowerCase().includes(trimmedQuery);
47656
+ }).slice().sort(function (_ref10, _ref11) {
47657
+ var _ref12 = _slicedToArray(_ref10, 1),
47658
+ a = _ref12[0];
47659
+ var _ref13 = _slicedToArray(_ref11, 1),
47660
+ b = _ref13[0];
47661
+ return a.localeCompare(b, undefined, {
47662
+ sensitivity: "base"
47663
+ });
47664
+ });
47665
+ var iconForClass = function iconForClass(cls) {
47666
+ return cls === "mcp" ? "server" : cls === "websocket" ? "plug" : "key";
47667
+ };
47620
47668
  var listContent = /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
47621
47669
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
47622
- className: "px-2 pt-2",
47670
+ className: "px-2 pt-2 pb-2",
47671
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
47672
+ value: searchQuery,
47673
+ onChange: function onChange(value) {
47674
+ return setSearchQuery(value);
47675
+ },
47676
+ placeholder: "Search providers..."
47677
+ })
47678
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
47679
+ className: "px-2",
47623
47680
  children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Tabs3, {
47624
47681
  value: providerTab,
47625
47682
  onValueChange: setProviderTab,
@@ -47629,6 +47686,10 @@ var ProvidersSection = function ProvidersSection(_ref) {
47629
47686
  className: "w-full flex",
47630
47687
  spacing: "p-0.5",
47631
47688
  children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Tabs3.Trigger, {
47689
+ value: "all",
47690
+ className: "flex-1",
47691
+ children: "All"
47692
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Tabs3.Trigger, {
47632
47693
  value: "credentials",
47633
47694
  className: "flex-1",
47634
47695
  children: "Credentials"
@@ -47643,15 +47704,22 @@ var ProvidersSection = function ProvidersSection(_ref) {
47643
47704
  })]
47644
47705
  })
47645
47706
  })
47707
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
47708
+ className: "px-3 pt-2 pb-1",
47709
+ children: /*#__PURE__*/jsxRuntime.jsxs("span", {
47710
+ className: "text-xs opacity-40",
47711
+ children: [visibleProviders.length, " provider", visibleProviders.length === 1 ? "" : "s"]
47712
+ })
47646
47713
  }), /*#__PURE__*/jsxRuntime.jsxs(DashReact.Sidebar.Content, {
47647
- children: [activeProviders.map(function (_ref0) {
47648
- var _ref1 = _slicedToArray(_ref0, 2),
47649
- name = _ref1[0],
47650
- provider = _ref1[1];
47714
+ children: [visibleProviders.map(function (_ref14) {
47715
+ var _ref15 = _slicedToArray(_ref14, 2),
47716
+ name = _ref15[0],
47717
+ provider = _ref15[1];
47651
47718
  var isSelected = selectedName === name && !isCreating;
47719
+ var cls = provider.providerClass || "credential";
47652
47720
  return /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
47653
47721
  icon: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
47654
- icon: activeIcon,
47722
+ icon: iconForClass(cls),
47655
47723
  className: "h-3.5 w-3.5"
47656
47724
  }),
47657
47725
  active: isSelected,
@@ -47673,40 +47741,9 @@ var ProvidersSection = function ProvidersSection(_ref) {
47673
47741
  className: isSelected ? "bg-white/10 opacity-100" : "",
47674
47742
  children: name
47675
47743
  }, name);
47676
- }), activeProviders.length === 0 && /*#__PURE__*/jsxRuntime.jsx("span", {
47744
+ }), visibleProviders.length === 0 && /*#__PURE__*/jsxRuntime.jsx("span", {
47677
47745
  className: "text-sm opacity-40 py-8 text-center",
47678
- children: providerTab === "credentials" ? "No API credentials configured" : providerTab === "mcp" ? "No MCP servers configured" : "No WebSocket providers configured"
47679
- }), providerTab === "mcp" && /*#__PURE__*/jsxRuntime.jsx("div", {
47680
- className: "px-3 py-3 mt-2 border-t border-white/10",
47681
- children: /*#__PURE__*/jsxRuntime.jsxs("button", {
47682
- onClick: function onClick() {
47683
- setIsAddingMcp(true);
47684
- setSelectedName(null);
47685
- setIsCreating(false);
47686
- setIsEditing(false);
47687
- },
47688
- className: "flex items-center gap-2 text-sm text-blue-400 hover:text-blue-300 transition-colors w-full",
47689
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
47690
- icon: "plus",
47691
- className: "h-3 w-3"
47692
- }), "Add MCP Server"]
47693
- })
47694
- }), providerTab === "websocket" && /*#__PURE__*/jsxRuntime.jsx("div", {
47695
- className: "px-3 py-3 mt-2 border-t border-white/10",
47696
- children: /*#__PURE__*/jsxRuntime.jsxs("button", {
47697
- onClick: function onClick() {
47698
- setIsAddingWs(true);
47699
- setSelectedName(null);
47700
- setIsCreating(false);
47701
- setIsEditing(false);
47702
- setIsAddingMcp(false);
47703
- },
47704
- className: "flex items-center gap-2 text-sm text-blue-400 hover:text-blue-300 transition-colors w-full",
47705
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
47706
- icon: "plus",
47707
- className: "h-3 w-3"
47708
- }), "Add WebSocket Provider"]
47709
- })
47746
+ children: trimmedQuery ? "No providers match \"".concat(searchQuery.trim(), "\"") : providerTab === "all" ? "No providers configured" : providerTab === "credentials" ? "No API credentials configured" : providerTab === "mcp" ? "No MCP servers configured" : "No WebSocket providers configured"
47710
47747
  })]
47711
47748
  })]
47712
47749
  });
@@ -47733,10 +47770,10 @@ var ProvidersSection = function ProvidersSection(_ref) {
47733
47770
  });
47734
47771
  } else if (isEditingWs && selectedName && selectedProvider) {
47735
47772
  var wc = selectedProvider.wsConfig || {};
47736
- var editHeaderRows = wc.headers ? Object.entries(wc.headers).map(function (_ref10, i) {
47737
- var _ref11 = _slicedToArray(_ref10, 2),
47738
- key = _ref11[0],
47739
- value = _ref11[1];
47773
+ var editHeaderRows = wc.headers ? Object.entries(wc.headers).map(function (_ref16, i) {
47774
+ var _ref17 = _slicedToArray(_ref16, 2),
47775
+ key = _ref17[0],
47776
+ value = _ref17[1];
47740
47777
  return {
47741
47778
  id: "ws_edit_".concat(i),
47742
47779
  key: key,