@trops/dash-core 0.1.459 → 0.1.461

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
@@ -6888,6 +6888,11 @@ var useRegistrySearch = function useRegistrySearch() {
6888
6888
  search: search,
6889
6889
  installPackage: installPackage,
6890
6890
  retry: retry,
6891
+ // refetch is an alias of retry, exposed under the name the
6892
+ // Wizard's sign-in flow uses to re-fetch the registry once
6893
+ // the user signs in (so private results show up without a
6894
+ // manual reload).
6895
+ refetch: retry,
6891
6896
  showAllPackages: showAllPackages,
6892
6897
  setShowAllPackages: setShowAllPackages,
6893
6898
  appCapabilities: appCapabilities
@@ -6964,12 +6969,19 @@ var KNOWN_PROVIDERS = [{
6964
6969
  /**
6965
6970
  * WizardDiscoverStep
6966
6971
  *
6967
- * Step 0 of the Dashboard Wizard. Combines search, category/provider
6968
- * filter chips, and results (dashboards + widgets) in a single view.
6969
- * Replaces the old Intent, Providers, and Results steps.
6972
+ * Step 0 of the Dashboard Wizard. Two-column layout mirroring the
6973
+ * dash-registry homepage: a left filter sidebar (TYPE / CATEGORIES /
6974
+ * PROVIDERS as vertical lists) and a right content pane with the
6975
+ * search input + result grid.
6970
6976
  *
6971
- * - Selecting a dashboard sets path to "prebuilt" and clears widget selections.
6972
- * - Selecting widgets sets path to "custom" and clears dashboard selection.
6977
+ * - TYPE filter (single-select): All / Dashboards / Widgets. Replaces
6978
+ * the previous tab bar so the right pane is a single result surface.
6979
+ * - CATEGORIES + PROVIDERS (multi-select): preserves the existing
6980
+ * wizard filter shape (`filters.categories[]`, `filters.providers[]`).
6981
+ *
6982
+ * Selecting a dashboard sets path = "prebuilt" and clears widget
6983
+ * selections. Selecting widgets sets path = "custom" and clears the
6984
+ * dashboard selection.
6973
6985
  *
6974
6986
  * @param {Object} props
6975
6987
  * @param {Object} props.state - Wizard state from useWizardState
@@ -6989,7 +7001,27 @@ var WizardDiscoverStep = function WizardDiscoverStep(_ref) {
6989
7001
  isLoading = _useRegistrySearch.isLoading,
6990
7002
  error = _useRegistrySearch.error,
6991
7003
  searchQuery = _useRegistrySearch.searchQuery,
6992
- setSearchQuery = _useRegistrySearch.setSearchQuery;
7004
+ setSearchQuery = _useRegistrySearch.setSearchQuery,
7005
+ refetch = _useRegistrySearch.refetch;
7006
+
7007
+ // --- Registry auth (device-code OAuth) ---
7008
+ // Surfaces a sign-in CTA when the user isn't authenticated so they
7009
+ // see private dashboards/widgets they have access to. After
7010
+ // successful auth, `refetch` re-runs the registry search so the
7011
+ // results refresh automatically — no manual reload needed.
7012
+ var _useRegistryAuth = useRegistryAuth(),
7013
+ isAuthenticated = _useRegistryAuth.isAuthenticated,
7014
+ isAuthenticating = _useRegistryAuth.isAuthenticating,
7015
+ authError = _useRegistryAuth.authError,
7016
+ checkAuth = _useRegistryAuth.checkAuth,
7017
+ initiateAuth = _useRegistryAuth.initiateAuth,
7018
+ cancelAuth = _useRegistryAuth.cancelAuth;
7019
+ React.useEffect(function () {
7020
+ checkAuth();
7021
+ }, [checkAuth]);
7022
+ var handleSignIn = React.useCallback(function () {
7023
+ initiateAuth(refetch);
7024
+ }, [initiateAuth, refetch]);
6993
7025
 
6994
7026
  // Sync search query from wizard state on mount
6995
7027
  React.useEffect(function () {
@@ -7052,7 +7084,7 @@ var WizardDiscoverStep = function WizardDiscoverStep(_ref) {
7052
7084
  });
7053
7085
  }, [state.selectedWidgets]);
7054
7086
 
7055
- // --- Filter chip handlers ---
7087
+ // --- Filter handlers ---
7056
7088
  var handleToggleCategory = React.useCallback(function (cat) {
7057
7089
  return dispatch({
7058
7090
  type: "TOGGLE_FILTER_CATEGORY",
@@ -7066,13 +7098,26 @@ var WizardDiscoverStep = function WizardDiscoverStep(_ref) {
7066
7098
  });
7067
7099
  }, [dispatch]);
7068
7100
 
7069
- // Tab state (DASH-185)
7101
+ // TYPE filter — replaces the old tab bar. Binary because the
7102
+ // wizard's data model is mutually exclusive: selecting a dashboard
7103
+ // clears widgets and sets path="prebuilt"; selecting a widget
7104
+ // clears the dashboard and sets path="custom". An "All" view would
7105
+ // imply you can browse both freely when in reality the first click
7106
+ // commits you to one of two paths. Defaulting to "dashboards" since
7107
+ // pre-built is the simpler, more common starting point.
7070
7108
  var _useState = React.useState("dashboards"),
7071
7109
  _useState2 = _slicedToArray(_useState, 2),
7072
- activeTab = _useState2[0],
7073
- setActiveTab = _useState2[1];
7110
+ typeFilter = _useState2[0],
7111
+ setTypeFilter = _useState2[1];
7112
+ var TYPE_OPTIONS = [{
7113
+ key: "dashboards",
7114
+ label: "Dashboards"
7115
+ }, {
7116
+ key: "widgets",
7117
+ label: "Widgets"
7118
+ }];
7074
7119
 
7075
- // Clear selection handler (DASH-186)
7120
+ // Clear-selection handler
7076
7121
  var hasSelection = state.selectedDashboard !== null || state.selectedWidgets.length > 0;
7077
7122
  var handleClearSelection = React.useCallback(function () {
7078
7123
  dispatch({
@@ -7088,236 +7133,276 @@ var WizardDiscoverStep = function WizardDiscoverStep(_ref) {
7088
7133
  payload: null
7089
7134
  });
7090
7135
  }, [dispatch]);
7091
- var hasResults = filteredDashboards.length > 0 || filteredWidgets.length > 0;
7136
+ var showDashboards = typeFilter === "dashboards";
7137
+ var showWidgets = typeFilter === "widgets";
7138
+ var visibleDashboards = showDashboards ? filteredDashboards : [];
7139
+ var visibleWidgets = showWidgets ? filteredWidgets : [];
7140
+ var hasResults = visibleDashboards.length > 0 || visibleWidgets.length > 0;
7092
7141
  var hasActiveFilters = filters.categories.length > 0 || filters.providers.length > 0;
7142
+
7143
+ // Shared row class for sidebar list items.
7144
+ var rowClass = function rowClass(active) {
7145
+ return "text-sm py-1.5 px-3 rounded text-left transition-colors flex items-center justify-between ".concat(active ? "bg-blue-900 text-blue-200" : "text-gray-400 hover:bg-gray-800 hover:text-gray-200");
7146
+ };
7147
+ var sectionLabelClass = "text-xs font-semibold text-gray-400 uppercase tracking-wide px-3 mb-1";
7093
7148
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
7094
- className: "flex flex-col gap-4",
7095
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
7096
- value: searchQuery,
7097
- onChange: handleSearchChange,
7098
- placeholder: "Search registry..."
7099
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
7100
- className: "flex flex-col gap-3",
7101
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
7102
- className: "flex flex-col gap-1.5",
7149
+ className: "flex flex-row gap-4",
7150
+ children: [/*#__PURE__*/jsxRuntime.jsxs("aside", {
7151
+ className: "flex-shrink-0 w-56 flex flex-col gap-4 overflow-y-auto",
7152
+ children: [!isAuthenticated && /*#__PURE__*/jsxRuntime.jsxs("div", {
7153
+ className: "flex flex-col gap-2 px-3 py-3 rounded bg-gray-800 text-gray-300",
7103
7154
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
7104
- className: "text-xs font-semibold text-gray-400 uppercase tracking-wide",
7105
- children: "Categories"
7106
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
7107
- className: "flex flex-wrap gap-1.5",
7108
- children: DASHBOARD_TAGS$1.map(function (tag) {
7109
- return /*#__PURE__*/jsxRuntime.jsx(DashReact.Tag2, {
7110
- text: tag,
7111
- onClick: function onClick() {
7112
- return handleToggleCategory(tag);
7113
- },
7114
- active: filters.categories.includes(tag)
7115
- }, tag);
7116
- })
7117
- })]
7118
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
7119
- className: "flex flex-col gap-1.5",
7120
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
7121
- className: "text-xs font-semibold text-gray-400 uppercase tracking-wide",
7122
- children: "Providers"
7123
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
7124
- className: "flex flex-wrap gap-1.5",
7125
- children: KNOWN_PROVIDERS.map(function (prov) {
7126
- return /*#__PURE__*/jsxRuntime.jsx(DashReact.Tag2, {
7127
- text: prov.name,
7128
- onClick: function onClick() {
7129
- return handleToggleProvider(prov.key);
7130
- },
7131
- active: filters.providers.includes(prov.key)
7132
- }, prov.key);
7133
- })
7134
- })]
7135
- })]
7136
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
7137
- className: "flex items-center justify-between",
7138
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
7139
- className: "flex gap-1",
7140
- children: [/*#__PURE__*/jsxRuntime.jsxs("button", {
7141
- type: "button",
7142
- className: "px-4 py-2 text-sm font-medium rounded-t transition-colors ".concat(activeTab === "dashboards" ? "bg-gray-800 text-blue-400 border-b-2 border-blue-400" : "text-gray-400 hover:text-gray-200"),
7143
- onClick: function onClick() {
7144
- return setActiveTab("dashboards");
7145
- },
7146
- children: ["Dashboards (", filteredDashboards.length, ")"]
7147
- }), /*#__PURE__*/jsxRuntime.jsxs("button", {
7155
+ className: "text-xs font-semibold text-gray-200",
7156
+ children: "Sign in to registry"
7157
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
7158
+ className: "text-xs text-gray-400",
7159
+ children: "See dashboards and widgets you have access to"
7160
+ }), !isAuthenticating ? /*#__PURE__*/jsxRuntime.jsx("button", {
7148
7161
  type: "button",
7149
- className: "px-4 py-2 text-sm font-medium rounded-t transition-colors ".concat(activeTab === "widgets" ? "bg-gray-800 text-blue-400 border-b-2 border-blue-400" : "text-gray-400 hover:text-gray-200"),
7150
- onClick: function onClick() {
7151
- return setActiveTab("widgets");
7152
- },
7153
- children: ["Widgets (", filteredWidgets.length, ")", state.selectedWidgets.length > 0 && /*#__PURE__*/jsxRuntime.jsx("span", {
7154
- className: "ml-1.5",
7155
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Tag3, {
7156
- text: "".concat(state.selectedWidgets.length, " selected")
7157
- })
7162
+ onClick: handleSignIn,
7163
+ className: "mt-1 text-xs py-1.5 px-3 rounded bg-blue-600 text-white hover:bg-blue-500 transition-colors",
7164
+ children: "Sign in"
7165
+ }) : /*#__PURE__*/jsxRuntime.jsxs("div", {
7166
+ className: "mt-1 flex flex-col gap-1",
7167
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
7168
+ className: "text-xs text-gray-400",
7169
+ children: "Waiting for browser\u2026"
7170
+ }), /*#__PURE__*/jsxRuntime.jsx("button", {
7171
+ type: "button",
7172
+ onClick: cancelAuth,
7173
+ className: "text-xs text-gray-400 hover:text-gray-200 underline self-start",
7174
+ children: "Cancel"
7158
7175
  })]
7176
+ }), authError && /*#__PURE__*/jsxRuntime.jsx("span", {
7177
+ className: "text-xs text-red-400",
7178
+ children: authError
7159
7179
  })]
7160
- }), hasSelection && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
7161
- onClick: handleClearSelection,
7162
- title: "Clear Selection",
7163
- textSize: "text-xs",
7164
- padding: "py-1 px-3",
7165
- backgroundColor: "bg-gray-700",
7166
- textColor: "text-gray-400",
7167
- hoverTextColor: "hover:text-white",
7168
- hoverBackgroundColor: "hover:bg-gray-600",
7169
- icon: "xmark"
7170
- })]
7171
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
7172
- className: "flex flex-col gap-6",
7173
- children: isLoading ? /*#__PURE__*/jsxRuntime.jsxs("div", {
7174
- className: "flex flex-col items-center justify-center gap-2 py-12 text-gray-400",
7180
+ }), isAuthenticated && /*#__PURE__*/jsxRuntime.jsxs("div", {
7181
+ className: "flex items-center gap-2 px-3 text-xs text-gray-500",
7175
7182
  children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7176
- icon: "spinner",
7177
- spin: true,
7178
- fixedWidth: true
7183
+ icon: "circle-check",
7184
+ className: "text-green-400 text-xs"
7179
7185
  }), /*#__PURE__*/jsxRuntime.jsx("span", {
7180
- children: "Searching registry..."
7186
+ children: "Signed in"
7181
7187
  })]
7182
- }) : error ? /*#__PURE__*/jsxRuntime.jsxs("div", {
7183
- className: "flex items-center gap-2 text-red-400 py-4",
7184
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7185
- icon: "circle-exclamation",
7186
- fixedWidth: true
7187
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
7188
- children: error
7188
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
7189
+ className: "flex flex-col",
7190
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
7191
+ className: sectionLabelClass,
7192
+ children: "TYPE"
7193
+ }), TYPE_OPTIONS.map(function (opt) {
7194
+ var active = typeFilter === opt.key;
7195
+ var showBadge = opt.key === "widgets" && state.selectedWidgets.length > 0;
7196
+ return /*#__PURE__*/jsxRuntime.jsxs("button", {
7197
+ type: "button",
7198
+ onClick: function onClick() {
7199
+ return setTypeFilter(opt.key);
7200
+ },
7201
+ className: rowClass(active),
7202
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
7203
+ children: opt.label
7204
+ }), showBadge && /*#__PURE__*/jsxRuntime.jsx(DashReact.Tag3, {
7205
+ text: "".concat(state.selectedWidgets.length, " selected")
7206
+ })]
7207
+ }, opt.key);
7189
7208
  })]
7190
- }) : !hasResults ? /*#__PURE__*/jsxRuntime.jsxs("div", {
7191
- className: "flex flex-col items-center justify-center gap-2 py-12 text-gray-500",
7192
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7193
- icon: "magnifying-glass",
7194
- fixedWidth: true
7195
- }), /*#__PURE__*/jsxRuntime.jsx("p", {
7196
- children: "No results match your search."
7197
- }), hasActiveFilters && /*#__PURE__*/jsxRuntime.jsx("p", {
7198
- className: "text-xs text-gray-600",
7199
- children: "Try removing some filters to see more results."
7209
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
7210
+ className: "flex flex-col",
7211
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
7212
+ className: sectionLabelClass,
7213
+ children: "CATEGORIES"
7214
+ }), DASHBOARD_TAGS$1.map(function (tag) {
7215
+ var active = filters.categories.includes(tag);
7216
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
7217
+ type: "button",
7218
+ onClick: function onClick() {
7219
+ return handleToggleCategory(tag);
7220
+ },
7221
+ className: "".concat(rowClass(active), " capitalize"),
7222
+ children: /*#__PURE__*/jsxRuntime.jsx("span", {
7223
+ children: tag
7224
+ })
7225
+ }, tag);
7200
7226
  })]
7201
- }) : /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
7202
- children: [activeTab === "dashboards" && filteredDashboards.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
7203
- className: "flex flex-col gap-3",
7204
- children: /*#__PURE__*/jsxRuntime.jsx("div", {
7205
- className: "grid grid-cols-3 gap-3",
7206
- children: filteredDashboards.map(function (dash) {
7207
- var isSelected = state.selectedDashboard && state.selectedDashboard.name === dash.name;
7208
- var widgetCount = (dash.widgets || []).length;
7209
- var providerTags = (dash.providers || []).map(function (p) {
7210
- return p.name || p.type;
7211
- }).filter(Boolean);
7212
- return /*#__PURE__*/jsxRuntime.jsxs(DashReact.Card2, {
7213
- hover: true,
7214
- selected: isSelected,
7215
- padding: "p-5",
7216
- rounded: "rounded-lg",
7217
- className: "hover:shadow-lg",
7218
- onClick: function onClick() {
7219
- return handleSelectDashboard(dash);
7220
- },
7221
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
7222
- className: "flex flex-col items-center text-center gap-2",
7223
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
7224
- className: "relative",
7225
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
7226
- className: "text-2xl",
7227
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7228
- icon: resolveIcon(dash.icon || "grid-2"),
7229
- fixedWidth: true,
7230
- className: "text-gray-400"
7231
- })
7232
- }), isSelected && /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7233
- icon: "circle-check",
7234
- className: "absolute -top-1 -right-3 text-blue-400 text-xs"
7235
- })]
7236
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
7237
- className: "text-sm font-semibold text-gray-200",
7238
- children: dash.displayName || dash.name
7239
- })]
7240
- }), dash.description && /*#__PURE__*/jsxRuntime.jsx("p", {
7241
- className: "text-xs text-gray-400 mt-2 line-clamp-2 text-center",
7242
- children: dash.description
7243
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
7244
- className: "flex items-center justify-between mt-3 pt-2 border-t border-gray-700/50",
7245
- children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
7246
- className: "text-xs text-gray-500",
7247
- children: [widgetCount, " widget", widgetCount !== 1 ? "s" : ""]
7248
- }), providerTags.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
7249
- className: "flex flex-wrap gap-1 justify-end",
7250
- children: providerTags.slice(0, 3).map(function (tag) {
7251
- return /*#__PURE__*/jsxRuntime.jsx("span", {
7252
- className: "text-xs px-1.5 py-0.5 rounded bg-gray-800 text-gray-400",
7253
- children: tag
7254
- }, tag);
7255
- })
7256
- })]
7257
- })]
7258
- }, dash.name);
7227
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
7228
+ className: "flex flex-col",
7229
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
7230
+ className: sectionLabelClass,
7231
+ children: "PROVIDERS"
7232
+ }), KNOWN_PROVIDERS.map(function (prov) {
7233
+ var active = filters.providers.includes(prov.key);
7234
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
7235
+ type: "button",
7236
+ onClick: function onClick() {
7237
+ return handleToggleProvider(prov.key);
7238
+ },
7239
+ className: rowClass(active),
7240
+ children: /*#__PURE__*/jsxRuntime.jsx("span", {
7241
+ children: prov.name
7259
7242
  })
7243
+ }, prov.key);
7244
+ })]
7245
+ })]
7246
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
7247
+ className: "flex-1 min-w-0 flex flex-col gap-4",
7248
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
7249
+ className: "flex items-center gap-3",
7250
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
7251
+ className: "flex-1",
7252
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
7253
+ value: searchQuery,
7254
+ onChange: handleSearchChange,
7255
+ placeholder: "Search registry..."
7260
7256
  })
7261
- }), activeTab === "dashboards" && filteredDashboards.length === 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
7257
+ }), hasSelection && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
7258
+ onClick: handleClearSelection,
7259
+ title: "Clear Selection",
7260
+ textSize: "text-xs",
7261
+ padding: "py-1 px-3",
7262
+ backgroundColor: "bg-gray-700",
7263
+ textColor: "text-gray-400",
7264
+ hoverTextColor: "hover:text-white",
7265
+ hoverBackgroundColor: "hover:bg-gray-600",
7266
+ icon: "xmark"
7267
+ })]
7268
+ }), !isLoading && !error && /*#__PURE__*/jsxRuntime.jsx("div", {
7269
+ className: "text-xs text-gray-500 px-1",
7270
+ children: showDashboards ? "".concat(visibleDashboards.length, " dashboard").concat(visibleDashboards.length === 1 ? "" : "s") : "".concat(visibleWidgets.length, " widget").concat(visibleWidgets.length === 1 ? "" : "s")
7271
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
7272
+ className: "flex flex-col gap-6",
7273
+ children: isLoading ? /*#__PURE__*/jsxRuntime.jsxs("div", {
7274
+ className: "flex flex-col items-center justify-center gap-2 py-12 text-gray-400",
7275
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7276
+ icon: "spinner",
7277
+ spin: true,
7278
+ fixedWidth: true
7279
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
7280
+ children: "Searching registry..."
7281
+ })]
7282
+ }) : error ? /*#__PURE__*/jsxRuntime.jsxs("div", {
7283
+ className: "flex items-center gap-2 text-red-400 py-4",
7284
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7285
+ icon: "circle-exclamation",
7286
+ fixedWidth: true
7287
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
7288
+ children: error
7289
+ })]
7290
+ }) : !hasResults ? /*#__PURE__*/jsxRuntime.jsxs("div", {
7262
7291
  className: "flex flex-col items-center justify-center gap-2 py-12 text-gray-500",
7263
7292
  children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7264
- icon: "grid-2",
7293
+ icon: "magnifying-glass",
7265
7294
  fixedWidth: true
7266
7295
  }), /*#__PURE__*/jsxRuntime.jsx("p", {
7267
- children: "No dashboards match your search."
7296
+ children: "No results match your search."
7297
+ }), hasActiveFilters && /*#__PURE__*/jsxRuntime.jsx("p", {
7298
+ className: "text-xs text-gray-600",
7299
+ children: "Try removing some filters to see more results."
7268
7300
  })]
7269
- }), activeTab === "widgets" && filteredWidgets.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
7270
- className: "flex flex-col gap-3",
7271
- children: /*#__PURE__*/jsxRuntime.jsx("div", {
7272
- className: "grid grid-cols-3 gap-3",
7273
- children: filteredWidgets.map(function (widget) {
7274
- var checked = isWidgetSelected(widget);
7275
- return /*#__PURE__*/jsxRuntime.jsxs(DashReact.Card2, {
7276
- hover: true,
7277
- selected: checked,
7278
- padding: "p-4",
7279
- rounded: "rounded-lg",
7280
- className: "hover:shadow-lg flex flex-col",
7281
- onClick: function onClick() {
7282
- return handleToggleWidget(widget);
7283
- },
7284
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
7285
- className: "flex items-start justify-between gap-2",
7301
+ }) : /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
7302
+ children: [showDashboards && visibleDashboards.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
7303
+ className: "flex flex-col gap-3",
7304
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
7305
+ className: "grid grid-cols-3 gap-3",
7306
+ children: visibleDashboards.map(function (dash) {
7307
+ var isSelected = state.selectedDashboard && state.selectedDashboard.name === dash.name;
7308
+ var widgetCount = (dash.widgets || []).length;
7309
+ var providerTags = (dash.providers || []).map(function (p) {
7310
+ return p.name || p.type;
7311
+ }).filter(Boolean);
7312
+ return /*#__PURE__*/jsxRuntime.jsxs(DashReact.Card2, {
7313
+ hover: true,
7314
+ selected: isSelected,
7315
+ padding: "p-5",
7316
+ rounded: "rounded-lg",
7317
+ className: "hover:shadow-lg",
7318
+ onClick: function onClick() {
7319
+ return handleSelectDashboard(dash);
7320
+ },
7286
7321
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
7287
- className: "flex items-center gap-1.5",
7288
- children: [widget.icon && /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7289
- icon: resolveIcon(widget.icon),
7290
- fixedWidth: true,
7291
- className: "text-gray-400 text-sm"
7322
+ className: "flex flex-col items-center text-center gap-2",
7323
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
7324
+ className: "relative",
7325
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
7326
+ className: "text-2xl",
7327
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7328
+ icon: resolveIcon(dash.icon || "grid-2"),
7329
+ fixedWidth: true,
7330
+ className: "text-gray-400"
7331
+ })
7332
+ }), isSelected && /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7333
+ icon: "circle-check",
7334
+ className: "absolute -top-1 -right-3 text-blue-400 text-xs"
7335
+ })]
7292
7336
  }), /*#__PURE__*/jsxRuntime.jsx("span", {
7293
- className: "text-sm font-medium text-gray-200 truncate",
7294
- children: widget.name
7337
+ className: "text-sm font-semibold text-gray-200",
7338
+ children: dash.displayName || dash.name
7339
+ })]
7340
+ }), dash.description && /*#__PURE__*/jsxRuntime.jsx("p", {
7341
+ className: "text-xs text-gray-400 mt-2 line-clamp-2 text-center",
7342
+ children: dash.description
7343
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
7344
+ className: "flex items-center justify-between mt-3 pt-2 border-t border-gray-700/50",
7345
+ children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
7346
+ className: "text-xs text-gray-500",
7347
+ children: [widgetCount, " widget", widgetCount !== 1 ? "s" : ""]
7348
+ }), providerTags.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
7349
+ className: "flex flex-wrap gap-1 justify-end",
7350
+ children: providerTags.slice(0, 3).map(function (tag) {
7351
+ return /*#__PURE__*/jsxRuntime.jsx("span", {
7352
+ className: "text-xs px-1.5 py-0.5 rounded bg-gray-800 text-gray-400",
7353
+ children: tag
7354
+ }, tag);
7355
+ })
7295
7356
  })]
7296
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7297
- icon: checked ? "square-check" : "square",
7298
- fixedWidth: true,
7299
- className: checked ? "text-blue-400 flex-shrink-0" : "text-gray-500 flex-shrink-0"
7300
7357
  })]
7301
- }), widget.description && /*#__PURE__*/jsxRuntime.jsx("p", {
7302
- className: "text-xs text-gray-400 line-clamp-2 mt-1.5 flex-1",
7303
- children: widget.description
7304
- }), widget.packageDisplayName && /*#__PURE__*/jsxRuntime.jsx("span", {
7305
- className: "text-xs text-gray-500 mt-2 pt-1.5 border-t border-gray-700/50 truncate",
7306
- children: widget.packageDisplayName
7307
- })]
7308
- }, widget.key);
7358
+ }, dash.name);
7359
+ })
7360
+ })
7361
+ }), showWidgets && visibleWidgets.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
7362
+ className: "flex flex-col gap-3",
7363
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
7364
+ className: "grid grid-cols-3 gap-3",
7365
+ children: visibleWidgets.map(function (widget) {
7366
+ var checked = isWidgetSelected(widget);
7367
+ return /*#__PURE__*/jsxRuntime.jsxs(DashReact.Card2, {
7368
+ hover: true,
7369
+ selected: checked,
7370
+ padding: "p-4",
7371
+ rounded: "rounded-lg",
7372
+ className: "hover:shadow-lg flex flex-col",
7373
+ onClick: function onClick() {
7374
+ return handleToggleWidget(widget);
7375
+ },
7376
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
7377
+ className: "flex items-start justify-between gap-2",
7378
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
7379
+ className: "flex items-center gap-1.5",
7380
+ children: [widget.icon && /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7381
+ icon: resolveIcon(widget.icon),
7382
+ fixedWidth: true,
7383
+ className: "text-gray-400 text-sm"
7384
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
7385
+ className: "text-sm font-medium text-gray-200 truncate",
7386
+ children: widget.name
7387
+ })]
7388
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7389
+ icon: checked ? "square-check" : "square",
7390
+ fixedWidth: true,
7391
+ className: checked ? "text-blue-400 flex-shrink-0" : "text-gray-500 flex-shrink-0"
7392
+ })]
7393
+ }), widget.description && /*#__PURE__*/jsxRuntime.jsx("p", {
7394
+ className: "text-xs text-gray-400 line-clamp-2 mt-1.5 flex-1",
7395
+ children: widget.description
7396
+ }), widget.packageDisplayName && /*#__PURE__*/jsxRuntime.jsx("span", {
7397
+ className: "text-xs text-gray-500 mt-2 pt-1.5 border-t border-gray-700/50 truncate",
7398
+ children: widget.packageDisplayName
7399
+ })]
7400
+ }, widget.key);
7401
+ })
7309
7402
  })
7310
- })
7311
- }), activeTab === "widgets" && filteredWidgets.length === 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
7312
- className: "flex flex-col items-center justify-center gap-2 py-12 text-gray-500",
7313
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
7314
- icon: "puzzle-piece",
7315
- fixedWidth: true
7316
- }), /*#__PURE__*/jsxRuntime.jsx("p", {
7317
- children: "No widgets match your search."
7318
7403
  })]
7319
- })]
7320
- })
7404
+ })
7405
+ })]
7321
7406
  })]
7322
7407
  });
7323
7408
  };