@trops/dash-core 0.1.453 → 0.1.454

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",
@@ -47072,6 +47072,103 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
47072
47072
  });
47073
47073
  };
47074
47074
 
47075
+ var OptionCard$1 = function OptionCard(_ref) {
47076
+ var icon = _ref.icon,
47077
+ title = _ref.title,
47078
+ description = _ref.description,
47079
+ onClick = _ref.onClick,
47080
+ currentTheme = _ref.currentTheme;
47081
+ return /*#__PURE__*/jsxRuntime.jsxs("button", {
47082
+ type: "button",
47083
+ onClick: onClick,
47084
+ 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"),
47085
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
47086
+ className: "flex-shrink-0 h-8 w-8 flex items-center justify-center opacity-60",
47087
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
47088
+ icon: icon,
47089
+ className: "h-5 w-5"
47090
+ })
47091
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
47092
+ className: "flex flex-col min-w-0",
47093
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
47094
+ className: "text-sm font-medium",
47095
+ children: title
47096
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
47097
+ className: "text-xs opacity-50 mt-0.5",
47098
+ children: description
47099
+ })]
47100
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
47101
+ className: "flex-shrink-0 ml-auto opacity-30",
47102
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
47103
+ icon: "chevron-right",
47104
+ className: "h-3 w-3"
47105
+ })
47106
+ })]
47107
+ });
47108
+ };
47109
+
47110
+ /**
47111
+ * NewProviderPicker — the 3-option chooser shown when the user clicks
47112
+ * "+ New Provider" from the Settings → Providers header without a
47113
+ * specific class pre-selected. Mirrors InstallWidgetPicker's pattern
47114
+ * so the UI feels consistent across "+ New ..." entry points in
47115
+ * Settings.
47116
+ *
47117
+ * Calls `onSelect(class)` with the literal class string ("credential",
47118
+ * "mcp", or "websocket"). The parent (ProvidersSection) then routes
47119
+ * to the appropriate create flow:
47120
+ *
47121
+ * credential → ProviderDetail (credential create form)
47122
+ * mcp → McpCatalogDetail (catalog browser)
47123
+ * websocket → WsProviderDetail (WebSocket add form)
47124
+ *
47125
+ * The Widget Builder's existing deep-link path (which always passes
47126
+ * an explicit class) bypasses this chooser and goes straight to the
47127
+ * matching form.
47128
+ */
47129
+ var NewProviderPicker = function NewProviderPicker(_ref2) {
47130
+ var onSelect = _ref2.onSelect;
47131
+ var _useContext = React.useContext(DashReact.ThemeContext),
47132
+ currentTheme = _useContext.currentTheme;
47133
+ var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
47134
+ grow: false
47135
+ });
47136
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
47137
+ className: "flex flex-col flex-1 min-h-0",
47138
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
47139
+ className: "flex-1 overflow-y-auto p-6 space-y-3 ".concat(panelStyles.textColor || "text-gray-200"),
47140
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
47141
+ className: "text-xs font-semibold opacity-50 block mb-4",
47142
+ children: "ADD A NEW PROVIDER"
47143
+ }), /*#__PURE__*/jsxRuntime.jsx(OptionCard$1, {
47144
+ icon: "key",
47145
+ title: "Credential",
47146
+ description: "API key or token credentials for services like Algolia, Anthropic, or any HTTP API",
47147
+ onClick: function onClick() {
47148
+ return onSelect("credential");
47149
+ },
47150
+ currentTheme: currentTheme
47151
+ }), /*#__PURE__*/jsxRuntime.jsx(OptionCard$1, {
47152
+ icon: "plug",
47153
+ title: "MCP",
47154
+ description: "Model Context Protocol server \u2014 pick from a curated catalog (Slack, Filesystem, Notion, etc.)",
47155
+ onClick: function onClick() {
47156
+ return onSelect("mcp");
47157
+ },
47158
+ currentTheme: currentTheme
47159
+ }), /*#__PURE__*/jsxRuntime.jsx(OptionCard$1, {
47160
+ icon: "diagram-project",
47161
+ title: "WebSocket",
47162
+ description: "Real-time WebSocket connection to a streaming endpoint",
47163
+ onClick: function onClick() {
47164
+ return onSelect("websocket");
47165
+ },
47166
+ currentTheme: currentTheme
47167
+ })]
47168
+ })
47169
+ });
47170
+ };
47171
+
47075
47172
  var ProvidersSection = function ProvidersSection(_ref) {
47076
47173
  var _ref$dashApi = _ref.dashApi,
47077
47174
  dashApi = _ref$dashApi === void 0 ? null : _ref$dashApi,
@@ -47112,42 +47209,51 @@ var ProvidersSection = function ProvidersSection(_ref) {
47112
47209
  _useState8 = _slicedToArray(_useState7, 2),
47113
47210
  isCreating = _useState8[0],
47114
47211
  setIsCreating = _useState8[1];
47212
+ // When the user clicks "+ New Provider" without a pre-selected
47213
+ // class (Settings header button), show the class chooser
47214
+ // (Credential / MCP / WebSocket) instead of defaulting to the
47215
+ // credential form. Widget Builder's deep-link path passes a class
47216
+ // explicitly and bypasses this chooser.
47115
47217
  var _useState9 = React.useState(false),
47116
47218
  _useState0 = _slicedToArray(_useState9, 2),
47117
- isEditing = _useState0[0],
47118
- setIsEditing = _useState0[1];
47119
- var _useState1 = React.useState(""),
47219
+ isShowingClassChooser = _useState0[0],
47220
+ setIsShowingClassChooser = _useState0[1];
47221
+ var _useState1 = React.useState(false),
47120
47222
  _useState10 = _slicedToArray(_useState1, 2),
47121
- formName = _useState10[0],
47122
- setFormName = _useState10[1];
47223
+ isEditing = _useState10[0],
47224
+ setIsEditing = _useState10[1];
47123
47225
  var _useState11 = React.useState(""),
47124
47226
  _useState12 = _slicedToArray(_useState11, 2),
47125
- formType = _useState12[0],
47126
- setFormType = _useState12[1];
47127
- var _useState13 = React.useState({}),
47227
+ formName = _useState12[0],
47228
+ setFormName = _useState12[1];
47229
+ var _useState13 = React.useState(""),
47128
47230
  _useState14 = _slicedToArray(_useState13, 2),
47129
- formCredentials = _useState14[0],
47130
- setFormCredentials = _useState14[1];
47131
- var _useState15 = React.useState(null),
47231
+ formType = _useState14[0],
47232
+ setFormType = _useState14[1];
47233
+ var _useState15 = React.useState({}),
47132
47234
  _useState16 = _slicedToArray(_useState15, 2),
47133
- deleteTarget = _useState16[0],
47134
- setDeleteTarget = _useState16[1];
47135
- var _useState17 = React.useState(false),
47235
+ formCredentials = _useState16[0],
47236
+ setFormCredentials = _useState16[1];
47237
+ var _useState17 = React.useState(null),
47136
47238
  _useState18 = _slicedToArray(_useState17, 2),
47137
- isAddingMcp = _useState18[0],
47138
- setIsAddingMcp = _useState18[1];
47239
+ deleteTarget = _useState18[0],
47240
+ setDeleteTarget = _useState18[1];
47139
47241
  var _useState19 = React.useState(false),
47140
47242
  _useState20 = _slicedToArray(_useState19, 2),
47141
- isEditingMcp = _useState20[0],
47142
- setIsEditingMcp = _useState20[1];
47243
+ isAddingMcp = _useState20[0],
47244
+ setIsAddingMcp = _useState20[1];
47143
47245
  var _useState21 = React.useState(false),
47144
47246
  _useState22 = _slicedToArray(_useState21, 2),
47145
- isAddingWs = _useState22[0],
47146
- setIsAddingWs = _useState22[1];
47247
+ isEditingMcp = _useState22[0],
47248
+ setIsEditingMcp = _useState22[1];
47147
47249
  var _useState23 = React.useState(false),
47148
47250
  _useState24 = _slicedToArray(_useState23, 2),
47149
- isEditingWs = _useState24[0],
47150
- setIsEditingWs = _useState24[1];
47251
+ isAddingWs = _useState24[0],
47252
+ setIsAddingWs = _useState24[1];
47253
+ var _useState25 = React.useState(false),
47254
+ _useState26 = _slicedToArray(_useState25, 2),
47255
+ isEditingWs = _useState26[0],
47256
+ setIsEditingWs = _useState26[1];
47151
47257
 
47152
47258
  // Row ID counter for env/header rows in MCP edit mode
47153
47259
  var nextRowIdRef = React.useRef(0);
@@ -47429,19 +47535,35 @@ var ProvidersSection = function ProvidersSection(_ref) {
47429
47535
  if (createRequested && !prevCreateRequested.current) {
47430
47536
  resetForm();
47431
47537
  setSelectedName(null);
47538
+ setIsShowingClassChooser(false);
47432
47539
  if (initialProviderClass === "mcp") {
47433
47540
  // MCP class: open the catalog detail. Pre-select happens in
47434
47541
  // McpCatalogDetail via the initialSelectedId prop passed below.
47435
47542
  setIsCreating(false);
47436
47543
  setIsAddingMcp(true);
47437
- } else {
47438
- // Credential class (default): open the credential create form
47439
- // and pre-fill the type field if provided.
47544
+ } else if (initialProviderClass === "websocket") {
47545
+ // WebSocket class: open the WebSocket add form. Reachable via
47546
+ // a future Widget Builder deep-link for ws-typed widgets.
47547
+ setIsCreating(false);
47548
+ setIsAddingMcp(false);
47549
+ setIsAddingWs(true);
47550
+ } else if (initialProviderClass === "credential") {
47551
+ // Credential class: open the credential create form and
47552
+ // pre-fill the type field if provided.
47440
47553
  setIsAddingMcp(false);
47441
47554
  setIsCreating(true);
47442
47555
  if (initialProviderType) {
47443
47556
  setFormType(initialProviderType);
47444
47557
  }
47558
+ } else {
47559
+ // No class specified — Settings header "+ New Provider"
47560
+ // button hits this branch. Show the chooser so the user
47561
+ // picks Credential / MCP / WebSocket explicitly instead of
47562
+ // landing on the credential form by default.
47563
+ setIsAddingMcp(false);
47564
+ setIsCreating(false);
47565
+ setIsAddingWs(false);
47566
+ setIsShowingClassChooser(true);
47445
47567
  }
47446
47568
  }
47447
47569
  prevCreateRequested.current = createRequested;
@@ -47573,6 +47695,19 @@ var ProvidersSection = function ProvidersSection(_ref) {
47573
47695
  return setIsEditingWs(false);
47574
47696
  }
47575
47697
  }, selectedName);
47698
+ } else if (isShowingClassChooser) {
47699
+ detailContent = /*#__PURE__*/jsxRuntime.jsx(NewProviderPicker, {
47700
+ onSelect: function onSelect(cls) {
47701
+ setIsShowingClassChooser(false);
47702
+ if (cls === "mcp") {
47703
+ setIsAddingMcp(true);
47704
+ } else if (cls === "websocket") {
47705
+ setIsAddingWs(true);
47706
+ } else {
47707
+ setIsCreating(true);
47708
+ }
47709
+ }
47710
+ });
47576
47711
  } else if (isAddingMcp) {
47577
47712
  detailContent = /*#__PURE__*/jsxRuntime.jsx(McpCatalogDetail, {
47578
47713
  onSave: handleMcpSave,