@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.esm.js CHANGED
@@ -3711,7 +3711,7 @@ var FolderDetail = function FolderDetail(_ref) {
3711
3711
  });
3712
3712
  };
3713
3713
 
3714
- var OptionCard$1 = function OptionCard(_ref) {
3714
+ var OptionCard$2 = function OptionCard(_ref) {
3715
3715
  var icon = _ref.icon,
3716
3716
  title = _ref.title,
3717
3717
  description = _ref.description,
@@ -3760,28 +3760,28 @@ var CreationMethodPicker = function CreationMethodPicker(_ref2) {
3760
3760
  })]
3761
3761
  }), /*#__PURE__*/jsxs("div", {
3762
3762
  className: "flex flex-col w-2/3 p-6 pt-10 space-y-3",
3763
- children: [/*#__PURE__*/jsx(OptionCard$1, {
3763
+ children: [/*#__PURE__*/jsx(OptionCard$2, {
3764
3764
  icon: "plus",
3765
3765
  title: "New Dashboard",
3766
3766
  description: "Start from a blank template and customize your layout",
3767
3767
  onClick: function onClick() {
3768
3768
  return onSelect("template");
3769
3769
  }
3770
- }), /*#__PURE__*/jsx(OptionCard$1, {
3770
+ }), /*#__PURE__*/jsx(OptionCard$2, {
3771
3771
  icon: "file-zipper",
3772
3772
  title: "Import from File",
3773
3773
  description: "Import a dashboard from a .zip file on your computer",
3774
3774
  onClick: function onClick() {
3775
3775
  return onSelect("import");
3776
3776
  }
3777
- }), /*#__PURE__*/jsx(OptionCard$1, {
3777
+ }), /*#__PURE__*/jsx(OptionCard$2, {
3778
3778
  icon: "compass",
3779
3779
  title: "Search Registry",
3780
3780
  description: "Browse and install dashboards from the online registry",
3781
3781
  onClick: function onClick() {
3782
3782
  return onSelect("registry");
3783
3783
  }
3784
- }), /*#__PURE__*/jsx(OptionCard$1, {
3784
+ }), /*#__PURE__*/jsx(OptionCard$2, {
3785
3785
  icon: "wand-magic-sparkles",
3786
3786
  title: "Dashboard Wizard",
3787
3787
  description: "Guided setup \u2014 pick categories, providers, and widgets step by step",
@@ -47054,6 +47054,103 @@ var WebSocketProviderForm = function WebSocketProviderForm(_ref) {
47054
47054
  });
47055
47055
  };
47056
47056
 
47057
+ var OptionCard$1 = function OptionCard(_ref) {
47058
+ var icon = _ref.icon,
47059
+ title = _ref.title,
47060
+ description = _ref.description,
47061
+ onClick = _ref.onClick,
47062
+ currentTheme = _ref.currentTheme;
47063
+ return /*#__PURE__*/jsxs("button", {
47064
+ type: "button",
47065
+ onClick: onClick,
47066
+ 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"),
47067
+ children: [/*#__PURE__*/jsx("div", {
47068
+ className: "flex-shrink-0 h-8 w-8 flex items-center justify-center opacity-60",
47069
+ children: /*#__PURE__*/jsx(FontAwesomeIcon, {
47070
+ icon: icon,
47071
+ className: "h-5 w-5"
47072
+ })
47073
+ }), /*#__PURE__*/jsxs("div", {
47074
+ className: "flex flex-col min-w-0",
47075
+ children: [/*#__PURE__*/jsx("span", {
47076
+ className: "text-sm font-medium",
47077
+ children: title
47078
+ }), /*#__PURE__*/jsx("span", {
47079
+ className: "text-xs opacity-50 mt-0.5",
47080
+ children: description
47081
+ })]
47082
+ }), /*#__PURE__*/jsx("div", {
47083
+ className: "flex-shrink-0 ml-auto opacity-30",
47084
+ children: /*#__PURE__*/jsx(FontAwesomeIcon, {
47085
+ icon: "chevron-right",
47086
+ className: "h-3 w-3"
47087
+ })
47088
+ })]
47089
+ });
47090
+ };
47091
+
47092
+ /**
47093
+ * NewProviderPicker — the 3-option chooser shown when the user clicks
47094
+ * "+ New Provider" from the Settings → Providers header without a
47095
+ * specific class pre-selected. Mirrors InstallWidgetPicker's pattern
47096
+ * so the UI feels consistent across "+ New ..." entry points in
47097
+ * Settings.
47098
+ *
47099
+ * Calls `onSelect(class)` with the literal class string ("credential",
47100
+ * "mcp", or "websocket"). The parent (ProvidersSection) then routes
47101
+ * to the appropriate create flow:
47102
+ *
47103
+ * credential → ProviderDetail (credential create form)
47104
+ * mcp → McpCatalogDetail (catalog browser)
47105
+ * websocket → WsProviderDetail (WebSocket add form)
47106
+ *
47107
+ * The Widget Builder's existing deep-link path (which always passes
47108
+ * an explicit class) bypasses this chooser and goes straight to the
47109
+ * matching form.
47110
+ */
47111
+ var NewProviderPicker = function NewProviderPicker(_ref2) {
47112
+ var onSelect = _ref2.onSelect;
47113
+ var _useContext = useContext(ThemeContext),
47114
+ currentTheme = _useContext.currentTheme;
47115
+ var panelStyles = getStylesForItem(themeObjects.PANEL, currentTheme, {
47116
+ grow: false
47117
+ });
47118
+ return /*#__PURE__*/jsx("div", {
47119
+ className: "flex flex-col flex-1 min-h-0",
47120
+ children: /*#__PURE__*/jsxs("div", {
47121
+ className: "flex-1 overflow-y-auto p-6 space-y-3 ".concat(panelStyles.textColor || "text-gray-200"),
47122
+ children: [/*#__PURE__*/jsx("span", {
47123
+ className: "text-xs font-semibold opacity-50 block mb-4",
47124
+ children: "ADD A NEW PROVIDER"
47125
+ }), /*#__PURE__*/jsx(OptionCard$1, {
47126
+ icon: "key",
47127
+ title: "Credential",
47128
+ description: "API key or token credentials for services like Algolia, Anthropic, or any HTTP API",
47129
+ onClick: function onClick() {
47130
+ return onSelect("credential");
47131
+ },
47132
+ currentTheme: currentTheme
47133
+ }), /*#__PURE__*/jsx(OptionCard$1, {
47134
+ icon: "plug",
47135
+ title: "MCP",
47136
+ description: "Model Context Protocol server \u2014 pick from a curated catalog (Slack, Filesystem, Notion, etc.)",
47137
+ onClick: function onClick() {
47138
+ return onSelect("mcp");
47139
+ },
47140
+ currentTheme: currentTheme
47141
+ }), /*#__PURE__*/jsx(OptionCard$1, {
47142
+ icon: "diagram-project",
47143
+ title: "WebSocket",
47144
+ description: "Real-time WebSocket connection to a streaming endpoint",
47145
+ onClick: function onClick() {
47146
+ return onSelect("websocket");
47147
+ },
47148
+ currentTheme: currentTheme
47149
+ })]
47150
+ })
47151
+ });
47152
+ };
47153
+
47057
47154
  var ProvidersSection = function ProvidersSection(_ref) {
47058
47155
  var _ref$dashApi = _ref.dashApi,
47059
47156
  dashApi = _ref$dashApi === void 0 ? null : _ref$dashApi,
@@ -47094,42 +47191,51 @@ var ProvidersSection = function ProvidersSection(_ref) {
47094
47191
  _useState8 = _slicedToArray(_useState7, 2),
47095
47192
  isCreating = _useState8[0],
47096
47193
  setIsCreating = _useState8[1];
47194
+ // When the user clicks "+ New Provider" without a pre-selected
47195
+ // class (Settings header button), show the class chooser
47196
+ // (Credential / MCP / WebSocket) instead of defaulting to the
47197
+ // credential form. Widget Builder's deep-link path passes a class
47198
+ // explicitly and bypasses this chooser.
47097
47199
  var _useState9 = useState(false),
47098
47200
  _useState0 = _slicedToArray(_useState9, 2),
47099
- isEditing = _useState0[0],
47100
- setIsEditing = _useState0[1];
47101
- var _useState1 = useState(""),
47201
+ isShowingClassChooser = _useState0[0],
47202
+ setIsShowingClassChooser = _useState0[1];
47203
+ var _useState1 = useState(false),
47102
47204
  _useState10 = _slicedToArray(_useState1, 2),
47103
- formName = _useState10[0],
47104
- setFormName = _useState10[1];
47205
+ isEditing = _useState10[0],
47206
+ setIsEditing = _useState10[1];
47105
47207
  var _useState11 = useState(""),
47106
47208
  _useState12 = _slicedToArray(_useState11, 2),
47107
- formType = _useState12[0],
47108
- setFormType = _useState12[1];
47109
- var _useState13 = useState({}),
47209
+ formName = _useState12[0],
47210
+ setFormName = _useState12[1];
47211
+ var _useState13 = useState(""),
47110
47212
  _useState14 = _slicedToArray(_useState13, 2),
47111
- formCredentials = _useState14[0],
47112
- setFormCredentials = _useState14[1];
47113
- var _useState15 = useState(null),
47213
+ formType = _useState14[0],
47214
+ setFormType = _useState14[1];
47215
+ var _useState15 = useState({}),
47114
47216
  _useState16 = _slicedToArray(_useState15, 2),
47115
- deleteTarget = _useState16[0],
47116
- setDeleteTarget = _useState16[1];
47117
- var _useState17 = useState(false),
47217
+ formCredentials = _useState16[0],
47218
+ setFormCredentials = _useState16[1];
47219
+ var _useState17 = useState(null),
47118
47220
  _useState18 = _slicedToArray(_useState17, 2),
47119
- isAddingMcp = _useState18[0],
47120
- setIsAddingMcp = _useState18[1];
47221
+ deleteTarget = _useState18[0],
47222
+ setDeleteTarget = _useState18[1];
47121
47223
  var _useState19 = useState(false),
47122
47224
  _useState20 = _slicedToArray(_useState19, 2),
47123
- isEditingMcp = _useState20[0],
47124
- setIsEditingMcp = _useState20[1];
47225
+ isAddingMcp = _useState20[0],
47226
+ setIsAddingMcp = _useState20[1];
47125
47227
  var _useState21 = useState(false),
47126
47228
  _useState22 = _slicedToArray(_useState21, 2),
47127
- isAddingWs = _useState22[0],
47128
- setIsAddingWs = _useState22[1];
47229
+ isEditingMcp = _useState22[0],
47230
+ setIsEditingMcp = _useState22[1];
47129
47231
  var _useState23 = useState(false),
47130
47232
  _useState24 = _slicedToArray(_useState23, 2),
47131
- isEditingWs = _useState24[0],
47132
- setIsEditingWs = _useState24[1];
47233
+ isAddingWs = _useState24[0],
47234
+ setIsAddingWs = _useState24[1];
47235
+ var _useState25 = useState(false),
47236
+ _useState26 = _slicedToArray(_useState25, 2),
47237
+ isEditingWs = _useState26[0],
47238
+ setIsEditingWs = _useState26[1];
47133
47239
 
47134
47240
  // Row ID counter for env/header rows in MCP edit mode
47135
47241
  var nextRowIdRef = useRef(0);
@@ -47411,19 +47517,35 @@ var ProvidersSection = function ProvidersSection(_ref) {
47411
47517
  if (createRequested && !prevCreateRequested.current) {
47412
47518
  resetForm();
47413
47519
  setSelectedName(null);
47520
+ setIsShowingClassChooser(false);
47414
47521
  if (initialProviderClass === "mcp") {
47415
47522
  // MCP class: open the catalog detail. Pre-select happens in
47416
47523
  // McpCatalogDetail via the initialSelectedId prop passed below.
47417
47524
  setIsCreating(false);
47418
47525
  setIsAddingMcp(true);
47419
- } else {
47420
- // Credential class (default): open the credential create form
47421
- // and pre-fill the type field if provided.
47526
+ } else if (initialProviderClass === "websocket") {
47527
+ // WebSocket class: open the WebSocket add form. Reachable via
47528
+ // a future Widget Builder deep-link for ws-typed widgets.
47529
+ setIsCreating(false);
47530
+ setIsAddingMcp(false);
47531
+ setIsAddingWs(true);
47532
+ } else if (initialProviderClass === "credential") {
47533
+ // Credential class: open the credential create form and
47534
+ // pre-fill the type field if provided.
47422
47535
  setIsAddingMcp(false);
47423
47536
  setIsCreating(true);
47424
47537
  if (initialProviderType) {
47425
47538
  setFormType(initialProviderType);
47426
47539
  }
47540
+ } else {
47541
+ // No class specified — Settings header "+ New Provider"
47542
+ // button hits this branch. Show the chooser so the user
47543
+ // picks Credential / MCP / WebSocket explicitly instead of
47544
+ // landing on the credential form by default.
47545
+ setIsAddingMcp(false);
47546
+ setIsCreating(false);
47547
+ setIsAddingWs(false);
47548
+ setIsShowingClassChooser(true);
47427
47549
  }
47428
47550
  }
47429
47551
  prevCreateRequested.current = createRequested;
@@ -47555,6 +47677,19 @@ var ProvidersSection = function ProvidersSection(_ref) {
47555
47677
  return setIsEditingWs(false);
47556
47678
  }
47557
47679
  }, selectedName);
47680
+ } else if (isShowingClassChooser) {
47681
+ detailContent = /*#__PURE__*/jsx(NewProviderPicker, {
47682
+ onSelect: function onSelect(cls) {
47683
+ setIsShowingClassChooser(false);
47684
+ if (cls === "mcp") {
47685
+ setIsAddingMcp(true);
47686
+ } else if (cls === "websocket") {
47687
+ setIsAddingWs(true);
47688
+ } else {
47689
+ setIsCreating(true);
47690
+ }
47691
+ }
47692
+ });
47558
47693
  } else if (isAddingMcp) {
47559
47694
  detailContent = /*#__PURE__*/jsx(McpCatalogDetail, {
47560
47695
  onSave: handleMcpSave,