@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.esm.js CHANGED
@@ -22108,13 +22108,26 @@ var LayoutBuilder = function LayoutBuilder(_ref) {
22108
22108
  // Listen for AI widget builder placement — modifies layout state directly
22109
22109
  useEffect(function () {
22110
22110
  var handler = function handler(e) {
22111
+ var _wsRef$current;
22111
22112
  var _ref4 = e.detail || {},
22112
22113
  widgetComponentName = _ref4.widgetComponentName,
22113
22114
  cellNumber = _ref4.cellNumber,
22114
- gridItemId = _ref4.gridItemId;
22115
+ gridItemId = _ref4.gridItemId,
22116
+ workspaceId = _ref4.workspaceId;
22115
22117
  if (!widgetComponentName || !cellNumber || !gridItemId) return;
22116
22118
  var ws = wsRef.current;
22117
22119
  if (!(ws !== null && ws !== void 0 && ws.layout)) return;
22120
+
22121
+ // Workspace-id guard: multiple LayoutBuilders are mounted (one per
22122
+ // open dashboard tab) and all listen to this global event. If the
22123
+ // event carries a workspaceId, only the matching workspace acts —
22124
+ // otherwise gridItemId collisions across workspaces (small ints)
22125
+ // would let the wrong dashboard handle the placement and silently
22126
+ // overwrite a cell. Older dash-electron versions that don't yet
22127
+ // pass workspaceId fall through (opt-in guard, backward-compatible).
22128
+ if (workspaceId && ((_wsRef$current = wsRef.current) === null || _wsRef$current === void 0 ? void 0 : _wsRef$current.id) !== workspaceId) {
22129
+ return;
22130
+ }
22118
22131
  var gridItem = ws.layout.find(function (item) {
22119
22132
  return item.id === gridItemId;
22120
22133
  });
@@ -22158,12 +22171,21 @@ var LayoutBuilder = function LayoutBuilder(_ref) {
22158
22171
  // Listen for AI widget remix — swaps existing widget component in-place
22159
22172
  useEffect(function () {
22160
22173
  var handler = function handler(e) {
22174
+ var _wsRef$current3;
22161
22175
  var _ref5 = e.detail || {},
22162
22176
  widgetComponentName = _ref5.widgetComponentName,
22163
- widgetId = _ref5.widgetId;
22177
+ widgetId = _ref5.widgetId,
22178
+ workspaceId = _ref5.workspaceId;
22164
22179
  if (!widgetComponentName || !widgetId) return;
22165
22180
  var ws = wsRef.current;
22166
22181
  if (!(ws !== null && ws !== void 0 && ws.layout)) return;
22182
+
22183
+ // Same workspace-id guard as the place-widget handler — keeps
22184
+ // the swap from acting on a different open dashboard's widget
22185
+ // when widgetIds collide across workspaces.
22186
+ if (workspaceId && ((_wsRef$current3 = wsRef.current) === null || _wsRef$current3 === void 0 ? void 0 : _wsRef$current3.id) !== workspaceId) {
22187
+ return;
22188
+ }
22167
22189
  var config = ComponentManager.config(widgetComponentName);
22168
22190
  if (!config) {
22169
22191
  return;
@@ -47209,71 +47231,75 @@ var ProvidersSection = function ProvidersSection(_ref) {
47209
47231
  if (result !== null && result !== void 0 && result.catalog) setCatalog(result.catalog);
47210
47232
  }, function () {});
47211
47233
  }, [dashApi]);
47212
- var _useState3 = useState("credentials"),
47234
+ var _useState3 = useState("all"),
47213
47235
  _useState4 = _slicedToArray(_useState3, 2),
47214
47236
  providerTab = _useState4[0],
47215
47237
  setProviderTab = _useState4[1];
47216
- var _useState5 = useState(null),
47238
+ var _useState5 = useState(""),
47217
47239
  _useState6 = _slicedToArray(_useState5, 2),
47218
- selectedName = _useState6[0],
47219
- setSelectedName = _useState6[1];
47220
- var _useState7 = useState(false),
47240
+ searchQuery = _useState6[0],
47241
+ setSearchQuery = _useState6[1];
47242
+ var _useState7 = useState(null),
47221
47243
  _useState8 = _slicedToArray(_useState7, 2),
47222
- isCreating = _useState8[0],
47223
- setIsCreating = _useState8[1];
47244
+ selectedName = _useState8[0],
47245
+ setSelectedName = _useState8[1];
47246
+ var _useState9 = useState(false),
47247
+ _useState0 = _slicedToArray(_useState9, 2),
47248
+ isCreating = _useState0[0],
47249
+ setIsCreating = _useState0[1];
47224
47250
  // When the user clicks "+ New Provider" without a pre-selected
47225
47251
  // class (Settings header button), show the class chooser
47226
47252
  // (Credential / MCP / WebSocket) instead of defaulting to the
47227
47253
  // credential form. Widget Builder's deep-link path passes a class
47228
47254
  // explicitly and bypasses this chooser.
47229
- var _useState9 = useState(false),
47230
- _useState0 = _slicedToArray(_useState9, 2),
47231
- isShowingClassChooser = _useState0[0],
47232
- setIsShowingClassChooser = _useState0[1];
47255
+ var _useState1 = useState(false),
47256
+ _useState10 = _slicedToArray(_useState1, 2),
47257
+ isShowingClassChooser = _useState10[0],
47258
+ setIsShowingClassChooser = _useState10[1];
47233
47259
  // Tracks whether the current create-flow detail was reached via the
47234
47260
  // chooser (vs. the Widget Builder deep-link or list-edit). Only the
47235
47261
  // chooser-entry path renders the "← Back" affordance, since that's
47236
47262
  // the only path that has somewhere to go back to.
47237
- var _useState1 = useState(false),
47238
- _useState10 = _slicedToArray(_useState1, 2),
47239
- cameFromClassChooser = _useState10[0],
47240
- setCameFromClassChooser = _useState10[1];
47241
47263
  var _useState11 = useState(false),
47242
47264
  _useState12 = _slicedToArray(_useState11, 2),
47243
- isEditing = _useState12[0],
47244
- setIsEditing = _useState12[1];
47245
- var _useState13 = useState(""),
47265
+ cameFromClassChooser = _useState12[0],
47266
+ setCameFromClassChooser = _useState12[1];
47267
+ var _useState13 = useState(false),
47246
47268
  _useState14 = _slicedToArray(_useState13, 2),
47247
- formName = _useState14[0],
47248
- setFormName = _useState14[1];
47269
+ isEditing = _useState14[0],
47270
+ setIsEditing = _useState14[1];
47249
47271
  var _useState15 = useState(""),
47250
47272
  _useState16 = _slicedToArray(_useState15, 2),
47251
- formType = _useState16[0],
47252
- setFormType = _useState16[1];
47253
- var _useState17 = useState({}),
47273
+ formName = _useState16[0],
47274
+ setFormName = _useState16[1];
47275
+ var _useState17 = useState(""),
47254
47276
  _useState18 = _slicedToArray(_useState17, 2),
47255
- formCredentials = _useState18[0],
47256
- setFormCredentials = _useState18[1];
47257
- var _useState19 = useState(null),
47277
+ formType = _useState18[0],
47278
+ setFormType = _useState18[1];
47279
+ var _useState19 = useState({}),
47258
47280
  _useState20 = _slicedToArray(_useState19, 2),
47259
- deleteTarget = _useState20[0],
47260
- setDeleteTarget = _useState20[1];
47261
- var _useState21 = useState(false),
47281
+ formCredentials = _useState20[0],
47282
+ setFormCredentials = _useState20[1];
47283
+ var _useState21 = useState(null),
47262
47284
  _useState22 = _slicedToArray(_useState21, 2),
47263
- isAddingMcp = _useState22[0],
47264
- setIsAddingMcp = _useState22[1];
47285
+ deleteTarget = _useState22[0],
47286
+ setDeleteTarget = _useState22[1];
47265
47287
  var _useState23 = useState(false),
47266
47288
  _useState24 = _slicedToArray(_useState23, 2),
47267
- isEditingMcp = _useState24[0],
47268
- setIsEditingMcp = _useState24[1];
47289
+ isAddingMcp = _useState24[0],
47290
+ setIsAddingMcp = _useState24[1];
47269
47291
  var _useState25 = useState(false),
47270
47292
  _useState26 = _slicedToArray(_useState25, 2),
47271
- isAddingWs = _useState26[0],
47272
- setIsAddingWs = _useState26[1];
47293
+ isEditingMcp = _useState26[0],
47294
+ setIsEditingMcp = _useState26[1];
47273
47295
  var _useState27 = useState(false),
47274
47296
  _useState28 = _slicedToArray(_useState27, 2),
47275
- isEditingWs = _useState28[0],
47276
- setIsEditingWs = _useState28[1];
47297
+ isAddingWs = _useState28[0],
47298
+ setIsAddingWs = _useState28[1];
47299
+ var _useState29 = useState(false),
47300
+ _useState30 = _slicedToArray(_useState29, 2),
47301
+ isEditingWs = _useState30[0],
47302
+ setIsEditingWs = _useState30[1];
47277
47303
 
47278
47304
  // Row ID counter for env/header rows in MCP edit mode
47279
47305
  var nextRowIdRef = useRef(0);
@@ -47597,11 +47623,42 @@ var ProvidersSection = function ProvidersSection(_ref) {
47597
47623
  // eslint-disable-next-line react-hooks/exhaustive-deps
47598
47624
  }, [createRequested]);
47599
47625
  var selectedProvider = selectedName && providers[selectedName] ? providers[selectedName] : null;
47600
- var activeProviders = providerTab === "credentials" ? credentialProviders : providerTab === "mcp" ? mcpProviders : wsProviders;
47601
- var activeIcon = providerTab === "credentials" ? "key" : providerTab === "mcp" ? "server" : "plug";
47626
+
47627
+ // Class filter (All + 3 classes). "All" merges every group so the
47628
+ // user gets one alphabetized list by default — mirrors the Widgets
47629
+ // sidebar pattern.
47630
+ var tabFilteredProviders = providerTab === "all" ? [].concat(_toConsumableArray(credentialProviders), _toConsumableArray(mcpProviders), _toConsumableArray(wsProviders)) : providerTab === "credentials" ? credentialProviders : providerTab === "mcp" ? mcpProviders : wsProviders;
47631
+ var trimmedQuery = searchQuery.trim().toLowerCase();
47632
+ var visibleProviders = tabFilteredProviders.filter(function (_ref0) {
47633
+ var _ref1 = _slicedToArray(_ref0, 2),
47634
+ name = _ref1[0],
47635
+ provider = _ref1[1];
47636
+ if (!trimmedQuery) return true;
47637
+ return name.toLowerCase().includes(trimmedQuery) || (provider.type || "").toLowerCase().includes(trimmedQuery);
47638
+ }).slice().sort(function (_ref10, _ref11) {
47639
+ var _ref12 = _slicedToArray(_ref10, 1),
47640
+ a = _ref12[0];
47641
+ var _ref13 = _slicedToArray(_ref11, 1),
47642
+ b = _ref13[0];
47643
+ return a.localeCompare(b, undefined, {
47644
+ sensitivity: "base"
47645
+ });
47646
+ });
47647
+ var iconForClass = function iconForClass(cls) {
47648
+ return cls === "mcp" ? "server" : cls === "websocket" ? "plug" : "key";
47649
+ };
47602
47650
  var listContent = /*#__PURE__*/jsxs(Fragment, {
47603
47651
  children: [/*#__PURE__*/jsx("div", {
47604
- className: "px-2 pt-2",
47652
+ className: "px-2 pt-2 pb-2",
47653
+ children: /*#__PURE__*/jsx(InputText, {
47654
+ value: searchQuery,
47655
+ onChange: function onChange(value) {
47656
+ return setSearchQuery(value);
47657
+ },
47658
+ placeholder: "Search providers..."
47659
+ })
47660
+ }), /*#__PURE__*/jsx("div", {
47661
+ className: "px-2",
47605
47662
  children: /*#__PURE__*/jsx(Tabs3, {
47606
47663
  value: providerTab,
47607
47664
  onValueChange: setProviderTab,
@@ -47611,6 +47668,10 @@ var ProvidersSection = function ProvidersSection(_ref) {
47611
47668
  className: "w-full flex",
47612
47669
  spacing: "p-0.5",
47613
47670
  children: [/*#__PURE__*/jsx(Tabs3.Trigger, {
47671
+ value: "all",
47672
+ className: "flex-1",
47673
+ children: "All"
47674
+ }), /*#__PURE__*/jsx(Tabs3.Trigger, {
47614
47675
  value: "credentials",
47615
47676
  className: "flex-1",
47616
47677
  children: "Credentials"
@@ -47625,15 +47686,22 @@ var ProvidersSection = function ProvidersSection(_ref) {
47625
47686
  })]
47626
47687
  })
47627
47688
  })
47689
+ }), /*#__PURE__*/jsx("div", {
47690
+ className: "px-3 pt-2 pb-1",
47691
+ children: /*#__PURE__*/jsxs("span", {
47692
+ className: "text-xs opacity-40",
47693
+ children: [visibleProviders.length, " provider", visibleProviders.length === 1 ? "" : "s"]
47694
+ })
47628
47695
  }), /*#__PURE__*/jsxs(Sidebar.Content, {
47629
- children: [activeProviders.map(function (_ref0) {
47630
- var _ref1 = _slicedToArray(_ref0, 2),
47631
- name = _ref1[0],
47632
- provider = _ref1[1];
47696
+ children: [visibleProviders.map(function (_ref14) {
47697
+ var _ref15 = _slicedToArray(_ref14, 2),
47698
+ name = _ref15[0],
47699
+ provider = _ref15[1];
47633
47700
  var isSelected = selectedName === name && !isCreating;
47701
+ var cls = provider.providerClass || "credential";
47634
47702
  return /*#__PURE__*/jsx(Sidebar.Item, {
47635
47703
  icon: /*#__PURE__*/jsx(FontAwesomeIcon, {
47636
- icon: activeIcon,
47704
+ icon: iconForClass(cls),
47637
47705
  className: "h-3.5 w-3.5"
47638
47706
  }),
47639
47707
  active: isSelected,
@@ -47655,40 +47723,9 @@ var ProvidersSection = function ProvidersSection(_ref) {
47655
47723
  className: isSelected ? "bg-white/10 opacity-100" : "",
47656
47724
  children: name
47657
47725
  }, name);
47658
- }), activeProviders.length === 0 && /*#__PURE__*/jsx("span", {
47726
+ }), visibleProviders.length === 0 && /*#__PURE__*/jsx("span", {
47659
47727
  className: "text-sm opacity-40 py-8 text-center",
47660
- children: providerTab === "credentials" ? "No API credentials configured" : providerTab === "mcp" ? "No MCP servers configured" : "No WebSocket providers configured"
47661
- }), providerTab === "mcp" && /*#__PURE__*/jsx("div", {
47662
- className: "px-3 py-3 mt-2 border-t border-white/10",
47663
- children: /*#__PURE__*/jsxs("button", {
47664
- onClick: function onClick() {
47665
- setIsAddingMcp(true);
47666
- setSelectedName(null);
47667
- setIsCreating(false);
47668
- setIsEditing(false);
47669
- },
47670
- className: "flex items-center gap-2 text-sm text-blue-400 hover:text-blue-300 transition-colors w-full",
47671
- children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
47672
- icon: "plus",
47673
- className: "h-3 w-3"
47674
- }), "Add MCP Server"]
47675
- })
47676
- }), providerTab === "websocket" && /*#__PURE__*/jsx("div", {
47677
- className: "px-3 py-3 mt-2 border-t border-white/10",
47678
- children: /*#__PURE__*/jsxs("button", {
47679
- onClick: function onClick() {
47680
- setIsAddingWs(true);
47681
- setSelectedName(null);
47682
- setIsCreating(false);
47683
- setIsEditing(false);
47684
- setIsAddingMcp(false);
47685
- },
47686
- className: "flex items-center gap-2 text-sm text-blue-400 hover:text-blue-300 transition-colors w-full",
47687
- children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
47688
- icon: "plus",
47689
- className: "h-3 w-3"
47690
- }), "Add WebSocket Provider"]
47691
- })
47728
+ 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"
47692
47729
  })]
47693
47730
  })]
47694
47731
  });
@@ -47715,10 +47752,10 @@ var ProvidersSection = function ProvidersSection(_ref) {
47715
47752
  });
47716
47753
  } else if (isEditingWs && selectedName && selectedProvider) {
47717
47754
  var wc = selectedProvider.wsConfig || {};
47718
- var editHeaderRows = wc.headers ? Object.entries(wc.headers).map(function (_ref10, i) {
47719
- var _ref11 = _slicedToArray(_ref10, 2),
47720
- key = _ref11[0],
47721
- value = _ref11[1];
47755
+ var editHeaderRows = wc.headers ? Object.entries(wc.headers).map(function (_ref16, i) {
47756
+ var _ref17 = _slicedToArray(_ref16, 2),
47757
+ key = _ref17[0],
47758
+ value = _ref17[1];
47722
47759
  return {
47723
47760
  id: "ws_edit_".concat(i),
47724
47761
  key: key,