@trops/dash-core 0.1.453 → 0.1.455

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
@@ -3729,7 +3729,7 @@ var FolderDetail = function FolderDetail(_ref) {
3729
3729
  });
3730
3730
  };
3731
3731
 
3732
- var OptionCard$1 = function OptionCard(_ref) {
3732
+ var OptionCard$2 = function OptionCard(_ref) {
3733
3733
  var icon = _ref.icon,
3734
3734
  title = _ref.title,
3735
3735
  description = _ref.description,
@@ -3778,28 +3778,28 @@ var CreationMethodPicker = function CreationMethodPicker(_ref2) {
3778
3778
  })]
3779
3779
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
3780
3780
  className: "flex flex-col w-2/3 p-6 pt-10 space-y-3",
3781
- children: [/*#__PURE__*/jsxRuntime.jsx(OptionCard$1, {
3781
+ children: [/*#__PURE__*/jsxRuntime.jsx(OptionCard$2, {
3782
3782
  icon: "plus",
3783
3783
  title: "New Dashboard",
3784
3784
  description: "Start from a blank template and customize your layout",
3785
3785
  onClick: function onClick() {
3786
3786
  return onSelect("template");
3787
3787
  }
3788
- }), /*#__PURE__*/jsxRuntime.jsx(OptionCard$1, {
3788
+ }), /*#__PURE__*/jsxRuntime.jsx(OptionCard$2, {
3789
3789
  icon: "file-zipper",
3790
3790
  title: "Import from File",
3791
3791
  description: "Import a dashboard from a .zip file on your computer",
3792
3792
  onClick: function onClick() {
3793
3793
  return onSelect("import");
3794
3794
  }
3795
- }), /*#__PURE__*/jsxRuntime.jsx(OptionCard$1, {
3795
+ }), /*#__PURE__*/jsxRuntime.jsx(OptionCard$2, {
3796
3796
  icon: "compass",
3797
3797
  title: "Search Registry",
3798
3798
  description: "Browse and install dashboards from the online registry",
3799
3799
  onClick: function onClick() {
3800
3800
  return onSelect("registry");
3801
3801
  }
3802
- }), /*#__PURE__*/jsxRuntime.jsx(OptionCard$1, {
3802
+ }), /*#__PURE__*/jsxRuntime.jsx(OptionCard$2, {
3803
3803
  icon: "wand-magic-sparkles",
3804
3804
  title: "Dashboard Wizard",
3805
3805
  description: "Guided setup \u2014 pick categories, providers, and widgets step by step",
@@ -43931,7 +43931,9 @@ var ProviderDetail = function ProviderDetail(_ref) {
43931
43931
  _ref$catalogAuthComma = _ref.catalogAuthCommand,
43932
43932
  catalogAuthCommand = _ref$catalogAuthComma === void 0 ? null : _ref$catalogAuthComma,
43933
43933
  _ref$catalogCredentia = _ref.catalogCredentialSchema,
43934
- catalogCredentialSchema = _ref$catalogCredentia === void 0 ? {} : _ref$catalogCredentia;
43934
+ catalogCredentialSchema = _ref$catalogCredentia === void 0 ? {} : _ref$catalogCredentia,
43935
+ _ref$onBack = _ref.onBack,
43936
+ onBack = _ref$onBack === void 0 ? null : _ref$onBack;
43935
43937
  var appContext = React.useContext(AppContext);
43936
43938
  var dashApi = appContext === null || appContext === void 0 ? void 0 : appContext.dashApi;
43937
43939
  var isMcp = (provider === null || provider === void 0 ? void 0 : provider.providerClass) === "mcp";
@@ -44260,7 +44262,15 @@ var ProviderDetail = function ProviderDetail(_ref) {
44260
44262
  className: "flex flex-col flex-1 min-h-0",
44261
44263
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
44262
44264
  className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-5",
44263
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
44265
+ children: [onBack && /*#__PURE__*/jsxRuntime.jsxs("button", {
44266
+ type: "button",
44267
+ onClick: onBack,
44268
+ className: "flex items-center gap-2 text-sm opacity-60 hover:opacity-100 transition-opacity",
44269
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
44270
+ icon: "chevron-left",
44271
+ className: "h-3 w-3"
44272
+ }), "Back"]
44273
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
44264
44274
  title: isCreating ? "New Provider" : "Edit Provider",
44265
44275
  padding: false
44266
44276
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
@@ -45854,7 +45864,9 @@ var McpCatalogDetail = function McpCatalogDetail(_ref) {
45854
45864
  var onSave = _ref.onSave,
45855
45865
  onCancel = _ref.onCancel,
45856
45866
  _ref$initialSelectedI = _ref.initialSelectedId,
45857
- initialSelectedId = _ref$initialSelectedI === void 0 ? null : _ref$initialSelectedI;
45867
+ initialSelectedId = _ref$initialSelectedI === void 0 ? null : _ref$initialSelectedI,
45868
+ _ref$onBack = _ref.onBack,
45869
+ onBack = _ref$onBack === void 0 ? null : _ref$onBack;
45858
45870
  var appContext = React.useContext(AppContext);
45859
45871
  var dashApi = appContext === null || appContext === void 0 ? void 0 : appContext.dashApi;
45860
45872
  var _useState = React.useState([]),
@@ -46505,7 +46517,15 @@ var McpCatalogDetail = function McpCatalogDetail(_ref) {
46505
46517
  className: "flex flex-col flex-1 min-h-0",
46506
46518
  children: /*#__PURE__*/jsxRuntime.jsxs("div", {
46507
46519
  className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-4",
46508
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
46520
+ children: [onBack && /*#__PURE__*/jsxRuntime.jsxs("button", {
46521
+ type: "button",
46522
+ onClick: onBack,
46523
+ className: "flex items-center gap-2 text-sm opacity-60 hover:opacity-100 transition-opacity",
46524
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
46525
+ icon: "chevron-left",
46526
+ className: "h-3 w-3"
46527
+ }), "Back"]
46528
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
46509
46529
  className: "flex items-center justify-between",
46510
46530
  children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
46511
46531
  title: "Add MCP Server",
@@ -46682,7 +46702,9 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
46682
46702
  _ref$initialCredentia = _ref.initialCredentials,
46683
46703
  initialCredentials = _ref$initialCredentia === void 0 ? {} : _ref$initialCredentia,
46684
46704
  onSave = _ref.onSave,
46685
- onCancel = _ref.onCancel;
46705
+ onCancel = _ref.onCancel,
46706
+ _ref$onBack = _ref.onBack,
46707
+ onBack = _ref$onBack === void 0 ? null : _ref$onBack;
46686
46708
  var _useState = React.useState(initialName),
46687
46709
  _useState2 = _slicedToArray(_useState, 2),
46688
46710
  name = _useState2[0],
@@ -46896,7 +46918,15 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
46896
46918
  className: "flex flex-col flex-1 min-h-0",
46897
46919
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
46898
46920
  className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-5",
46899
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
46921
+ children: [onBack && /*#__PURE__*/jsxRuntime.jsxs("button", {
46922
+ type: "button",
46923
+ onClick: onBack,
46924
+ className: "flex items-center gap-2 text-sm opacity-60 hover:opacity-100 transition-opacity",
46925
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
46926
+ icon: "chevron-left",
46927
+ className: "h-3 w-3"
46928
+ }), "Back"]
46929
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
46900
46930
  title: isEditMode ? "Edit WebSocket Provider" : "New WebSocket Provider",
46901
46931
  padding: false
46902
46932
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
@@ -47072,6 +47102,103 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
47072
47102
  });
47073
47103
  };
47074
47104
 
47105
+ var OptionCard$1 = function OptionCard(_ref) {
47106
+ var icon = _ref.icon,
47107
+ title = _ref.title,
47108
+ description = _ref.description,
47109
+ onClick = _ref.onClick,
47110
+ currentTheme = _ref.currentTheme;
47111
+ return /*#__PURE__*/jsxRuntime.jsxs("button", {
47112
+ type: "button",
47113
+ onClick: onClick,
47114
+ className: "w-full flex flex-row items-center gap-4 p-4 rounded-lg text-left transition-opacity ".concat(currentTheme["bg-primary-medium"] || "bg-white/5", " hover:opacity-80"),
47115
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
47116
+ className: "flex-shrink-0 h-8 w-8 flex items-center justify-center opacity-60",
47117
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
47118
+ icon: icon,
47119
+ className: "h-5 w-5"
47120
+ })
47121
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
47122
+ className: "flex flex-col min-w-0",
47123
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
47124
+ className: "text-sm font-medium",
47125
+ children: title
47126
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
47127
+ className: "text-xs opacity-50 mt-0.5",
47128
+ children: description
47129
+ })]
47130
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
47131
+ className: "flex-shrink-0 ml-auto opacity-30",
47132
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
47133
+ icon: "chevron-right",
47134
+ className: "h-3 w-3"
47135
+ })
47136
+ })]
47137
+ });
47138
+ };
47139
+
47140
+ /**
47141
+ * NewProviderPicker — the 3-option chooser shown when the user clicks
47142
+ * "+ New Provider" from the Settings → Providers header without a
47143
+ * specific class pre-selected. Mirrors InstallWidgetPicker's pattern
47144
+ * so the UI feels consistent across "+ New ..." entry points in
47145
+ * Settings.
47146
+ *
47147
+ * Calls `onSelect(class)` with the literal class string ("credential",
47148
+ * "mcp", or "websocket"). The parent (ProvidersSection) then routes
47149
+ * to the appropriate create flow:
47150
+ *
47151
+ * credential → ProviderDetail (credential create form)
47152
+ * mcp → McpCatalogDetail (catalog browser)
47153
+ * websocket → WsProviderDetail (WebSocket add form)
47154
+ *
47155
+ * The Widget Builder's existing deep-link path (which always passes
47156
+ * an explicit class) bypasses this chooser and goes straight to the
47157
+ * matching form.
47158
+ */
47159
+ var NewProviderPicker = function NewProviderPicker(_ref2) {
47160
+ var onSelect = _ref2.onSelect;
47161
+ var _useContext = React.useContext(DashReact.ThemeContext),
47162
+ currentTheme = _useContext.currentTheme;
47163
+ var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
47164
+ grow: false
47165
+ });
47166
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
47167
+ className: "flex flex-col flex-1 min-h-0",
47168
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
47169
+ className: "flex-1 overflow-y-auto p-6 space-y-3 ".concat(panelStyles.textColor || "text-gray-200"),
47170
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
47171
+ className: "text-xs font-semibold opacity-50 block mb-4",
47172
+ children: "ADD A NEW PROVIDER"
47173
+ }), /*#__PURE__*/jsxRuntime.jsx(OptionCard$1, {
47174
+ icon: "key",
47175
+ title: "Credential",
47176
+ description: "API key or token credentials for services like Algolia, Anthropic, or any HTTP API",
47177
+ onClick: function onClick() {
47178
+ return onSelect("credential");
47179
+ },
47180
+ currentTheme: currentTheme
47181
+ }), /*#__PURE__*/jsxRuntime.jsx(OptionCard$1, {
47182
+ icon: "plug",
47183
+ title: "MCP",
47184
+ description: "Model Context Protocol server \u2014 pick from a curated catalog (Slack, Filesystem, Notion, etc.)",
47185
+ onClick: function onClick() {
47186
+ return onSelect("mcp");
47187
+ },
47188
+ currentTheme: currentTheme
47189
+ }), /*#__PURE__*/jsxRuntime.jsx(OptionCard$1, {
47190
+ icon: "diagram-project",
47191
+ title: "WebSocket",
47192
+ description: "Real-time WebSocket connection to a streaming endpoint",
47193
+ onClick: function onClick() {
47194
+ return onSelect("websocket");
47195
+ },
47196
+ currentTheme: currentTheme
47197
+ })]
47198
+ })
47199
+ });
47200
+ };
47201
+
47075
47202
  var ProvidersSection = function ProvidersSection(_ref) {
47076
47203
  var _ref$dashApi = _ref.dashApi,
47077
47204
  dashApi = _ref$dashApi === void 0 ? null : _ref$dashApi,
@@ -47112,42 +47239,59 @@ var ProvidersSection = function ProvidersSection(_ref) {
47112
47239
  _useState8 = _slicedToArray(_useState7, 2),
47113
47240
  isCreating = _useState8[0],
47114
47241
  setIsCreating = _useState8[1];
47242
+ // When the user clicks "+ New Provider" without a pre-selected
47243
+ // class (Settings header button), show the class chooser
47244
+ // (Credential / MCP / WebSocket) instead of defaulting to the
47245
+ // credential form. Widget Builder's deep-link path passes a class
47246
+ // explicitly and bypasses this chooser.
47115
47247
  var _useState9 = React.useState(false),
47116
47248
  _useState0 = _slicedToArray(_useState9, 2),
47117
- isEditing = _useState0[0],
47118
- setIsEditing = _useState0[1];
47119
- var _useState1 = React.useState(""),
47249
+ isShowingClassChooser = _useState0[0],
47250
+ setIsShowingClassChooser = _useState0[1];
47251
+ // Tracks whether the current create-flow detail was reached via the
47252
+ // chooser (vs. the Widget Builder deep-link or list-edit). Only the
47253
+ // chooser-entry path renders the "← Back" affordance, since that's
47254
+ // the only path that has somewhere to go back to.
47255
+ var _useState1 = React.useState(false),
47120
47256
  _useState10 = _slicedToArray(_useState1, 2),
47121
- formName = _useState10[0],
47122
- setFormName = _useState10[1];
47123
- var _useState11 = React.useState(""),
47257
+ cameFromClassChooser = _useState10[0],
47258
+ setCameFromClassChooser = _useState10[1];
47259
+ var _useState11 = React.useState(false),
47124
47260
  _useState12 = _slicedToArray(_useState11, 2),
47125
- formType = _useState12[0],
47126
- setFormType = _useState12[1];
47127
- var _useState13 = React.useState({}),
47261
+ isEditing = _useState12[0],
47262
+ setIsEditing = _useState12[1];
47263
+ var _useState13 = React.useState(""),
47128
47264
  _useState14 = _slicedToArray(_useState13, 2),
47129
- formCredentials = _useState14[0],
47130
- setFormCredentials = _useState14[1];
47131
- var _useState15 = React.useState(null),
47265
+ formName = _useState14[0],
47266
+ setFormName = _useState14[1];
47267
+ var _useState15 = React.useState(""),
47132
47268
  _useState16 = _slicedToArray(_useState15, 2),
47133
- deleteTarget = _useState16[0],
47134
- setDeleteTarget = _useState16[1];
47135
- var _useState17 = React.useState(false),
47269
+ formType = _useState16[0],
47270
+ setFormType = _useState16[1];
47271
+ var _useState17 = React.useState({}),
47136
47272
  _useState18 = _slicedToArray(_useState17, 2),
47137
- isAddingMcp = _useState18[0],
47138
- setIsAddingMcp = _useState18[1];
47139
- var _useState19 = React.useState(false),
47273
+ formCredentials = _useState18[0],
47274
+ setFormCredentials = _useState18[1];
47275
+ var _useState19 = React.useState(null),
47140
47276
  _useState20 = _slicedToArray(_useState19, 2),
47141
- isEditingMcp = _useState20[0],
47142
- setIsEditingMcp = _useState20[1];
47277
+ deleteTarget = _useState20[0],
47278
+ setDeleteTarget = _useState20[1];
47143
47279
  var _useState21 = React.useState(false),
47144
47280
  _useState22 = _slicedToArray(_useState21, 2),
47145
- isAddingWs = _useState22[0],
47146
- setIsAddingWs = _useState22[1];
47281
+ isAddingMcp = _useState22[0],
47282
+ setIsAddingMcp = _useState22[1];
47147
47283
  var _useState23 = React.useState(false),
47148
47284
  _useState24 = _slicedToArray(_useState23, 2),
47149
- isEditingWs = _useState24[0],
47150
- setIsEditingWs = _useState24[1];
47285
+ isEditingMcp = _useState24[0],
47286
+ setIsEditingMcp = _useState24[1];
47287
+ var _useState25 = React.useState(false),
47288
+ _useState26 = _slicedToArray(_useState25, 2),
47289
+ isAddingWs = _useState26[0],
47290
+ setIsAddingWs = _useState26[1];
47291
+ var _useState27 = React.useState(false),
47292
+ _useState28 = _slicedToArray(_useState27, 2),
47293
+ isEditingWs = _useState28[0],
47294
+ setIsEditingWs = _useState28[1];
47151
47295
 
47152
47296
  // Row ID counter for env/header rows in MCP edit mode
47153
47297
  var nextRowIdRef = React.useRef(0);
@@ -47429,19 +47573,39 @@ var ProvidersSection = function ProvidersSection(_ref) {
47429
47573
  if (createRequested && !prevCreateRequested.current) {
47430
47574
  resetForm();
47431
47575
  setSelectedName(null);
47576
+ setIsShowingClassChooser(false);
47577
+ // External create requests (deep-link or header button) do NOT
47578
+ // come via the chooser, so any leftover "came from chooser" state
47579
+ // from a prior session must be cleared before routing.
47580
+ setCameFromClassChooser(false);
47432
47581
  if (initialProviderClass === "mcp") {
47433
47582
  // MCP class: open the catalog detail. Pre-select happens in
47434
47583
  // McpCatalogDetail via the initialSelectedId prop passed below.
47435
47584
  setIsCreating(false);
47436
47585
  setIsAddingMcp(true);
47437
- } else {
47438
- // Credential class (default): open the credential create form
47439
- // and pre-fill the type field if provided.
47586
+ } else if (initialProviderClass === "websocket") {
47587
+ // WebSocket class: open the WebSocket add form. Reachable via
47588
+ // a future Widget Builder deep-link for ws-typed widgets.
47589
+ setIsCreating(false);
47590
+ setIsAddingMcp(false);
47591
+ setIsAddingWs(true);
47592
+ } else if (initialProviderClass === "credential") {
47593
+ // Credential class: open the credential create form and
47594
+ // pre-fill the type field if provided.
47440
47595
  setIsAddingMcp(false);
47441
47596
  setIsCreating(true);
47442
47597
  if (initialProviderType) {
47443
47598
  setFormType(initialProviderType);
47444
47599
  }
47600
+ } else {
47601
+ // No class specified — Settings header "+ New Provider"
47602
+ // button hits this branch. Show the chooser so the user
47603
+ // picks Credential / MCP / WebSocket explicitly instead of
47604
+ // landing on the credential form by default.
47605
+ setIsAddingMcp(false);
47606
+ setIsCreating(false);
47607
+ setIsAddingWs(false);
47608
+ setIsShowingClassChooser(true);
47445
47609
  }
47446
47610
  }
47447
47611
  prevCreateRequested.current = createRequested;
@@ -47541,13 +47705,26 @@ var ProvidersSection = function ProvidersSection(_ref) {
47541
47705
  })]
47542
47706
  })]
47543
47707
  });
47708
+
47709
+ // Closes whichever create-flow detail is open and re-opens the
47710
+ // class chooser. Only attached to the detail's onBack prop when
47711
+ // the user reached it via the chooser (cameFromClassChooser).
47712
+ var goBackToClassChooser = function goBackToClassChooser() {
47713
+ resetForm();
47714
+ setIsAddingWs(false);
47715
+ setIsAddingMcp(false);
47716
+ setIsCreating(false);
47717
+ setCameFromClassChooser(false);
47718
+ setIsShowingClassChooser(true);
47719
+ };
47544
47720
  var detailContent = null;
47545
47721
  if (isAddingWs) {
47546
47722
  detailContent = /*#__PURE__*/jsxRuntime.jsx(WebSocketProviderForm, {
47547
47723
  onSave: handleWsSave,
47548
47724
  onCancel: function onCancel() {
47549
47725
  return setIsAddingWs(false);
47550
- }
47726
+ },
47727
+ onBack: cameFromClassChooser ? goBackToClassChooser : null
47551
47728
  });
47552
47729
  } else if (isEditingWs && selectedName && selectedProvider) {
47553
47730
  var wc = selectedProvider.wsConfig || {};
@@ -47573,13 +47750,28 @@ var ProvidersSection = function ProvidersSection(_ref) {
47573
47750
  return setIsEditingWs(false);
47574
47751
  }
47575
47752
  }, selectedName);
47753
+ } else if (isShowingClassChooser) {
47754
+ detailContent = /*#__PURE__*/jsxRuntime.jsx(NewProviderPicker, {
47755
+ onSelect: function onSelect(cls) {
47756
+ setIsShowingClassChooser(false);
47757
+ setCameFromClassChooser(true);
47758
+ if (cls === "mcp") {
47759
+ setIsAddingMcp(true);
47760
+ } else if (cls === "websocket") {
47761
+ setIsAddingWs(true);
47762
+ } else {
47763
+ setIsCreating(true);
47764
+ }
47765
+ }
47766
+ });
47576
47767
  } else if (isAddingMcp) {
47577
47768
  detailContent = /*#__PURE__*/jsxRuntime.jsx(McpCatalogDetail, {
47578
47769
  onSave: handleMcpSave,
47579
47770
  onCancel: function onCancel() {
47580
47771
  return setIsAddingMcp(false);
47581
47772
  },
47582
- initialSelectedId: initialProviderType
47773
+ initialSelectedId: initialProviderType,
47774
+ onBack: cameFromClassChooser ? goBackToClassChooser : null
47583
47775
  });
47584
47776
  } else if (isCreating) {
47585
47777
  detailContent = /*#__PURE__*/jsxRuntime.jsx(ProviderDetail, {
@@ -47594,7 +47786,8 @@ var ProvidersSection = function ProvidersSection(_ref) {
47594
47786
  onCancelEdit: function onCancelEdit() {
47595
47787
  resetForm();
47596
47788
  setIsCreating(false);
47597
- }
47789
+ },
47790
+ onBack: cameFromClassChooser ? goBackToClassChooser : null
47598
47791
  });
47599
47792
  } else if (isEditingMcp && selectedName && selectedProvider) {
47600
47793
  var mc = selectedProvider.mcpConfig || {};