@trops/dash-core 0.1.93 → 0.1.96

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
@@ -3080,7 +3080,7 @@ var LayoutManagerPicker = function LayoutManagerPicker(_ref2) {
3080
3080
  });
3081
3081
  };
3082
3082
 
3083
- var FOLDER_ICONS = [
3083
+ var FOLDER_ICONS$1 = [
3084
3084
  // General / UI
3085
3085
  "home", "folder", "star", "heart", "bookmark", "tag", "flag", "bell", "circle", "square", "circle-check", "thumbs-up", "clone", "signal",
3086
3086
  // Communication
@@ -3103,7 +3103,7 @@ var FOLDER_ICONS = [
3103
3103
  "file", "file-code", "clipboard", "book", "pen", "pencil",
3104
3104
  // Misc
3105
3105
  "magnifying-glass", "eye", "lock", "key", "shield", "clock", "calendar", "link"];
3106
- var ALL_ICON_NAMES = Object.keys(DashReact__namespace).filter(function (key) {
3106
+ var ALL_ICON_NAMES$1 = Object.keys(DashReact__namespace).filter(function (key) {
3107
3107
  return key.startsWith("fa") && key !== "fas";
3108
3108
  }).map(function (key) {
3109
3109
  var _DashReact$key;
@@ -3111,8 +3111,8 @@ var ALL_ICON_NAMES = Object.keys(DashReact__namespace).filter(function (key) {
3111
3111
  }).filter(Boolean).filter(function (name, index, arr) {
3112
3112
  return arr.indexOf(name) === index;
3113
3113
  }).sort();
3114
- var CURATED_SET = new Set(FOLDER_ICONS);
3115
- var IconPicker = function IconPicker(_ref) {
3114
+ var CURATED_SET$1 = new Set(FOLDER_ICONS$1);
3115
+ var IconPicker$1 = function IconPicker(_ref) {
3116
3116
  var selectedIcon = _ref.selectedIcon,
3117
3117
  onSelectIcon = _ref.onSelectIcon;
3118
3118
  var _useState = React.useState(""),
@@ -3121,13 +3121,13 @@ var IconPicker = function IconPicker(_ref) {
3121
3121
  setSearch = _useState2[1];
3122
3122
  var query = search.trim().toLowerCase();
3123
3123
  var filteredCurated = React.useMemo(function () {
3124
- return query ? FOLDER_ICONS.filter(function (name) {
3124
+ return query ? FOLDER_ICONS$1.filter(function (name) {
3125
3125
  return name.includes(query);
3126
- }) : FOLDER_ICONS;
3126
+ }) : FOLDER_ICONS$1;
3127
3127
  }, [query]);
3128
3128
  var remainingIcons = React.useMemo(function () {
3129
- var all = ALL_ICON_NAMES.filter(function (name) {
3130
- return !CURATED_SET.has(name);
3129
+ var all = ALL_ICON_NAMES$1.filter(function (name) {
3130
+ return !CURATED_SET$1.has(name);
3131
3131
  });
3132
3132
  return query ? all.filter(function (name) {
3133
3133
  return name.includes(query);
@@ -3228,7 +3228,7 @@ var FolderDetail = function FolderDetail(_ref2) {
3228
3228
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
3229
3229
  className: "flex-shrink-0 text-sm font-medium opacity-70",
3230
3230
  children: "Icon"
3231
- }), /*#__PURE__*/jsxRuntime.jsx(IconPicker, {
3231
+ }), /*#__PURE__*/jsxRuntime.jsx(IconPicker$1, {
3232
3232
  selectedIcon: formIcon,
3233
3233
  onSelectIcon: setFormIcon
3234
3234
  })]
@@ -3519,7 +3519,7 @@ var LayoutManagerModal = function LayoutManagerModal(_ref) {
3519
3519
  placeholder: "Folder name"
3520
3520
  }), /*#__PURE__*/jsxRuntime.jsx("div", {
3521
3521
  className: "grid grid-cols-10 gap-2",
3522
- children: FOLDER_ICONS.map(function (icon) {
3522
+ children: FOLDER_ICONS$1.map(function (icon) {
3523
3523
  var isIconSelected = icon === newFolderIcon;
3524
3524
  return /*#__PURE__*/jsxRuntime.jsx("div", {
3525
3525
  className: "flex items-center justify-center p-2 rounded cursor-pointer transition-all ".concat(isIconSelected ? "bg-blue-600 ring-2 ring-blue-400 text-white" : "bg-gray-700 text-gray-400 hover:bg-gray-600 hover:text-gray-200"),
@@ -26384,236 +26384,1378 @@ var ThemeManagerModal = function ThemeManagerModal(_ref) {
26384
26384
  });
26385
26385
  };
26386
26386
 
26387
- function ownKeys$8(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
26388
- function _objectSpread$8(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$8(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$8(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
26389
- var LayoutPreview = function LayoutPreview(_ref) {
26390
- var layout = _ref.layout;
26391
- var gridRoot = (layout || []).find(function (item) {
26392
- return item.component === "LayoutGridContainer";
26393
- });
26394
- var grid = (gridRoot === null || gridRoot === void 0 ? void 0 : gridRoot.grid) || null;
26395
- if (!grid || !grid.rows || !grid.cols) return null;
26396
-
26397
- // Build preview cells from grid keys (e.g. "1.1", "2.3")
26398
- var previewCells = [];
26399
- for (var r = 1; r <= grid.rows; r++) {
26400
- for (var c = 1; c <= grid.cols; c++) {
26401
- var _cell$span, _cell$span2;
26402
- var key = "".concat(r, ".").concat(c);
26403
- var cell = grid[key];
26404
- if (!cell || cell.hide) continue;
26405
- var colSpan = ((_cell$span = cell.span) === null || _cell$span === void 0 ? void 0 : _cell$span.col) || undefined;
26406
- var rowSpan = ((_cell$span2 = cell.span) === null || _cell$span2 === void 0 ? void 0 : _cell$span2.row) || undefined;
26407
- previewCells.push({
26408
- row: r,
26409
- col: c,
26410
- colSpan: colSpan,
26411
- rowSpan: rowSpan
26412
- });
26413
- }
26414
- }
26415
- if (previewCells.length === 0) return null;
26416
- return /*#__PURE__*/jsxRuntime.jsx("div", {
26417
- className: "flex-1 min-h-0 w-full rounded bg-white/5 border border-white/10 p-2 overflow-hidden",
26418
- style: {
26419
- display: "grid",
26420
- gridTemplateRows: "repeat(".concat(grid.rows, ", 1fr)"),
26421
- gridTemplateColumns: "repeat(".concat(grid.cols, ", 1fr)"),
26422
- gap: "4px"
26423
- },
26424
- children: previewCells.map(function (cell, i) {
26425
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
26426
- className: "rounded-sm overflow-hidden border border-white/10 bg-white/5",
26427
- style: {
26428
- gridColumn: cell.colSpan ? "span ".concat(cell.colSpan) : undefined,
26429
- gridRow: cell.rowSpan ? "span ".concat(cell.rowSpan) : undefined
26430
- },
26431
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
26432
- className: "h-1.5 bg-white/10"
26433
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26434
- className: "p-1 space-y-0.5",
26435
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
26436
- className: "h-0.5 w-3/4 rounded-full bg-white/5"
26437
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
26438
- className: "h-0.5 w-1/2 rounded-full bg-white/5"
26439
- })]
26440
- })]
26441
- }, i);
26442
- })
26443
- });
26444
- };
26445
- var DashboardDetail = function DashboardDetail(_ref2) {
26446
- var workspace = _ref2.workspace,
26447
- _ref2$menuItems = _ref2.menuItems,
26448
- menuItems = _ref2$menuItems === void 0 ? [] : _ref2$menuItems,
26449
- editingId = _ref2.editingId,
26450
- editName = _ref2.editName,
26451
- setEditName = _ref2.setEditName,
26452
- onStartRename = _ref2.onStartRename,
26453
- onSaveRename = _ref2.onSaveRename,
26454
- onCancelRename = _ref2.onCancelRename,
26455
- onDuplicate = _ref2.onDuplicate,
26456
- onDelete = _ref2.onDelete,
26457
- _ref2$dashApi = _ref2.dashApi,
26458
- dashApi = _ref2$dashApi === void 0 ? null : _ref2$dashApi,
26459
- _ref2$credentials = _ref2.credentials,
26460
- credentials = _ref2$credentials === void 0 ? null : _ref2$credentials,
26461
- _ref2$onReloadWorkspa = _ref2.onReloadWorkspaces,
26462
- onReloadWorkspaces = _ref2$onReloadWorkspa === void 0 ? null : _ref2$onReloadWorkspa;
26463
- var ws = workspace;
26464
- var isEditing = editingId === ws.id;
26465
- var widgetCount = (ws.layout || []).length;
26466
- var appId = credentials === null || credentials === void 0 ? void 0 : credentials.appId;
26387
+ var StarRating = function StarRating(_ref) {
26388
+ var appId = _ref.appId,
26389
+ packageName = _ref.packageName,
26390
+ _ref$interactive = _ref.interactive,
26391
+ interactive = _ref$interactive === void 0 ? true : _ref$interactive;
26467
26392
  var _useContext = React.useContext(DashReact.ThemeContext),
26468
- themes = _useContext.themes;
26469
- var folderOptions = menuItems.map(function (m) {
26470
- return {
26471
- label: m.name,
26472
- value: String(m.id)
26473
- };
26474
- });
26475
- var themeOptions = [{
26476
- label: "App Default",
26477
- value: ""
26478
- }].concat(_toConsumableArray(Object.entries(themes || {}).map(function (_ref3) {
26479
- var _ref4 = _slicedToArray(_ref3, 2),
26480
- key = _ref4[0],
26481
- t = _ref4[1];
26482
- return {
26483
- label: t.name || key,
26484
- value: key
26485
- };
26486
- })));
26487
- function handleChangeFolder(val) {
26488
- if (!dashApi || !appId) return;
26489
- var updated = DashReact.deepCopy(ws);
26490
- updated.menuId = val ? Number(val) : null;
26491
- // Strip widgetConfig from layout before saving
26492
- updated.layout = (updated.layout || []).map(function (layoutItem) {
26493
- var cleaned = _objectSpread$8({}, layoutItem);
26494
- delete cleaned.widgetConfig;
26495
- return cleaned;
26496
- });
26497
- dashApi.saveWorkspace(appId, updated, function () {
26498
- onReloadWorkspaces && onReloadWorkspaces();
26499
- }, function (e, err) {
26500
- return (void 0);
26393
+ currentTheme = _useContext.currentTheme;
26394
+ var _useState = React.useState(0),
26395
+ _useState2 = _slicedToArray(_useState, 2),
26396
+ rating = _useState2[0],
26397
+ setRating = _useState2[1];
26398
+ var _useState3 = React.useState(0),
26399
+ _useState4 = _slicedToArray(_useState3, 2),
26400
+ hoverRating = _useState4[0],
26401
+ setHoverRating = _useState4[1];
26402
+ var _useState5 = React.useState(true),
26403
+ _useState6 = _slicedToArray(_useState5, 2),
26404
+ loading = _useState6[0],
26405
+ setLoading = _useState6[1];
26406
+ React.useEffect(function () {
26407
+ var _window$mainApi;
26408
+ if (!appId || !packageName) return;
26409
+ var cancelled = false;
26410
+ setLoading(true);
26411
+ (_window$mainApi = window.mainApi) === null || _window$mainApi === void 0 || (_window$mainApi = _window$mainApi.dashboardRatings) === null || _window$mainApi === void 0 || _window$mainApi.getDashboardRating(appId, packageName).then(function (result) {
26412
+ if (!cancelled && result !== null && result !== void 0 && result.rating) {
26413
+ setRating(result.rating);
26414
+ }
26415
+ })["catch"](function () {})["finally"](function () {
26416
+ if (!cancelled) setLoading(false);
26501
26417
  });
26418
+ return function () {
26419
+ cancelled = true;
26420
+ };
26421
+ }, [appId, packageName]);
26422
+ function handleClick(_x) {
26423
+ return _handleClick.apply(this, arguments);
26502
26424
  }
26503
- function handleChangeTheme(val) {
26504
- if (!dashApi || !appId) return;
26505
- var updated = DashReact.deepCopy(ws);
26506
- updated.themeKey = val || null;
26507
- updated.layout = (updated.layout || []).map(function (layoutItem) {
26508
- var cleaned = _objectSpread$8({}, layoutItem);
26509
- delete cleaned.widgetConfig;
26510
- return cleaned;
26511
- });
26512
- dashApi.saveWorkspace(appId, updated, function () {
26513
- onReloadWorkspaces && onReloadWorkspaces();
26514
- }, function (e, err) {
26515
- return (void 0);
26516
- });
26425
+ function _handleClick() {
26426
+ _handleClick = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(value) {
26427
+ var newRating, _window$mainApi2;
26428
+ return _regeneratorRuntime.wrap(function (_context) {
26429
+ while (1) switch (_context.prev = _context.next) {
26430
+ case 0:
26431
+ if (!(!interactive || !appId || !packageName)) {
26432
+ _context.next = 1;
26433
+ break;
26434
+ }
26435
+ return _context.abrupt("return");
26436
+ case 1:
26437
+ newRating = value === rating ? 0 : value;
26438
+ setRating(newRating);
26439
+ _context.prev = 2;
26440
+ _context.next = 3;
26441
+ return (_window$mainApi2 = window.mainApi) === null || _window$mainApi2 === void 0 || (_window$mainApi2 = _window$mainApi2.dashboardRatings) === null || _window$mainApi2 === void 0 ? void 0 : _window$mainApi2.saveDashboardRating(appId, packageName, newRating);
26442
+ case 3:
26443
+ _context.next = 5;
26444
+ break;
26445
+ case 4:
26446
+ _context.prev = 4;
26447
+ _context["catch"](2);
26448
+ case 5:
26449
+ case "end":
26450
+ return _context.stop();
26451
+ }
26452
+ }, _callee, null, [[2, 4]]);
26453
+ }));
26454
+ return _handleClick.apply(this, arguments);
26517
26455
  }
26518
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
26519
- className: "flex flex-col flex-1 min-h-0",
26520
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
26521
- className: "flex flex-col flex-1 min-h-0 overflow-y-auto p-6 gap-6",
26522
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
26523
- className: "flex-shrink-0 flex flex-row items-center justify-between",
26524
- children: isEditing ? /*#__PURE__*/jsxRuntime.jsxs("div", {
26525
- className: "flex flex-row items-center gap-2 flex-1",
26526
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
26527
- value: editName,
26528
- onChange: function onChange(value) {
26529
- return setEditName(value);
26530
- },
26531
- placeholder: "Dashboard name",
26532
- className: "flex-1"
26533
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.ButtonIcon, {
26534
- icon: "check",
26535
- onClick: function onClick() {
26536
- return onSaveRename(ws);
26537
- },
26538
- size: "sm"
26539
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.ButtonIcon, {
26540
- icon: "xmark",
26541
- onClick: onCancelRename,
26542
- size: "sm"
26543
- })]
26544
- }) : /*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading, {
26545
- title: ws.name || "Untitled",
26546
- padding: false
26547
- })
26548
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26549
- className: "flex-shrink-0 flex flex-col space-y-3",
26550
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SelectInput, {
26551
- label: "Folder",
26552
- value: String(ws.menuId || ""),
26553
- onChange: function onChange(val) {
26554
- return handleChangeFolder(val);
26555
- },
26556
- options: folderOptions,
26557
- placeholder: "No folder"
26558
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.SelectInput, {
26559
- label: "Theme",
26560
- value: ws.themeKey || "",
26561
- onChange: function onChange(val) {
26562
- return handleChangeTheme(val);
26563
- },
26564
- options: themeOptions,
26565
- placeholder: "App Default"
26566
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26567
- className: "flex flex-row items-center gap-2",
26568
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26569
- icon: "th-large",
26570
- className: "h-3 w-3 opacity-50"
26571
- }), /*#__PURE__*/jsxRuntime.jsxs("span", {
26572
- className: "text-sm opacity-70",
26573
- children: [widgetCount, " widget", widgetCount !== 1 ? "s" : ""]
26574
- })]
26575
- })]
26576
- }), /*#__PURE__*/jsxRuntime.jsx(LayoutPreview, {
26577
- layout: ws.layout
26578
- })]
26579
- }), !isEditing && /*#__PURE__*/jsxRuntime.jsxs("div", {
26580
- className: "flex-shrink-0 flex flex-row justify-end gap-2 px-6 py-4 border-t border-white/10",
26581
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
26582
- title: "Rename",
26583
- onClick: function onClick() {
26584
- return onStartRename(ws);
26585
- },
26586
- size: "sm"
26587
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
26588
- title: "Duplicate",
26456
+ if (loading) return null;
26457
+ var displayRating = hoverRating || rating;
26458
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
26459
+ className: "flex items-center gap-0.5",
26460
+ onMouseLeave: function onMouseLeave() {
26461
+ return setHoverRating(0);
26462
+ },
26463
+ children: [1, 2, 3, 4, 5].map(function (star) {
26464
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
26465
+ type: "button",
26466
+ disabled: !interactive,
26589
26467
  onClick: function onClick() {
26590
- return onDuplicate(ws);
26468
+ return handleClick(star);
26591
26469
  },
26592
- size: "sm"
26593
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
26594
- title: "Delete",
26595
- onClick: function onClick() {
26596
- return onDelete(ws);
26470
+ onMouseEnter: function onMouseEnter() {
26471
+ return interactive && setHoverRating(star);
26597
26472
  },
26598
- size: "sm"
26599
- })]
26600
- })]
26473
+ className: "p-0.5 transition-colors ".concat(interactive ? "cursor-pointer hover:scale-110" : "cursor-default"),
26474
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26475
+ icon: star <= displayRating ? "star" : ["far", "star"],
26476
+ className: "h-3.5 w-3.5 ".concat(star <= displayRating ? "text-yellow-400" : currentTheme["text-primary-medium"] || "text-gray-500")
26477
+ })
26478
+ }, star);
26479
+ })
26601
26480
  });
26602
26481
  };
26603
26482
 
26604
- function ownKeys$7(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
26605
- function _objectSpread$7(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$7(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$7(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
26606
- var DashboardsSection = function DashboardsSection(_ref) {
26607
- var _ref$workspaces = _ref.workspaces,
26608
- workspaces = _ref$workspaces === void 0 ? [] : _ref$workspaces,
26609
- _ref$menuItems = _ref.menuItems,
26483
+ var FOLDER_ICONS = [
26484
+ // General / UI
26485
+ "home", "folder", "star", "heart", "bookmark", "tag", "flag", "bell", "circle", "square", "circle-check", "thumbs-up", "clone", "signal",
26486
+ // Communication
26487
+ "phone", "envelope", "comment", "message", "paper-plane",
26488
+ // Media
26489
+ "image", "camera", "music", "video", "film", "headphones",
26490
+ // Tech
26491
+ "code", "terminal", "database", "server", "wifi", "plug", "robot", "microchip", "globe",
26492
+ // Nature
26493
+ "leaf", "seedling", "tree", "sun", "moon", "cloud", "bolt", "fire", "snowflake", "water",
26494
+ // Objects
26495
+ "hammer", "wrench", "gear", "briefcase", "cart-shopping", "truck", "car", "plane", "rocket",
26496
+ // People / Activity
26497
+ "user", "users", "trophy", "gamepad", "dumbbell", "graduation-cap", "baby", "baby-carriage",
26498
+ // Arrows / Navigation
26499
+ "arrow-up", "arrow-down", "arrow-left", "arrow-right", "arrows-up-down", "arrows-left-right", "minus",
26500
+ // Data / Charts
26501
+ "chart-bar", "chart-line", "chart-pie", "table", "list", "layer-group",
26502
+ // Files
26503
+ "file", "file-code", "clipboard", "book", "pen", "pencil",
26504
+ // Misc
26505
+ "magnifying-glass", "eye", "lock", "key", "shield", "clock", "calendar", "link"];
26506
+ var ALL_ICON_NAMES = Object.keys(DashReact__namespace).filter(function (key) {
26507
+ return key.startsWith("fa") && key !== "fas";
26508
+ }).map(function (key) {
26509
+ var _DashReact$key;
26510
+ return (_DashReact$key = DashReact__namespace[key]) === null || _DashReact$key === void 0 ? void 0 : _DashReact$key.iconName;
26511
+ }).filter(Boolean).filter(function (name, index, arr) {
26512
+ return arr.indexOf(name) === index;
26513
+ }).sort();
26514
+ var CURATED_SET = new Set(FOLDER_ICONS);
26515
+ var IconPicker = function IconPicker(_ref) {
26516
+ var selectedIcon = _ref.selectedIcon,
26517
+ onSelectIcon = _ref.onSelectIcon;
26518
+ var _useState = React.useState(""),
26519
+ _useState2 = _slicedToArray(_useState, 2),
26520
+ search = _useState2[0],
26521
+ setSearch = _useState2[1];
26522
+ var query = search.trim().toLowerCase();
26523
+ var filteredCurated = React.useMemo(function () {
26524
+ return query ? FOLDER_ICONS.filter(function (name) {
26525
+ return name.includes(query);
26526
+ }) : FOLDER_ICONS;
26527
+ }, [query]);
26528
+ var remainingIcons = React.useMemo(function () {
26529
+ var all = ALL_ICON_NAMES.filter(function (name) {
26530
+ return !CURATED_SET.has(name);
26531
+ });
26532
+ return query ? all.filter(function (name) {
26533
+ return name.includes(query);
26534
+ }) : all;
26535
+ }, [query]);
26536
+ var hasResults = filteredCurated.length > 0 || remainingIcons.length > 0;
26537
+ var renderIcon = function renderIcon(icon) {
26538
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.ButtonIcon, {
26539
+ icon: icon,
26540
+ selected: icon === selectedIcon,
26541
+ onClick: function onClick() {
26542
+ return onSelectIcon(icon);
26543
+ },
26544
+ iconSize: "h-6 w-6",
26545
+ backgroundColor: "transparent",
26546
+ className: icon !== selectedIcon ? "opacity-50 hover:!opacity-80" : ""
26547
+ }, icon);
26548
+ };
26549
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
26550
+ className: "flex flex-col flex-1 min-h-0 space-y-3",
26551
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
26552
+ className: "flex-shrink-0",
26553
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.SearchInput, {
26554
+ value: search,
26555
+ onChange: setSearch,
26556
+ placeholder: "Search icons..."
26557
+ })
26558
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26559
+ className: "flex-1 min-h-0 overflow-y-auto space-y-3",
26560
+ children: [!hasResults && /*#__PURE__*/jsxRuntime.jsxs("span", {
26561
+ className: "text-sm opacity-50 py-2",
26562
+ children: ["No icons match \"", search, "\""]
26563
+ }), filteredCurated.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
26564
+ className: "flex flex-col space-y-1.5",
26565
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26566
+ className: "text-xs font-medium opacity-50",
26567
+ children: "Suggested"
26568
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
26569
+ className: "grid grid-cols-6 gap-2",
26570
+ children: filteredCurated.map(renderIcon)
26571
+ })]
26572
+ }), remainingIcons.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
26573
+ className: "flex flex-col space-y-1.5",
26574
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26575
+ className: "text-xs font-medium opacity-50",
26576
+ children: "All Icons"
26577
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
26578
+ className: "grid grid-cols-6 gap-2",
26579
+ children: remainingIcons.map(renderIcon)
26580
+ })]
26581
+ })]
26582
+ })]
26583
+ });
26584
+ };
26585
+
26586
+ var DASHBOARD_TAGS = ["productivity", "monitoring", "analytics", "communication", "developer", "sales", "marketing", "finance", "project-management", "social", "news", "utilities"];
26587
+
26588
+ /**
26589
+ * PublishDashboardModal — multi-step stepper for preparing a dashboard
26590
+ * for registry publishing.
26591
+ *
26592
+ * Steps:
26593
+ * 1. Details — Author name (required) + description (textarea)
26594
+ * 2. Tags — Predefined tag selection with toggle-pill styling
26595
+ * 3. Icon — Full icon picker with search
26596
+ * 4. Publish — Review summary, publish action, result display
26597
+ */
26598
+ var PublishDashboardModal = function PublishDashboardModal(_ref) {
26599
+ var isOpen = _ref.isOpen,
26600
+ setIsOpen = _ref.setIsOpen,
26601
+ appId = _ref.appId,
26602
+ workspaceId = _ref.workspaceId,
26603
+ workspaceName = _ref.workspaceName;
26604
+ var _useContext = React.useContext(DashReact.ThemeContext),
26605
+ currentTheme = _useContext.currentTheme;
26606
+ var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
26607
+ grow: false
26608
+ });
26609
+ // Stepper state
26610
+ var _useState = React.useState(0),
26611
+ _useState2 = _slicedToArray(_useState, 2),
26612
+ step = _useState2[0],
26613
+ setStep = _useState2[1];
26614
+
26615
+ // Step 1: Details
26616
+ var _useState3 = React.useState(""),
26617
+ _useState4 = _slicedToArray(_useState3, 2),
26618
+ authorName = _useState4[0],
26619
+ setAuthorName = _useState4[1];
26620
+ var _useState5 = React.useState(""),
26621
+ _useState6 = _slicedToArray(_useState5, 2),
26622
+ description = _useState6[0],
26623
+ setDescription = _useState6[1];
26624
+
26625
+ // Step 2: Tags
26626
+ var _useState7 = React.useState([]),
26627
+ _useState8 = _slicedToArray(_useState7, 2),
26628
+ selectedTags = _useState8[0],
26629
+ setSelectedTags = _useState8[1];
26630
+
26631
+ // Step 3: Icon
26632
+ var _useState9 = React.useState("grip"),
26633
+ _useState0 = _slicedToArray(_useState9, 2),
26634
+ icon = _useState0[0],
26635
+ setIcon = _useState0[1];
26636
+
26637
+ // Step 4: Publish
26638
+ var _useState1 = React.useState(false),
26639
+ _useState10 = _slicedToArray(_useState1, 2),
26640
+ isPublishing = _useState10[0],
26641
+ setIsPublishing = _useState10[1];
26642
+ var _useState11 = React.useState(null),
26643
+ _useState12 = _slicedToArray(_useState11, 2),
26644
+ result = _useState12[0],
26645
+ setResult = _useState12[1];
26646
+ function resetState() {
26647
+ setStep(0);
26648
+ setAuthorName("");
26649
+ setDescription("");
26650
+ setSelectedTags([]);
26651
+ setIcon("grip");
26652
+ setIsPublishing(false);
26653
+ setResult(null);
26654
+ }
26655
+ function handleClose() {
26656
+ setIsOpen(false);
26657
+ setTimeout(resetState, 200);
26658
+ }
26659
+ function handleStepChange(nextStep) {
26660
+ if (step === 0 && nextStep > 0 && !authorName.trim()) return;
26661
+ if (step === 1 && nextStep > 1 && selectedTags.length === 0) return;
26662
+ setStep(nextStep);
26663
+ }
26664
+ function toggleTag(tag) {
26665
+ setSelectedTags(function (prev) {
26666
+ return prev.includes(tag) ? prev.filter(function (t) {
26667
+ return t !== tag;
26668
+ }) : [].concat(_toConsumableArray(prev), [tag]);
26669
+ });
26670
+ }
26671
+ function handlePublish() {
26672
+ return _handlePublish.apply(this, arguments);
26673
+ }
26674
+ function _handlePublish() {
26675
+ _handlePublish = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
26676
+ var options, res, _t;
26677
+ return _regeneratorRuntime.wrap(function (_context) {
26678
+ while (1) switch (_context.prev = _context.next) {
26679
+ case 0:
26680
+ if (!(!appId || !workspaceId)) {
26681
+ _context.next = 1;
26682
+ break;
26683
+ }
26684
+ return _context.abrupt("return");
26685
+ case 1:
26686
+ setIsPublishing(true);
26687
+ setResult(null);
26688
+ _context.prev = 2;
26689
+ options = {
26690
+ authorName: authorName.trim(),
26691
+ description: description.trim() || undefined,
26692
+ tags: selectedTags,
26693
+ icon: icon || undefined
26694
+ };
26695
+ _context.next = 3;
26696
+ return window.mainApi.dashboardConfig.prepareDashboardForPublish(appId, workspaceId, options);
26697
+ case 3:
26698
+ res = _context.sent;
26699
+ setResult(res);
26700
+ _context.next = 5;
26701
+ break;
26702
+ case 4:
26703
+ _context.prev = 4;
26704
+ _t = _context["catch"](2);
26705
+ setResult({
26706
+ success: false,
26707
+ error: _t.message || "Failed to prepare dashboard for publish."
26708
+ });
26709
+ case 5:
26710
+ _context.prev = 5;
26711
+ setIsPublishing(false);
26712
+ return _context.finish(5);
26713
+ case 6:
26714
+ case "end":
26715
+ return _context.stop();
26716
+ }
26717
+ }, _callee, null, [[2, 4, 5, 6]]);
26718
+ }));
26719
+ return _handlePublish.apply(this, arguments);
26720
+ }
26721
+ var isLastStep = step === 3;
26722
+ var canAdvance = step === 0 ? !!authorName.trim() : step === 1 ? selectedTags.length > 0 : true;
26723
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Modal, {
26724
+ isOpen: isOpen,
26725
+ setIsOpen: handleClose,
26726
+ width: "w-full max-w-2xl",
26727
+ height: "h-[70vh]",
26728
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26729
+ className: "flex flex-col h-full rounded-lg overflow-clip border ".concat(panelStyles.backgroundColor || "", " ").concat(panelStyles.borderColor || "", " ").concat(panelStyles.textColor || ""),
26730
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
26731
+ className: "flex-shrink-0 flex flex-row items-center justify-between p-4 border-b border-white/10",
26732
+ children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
26733
+ className: "text-lg font-semibold",
26734
+ children: ["Publish \"", workspaceName || "Dashboard", "\""]
26735
+ }), /*#__PURE__*/jsxRuntime.jsx("button", {
26736
+ type: "button",
26737
+ onClick: handleClose,
26738
+ className: "opacity-50 hover:opacity-100 transition-opacity cursor-pointer",
26739
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26740
+ icon: "xmark",
26741
+ className: "h-5 w-5"
26742
+ })
26743
+ })]
26744
+ }), /*#__PURE__*/jsxRuntime.jsxs(DashReact.Stepper, {
26745
+ activeStep: step,
26746
+ onStepChange: handleStepChange,
26747
+ showNavigation: false,
26748
+ className: "flex-1 min-h-0 flex flex-col px-6 pt-2",
26749
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
26750
+ label: "Details",
26751
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26752
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
26753
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
26754
+ className: "text-sm opacity-70",
26755
+ children: "Provide details about your dashboard for the registry listing."
26756
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
26757
+ label: "Author Name *",
26758
+ value: authorName,
26759
+ onChange: setAuthorName,
26760
+ placeholder: "Your name"
26761
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.TextArea, {
26762
+ label: "Description",
26763
+ value: description,
26764
+ onChange: setDescription,
26765
+ placeholder: "A brief description of this dashboard...",
26766
+ rows: 3
26767
+ })]
26768
+ })
26769
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
26770
+ label: "Tags",
26771
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26772
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
26773
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
26774
+ className: "text-sm opacity-70",
26775
+ children: "Select at least one tag to categorize your dashboard."
26776
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
26777
+ className: "grid grid-cols-3 gap-2",
26778
+ children: DASHBOARD_TAGS.map(function (tag) {
26779
+ var isSelected = selectedTags.includes(tag);
26780
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
26781
+ type: "button",
26782
+ onClick: function onClick() {
26783
+ return toggleTag(tag);
26784
+ },
26785
+ className: "px-3 py-1.5 rounded-full text-sm border transition-colors cursor-pointer ".concat(isSelected ? "bg-white/15 border-white/30 text-white" : "bg-transparent border-white/10 text-white/60 hover:border-white/20 hover:text-white/80"),
26786
+ children: tag
26787
+ }, tag);
26788
+ })
26789
+ })]
26790
+ })
26791
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
26792
+ label: "Icon",
26793
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
26794
+ className: "flex-1 min-h-0 flex flex-col pb-4",
26795
+ children: /*#__PURE__*/jsxRuntime.jsx(IconPicker, {
26796
+ selectedIcon: icon,
26797
+ onSelectIcon: setIcon
26798
+ })
26799
+ })
26800
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
26801
+ label: "Publish",
26802
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
26803
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-4",
26804
+ children: !result ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
26805
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
26806
+ className: "text-sm opacity-70",
26807
+ children: "Review your dashboard details before publishing."
26808
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26809
+ className: "bg-white/5 border border-white/10 rounded-lg p-4 space-y-2 text-sm",
26810
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
26811
+ className: "flex gap-2",
26812
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26813
+ className: "opacity-50 w-20 flex-shrink-0",
26814
+ children: "Author"
26815
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26816
+ children: authorName
26817
+ })]
26818
+ }), description.trim() && /*#__PURE__*/jsxRuntime.jsxs("div", {
26819
+ className: "flex gap-2",
26820
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26821
+ className: "opacity-50 w-20 flex-shrink-0",
26822
+ children: "Description"
26823
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26824
+ children: description
26825
+ })]
26826
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26827
+ className: "flex gap-2",
26828
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26829
+ className: "opacity-50 w-20 flex-shrink-0",
26830
+ children: "Tags"
26831
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26832
+ children: selectedTags.length > 0 ? selectedTags.join(", ") : "None"
26833
+ })]
26834
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26835
+ className: "flex gap-2 items-center",
26836
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26837
+ className: "opacity-50 w-20 flex-shrink-0",
26838
+ children: "Icon"
26839
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26840
+ icon: icon || "grip",
26841
+ className: "h-4 w-4"
26842
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26843
+ className: "opacity-70",
26844
+ children: icon || "grip"
26845
+ })]
26846
+ })]
26847
+ })]
26848
+ }) : result.success ? /*#__PURE__*/jsxRuntime.jsxs("div", {
26849
+ className: "space-y-3",
26850
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
26851
+ className: "flex items-center gap-2",
26852
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26853
+ icon: "circle-check",
26854
+ className: "h-4 w-4 text-green-400"
26855
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26856
+ className: "text-sm",
26857
+ children: "Dashboard prepared for publishing."
26858
+ })]
26859
+ }), result.filePath && /*#__PURE__*/jsxRuntime.jsxs("div", {
26860
+ className: "text-xs opacity-50 break-all",
26861
+ children: ["Saved to: ", result.filePath]
26862
+ }), result.warnings && result.warnings.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
26863
+ className: "bg-amber-500/10 border border-amber-500/20 rounded-lg p-3 space-y-2",
26864
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
26865
+ className: "flex items-start gap-2",
26866
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26867
+ icon: "triangle-exclamation",
26868
+ className: "h-3.5 w-3.5 text-amber-400 mt-0.5 flex-shrink-0"
26869
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26870
+ className: "text-xs text-amber-300/90",
26871
+ children: "The following widgets are not currently on the registry. This may be intentional if they are private. Dashboards referencing these widgets can only be installed by users who already have them."
26872
+ })]
26873
+ }), /*#__PURE__*/jsxRuntime.jsx("ul", {
26874
+ className: "text-xs opacity-60 pl-5 list-disc space-y-0.5",
26875
+ children: result.warnings.map(function (w) {
26876
+ return /*#__PURE__*/jsxRuntime.jsx("li", {
26877
+ children: w
26878
+ }, w);
26879
+ })
26880
+ })]
26881
+ }), result.registryCheckFailed && /*#__PURE__*/jsxRuntime.jsx("div", {
26882
+ className: "bg-amber-500/10 border border-amber-500/20 rounded-lg p-3",
26883
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26884
+ className: "flex items-start gap-2",
26885
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26886
+ icon: "triangle-exclamation",
26887
+ className: "h-3.5 w-3.5 text-amber-400 mt-0.5 flex-shrink-0"
26888
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26889
+ className: "text-xs text-amber-300/90",
26890
+ children: "Unable to reach the registry to verify widget availability. Your dashboard was still prepared successfully."
26891
+ })]
26892
+ })
26893
+ })]
26894
+ }) : /*#__PURE__*/jsxRuntime.jsxs("div", {
26895
+ className: "flex items-center gap-2",
26896
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26897
+ icon: "circle-xmark",
26898
+ className: "h-4 w-4 text-red-400"
26899
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26900
+ className: "text-sm text-red-400",
26901
+ children: result.error || "Publish preparation failed."
26902
+ })]
26903
+ })
26904
+ })
26905
+ })]
26906
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26907
+ className: "flex-shrink-0 flex flex-row items-center px-6 py-4 border-t border-white/10",
26908
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
26909
+ className: "flex flex-row gap-2",
26910
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
26911
+ title: step === 0 ? "Cancel" : "Back",
26912
+ onClick: step === 0 ? handleClose : function () {
26913
+ return setStep(step - 1);
26914
+ },
26915
+ disabled: isPublishing
26916
+ })
26917
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
26918
+ className: "flex-1 text-center",
26919
+ children: /*#__PURE__*/jsxRuntime.jsxs("span", {
26920
+ className: "text-xs opacity-40",
26921
+ children: ["Step ", step + 1, " of 4"]
26922
+ })
26923
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
26924
+ className: "flex flex-row gap-2",
26925
+ children: result !== null && result !== void 0 && result.success ? /*#__PURE__*/jsxRuntime.jsx(DashReact.Button2, {
26926
+ title: "Done",
26927
+ onClick: handleClose
26928
+ }) : isLastStep ? /*#__PURE__*/jsxRuntime.jsx(DashReact.Button2, {
26929
+ title: isPublishing ? "Preparing..." : "Publish",
26930
+ onClick: handlePublish,
26931
+ disabled: isPublishing
26932
+ }) : /*#__PURE__*/jsxRuntime.jsx(DashReact.Button2, {
26933
+ title: "Next",
26934
+ onClick: function onClick() {
26935
+ return handleStepChange(step + 1);
26936
+ },
26937
+ disabled: !canAdvance
26938
+ })
26939
+ })]
26940
+ })]
26941
+ })
26942
+ });
26943
+ };
26944
+
26945
+ function ownKeys$8(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
26946
+ function _objectSpread$8(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$8(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$8(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
26947
+ var LayoutPreview = function LayoutPreview(_ref) {
26948
+ var layout = _ref.layout;
26949
+ var gridRoot = (layout || []).find(function (item) {
26950
+ return item.component === "LayoutGridContainer";
26951
+ });
26952
+ var grid = (gridRoot === null || gridRoot === void 0 ? void 0 : gridRoot.grid) || null;
26953
+ if (!grid || !grid.rows || !grid.cols) return null;
26954
+
26955
+ // Build preview cells from grid keys (e.g. "1.1", "2.3")
26956
+ var previewCells = [];
26957
+ for (var r = 1; r <= grid.rows; r++) {
26958
+ for (var c = 1; c <= grid.cols; c++) {
26959
+ var _cell$span, _cell$span2;
26960
+ var key = "".concat(r, ".").concat(c);
26961
+ var cell = grid[key];
26962
+ if (!cell || cell.hide) continue;
26963
+ var colSpan = ((_cell$span = cell.span) === null || _cell$span === void 0 ? void 0 : _cell$span.col) || undefined;
26964
+ var rowSpan = ((_cell$span2 = cell.span) === null || _cell$span2 === void 0 ? void 0 : _cell$span2.row) || undefined;
26965
+ previewCells.push({
26966
+ row: r,
26967
+ col: c,
26968
+ colSpan: colSpan,
26969
+ rowSpan: rowSpan
26970
+ });
26971
+ }
26972
+ }
26973
+ if (previewCells.length === 0) return null;
26974
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
26975
+ className: "flex-1 min-h-0 w-full rounded bg-white/5 border border-white/10 p-2 overflow-hidden",
26976
+ style: {
26977
+ display: "grid",
26978
+ gridTemplateRows: "repeat(".concat(grid.rows, ", 1fr)"),
26979
+ gridTemplateColumns: "repeat(".concat(grid.cols, ", 1fr)"),
26980
+ gap: "4px"
26981
+ },
26982
+ children: previewCells.map(function (cell, i) {
26983
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
26984
+ className: "rounded-sm overflow-hidden border border-white/10 bg-white/5",
26985
+ style: {
26986
+ gridColumn: cell.colSpan ? "span ".concat(cell.colSpan) : undefined,
26987
+ gridRow: cell.rowSpan ? "span ".concat(cell.rowSpan) : undefined
26988
+ },
26989
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
26990
+ className: "h-1.5 bg-white/10"
26991
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26992
+ className: "p-1 space-y-0.5",
26993
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
26994
+ className: "h-0.5 w-3/4 rounded-full bg-white/5"
26995
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
26996
+ className: "h-0.5 w-1/2 rounded-full bg-white/5"
26997
+ })]
26998
+ })]
26999
+ }, i);
27000
+ })
27001
+ });
27002
+ };
27003
+ var DashboardDetail = function DashboardDetail(_ref2) {
27004
+ var _ws$_dashboardConfig, _ws$_dashboardConfig2;
27005
+ var workspace = _ref2.workspace,
27006
+ _ref2$menuItems = _ref2.menuItems,
27007
+ menuItems = _ref2$menuItems === void 0 ? [] : _ref2$menuItems,
27008
+ editingId = _ref2.editingId,
27009
+ editName = _ref2.editName,
27010
+ setEditName = _ref2.setEditName,
27011
+ onStartRename = _ref2.onStartRename,
27012
+ onSaveRename = _ref2.onSaveRename,
27013
+ onCancelRename = _ref2.onCancelRename,
27014
+ onDuplicate = _ref2.onDuplicate,
27015
+ onDelete = _ref2.onDelete,
27016
+ _ref2$dashApi = _ref2.dashApi,
27017
+ dashApi = _ref2$dashApi === void 0 ? null : _ref2$dashApi,
27018
+ _ref2$credentials = _ref2.credentials,
27019
+ credentials = _ref2$credentials === void 0 ? null : _ref2$credentials,
27020
+ _ref2$onReloadWorkspa = _ref2.onReloadWorkspaces,
27021
+ onReloadWorkspaces = _ref2$onReloadWorkspa === void 0 ? null : _ref2$onReloadWorkspa;
27022
+ var ws = workspace;
27023
+ var isEditing = editingId === ws.id;
27024
+ var widgetCount = (ws.layout || []).length;
27025
+ var appId = credentials === null || credentials === void 0 ? void 0 : credentials.appId;
27026
+ var _useContext = React.useContext(DashReact.ThemeContext),
27027
+ themes = _useContext.themes;
27028
+ var _useState = React.useState(null),
27029
+ _useState2 = _slicedToArray(_useState, 2),
27030
+ exportStatus = _useState2[0],
27031
+ setExportStatus = _useState2[1];
27032
+ var _useState3 = React.useState(false),
27033
+ _useState4 = _slicedToArray(_useState3, 2),
27034
+ publishOpen = _useState4[0],
27035
+ setPublishOpen = _useState4[1];
27036
+ var registryPackage = (_ws$_dashboardConfig = ws._dashboardConfig) === null || _ws$_dashboardConfig === void 0 ? void 0 : _ws$_dashboardConfig.registryPackage;
27037
+ var isShareable = ((_ws$_dashboardConfig2 = ws._dashboardConfig) === null || _ws$_dashboardConfig2 === void 0 ? void 0 : _ws$_dashboardConfig2.shareable) !== false;
27038
+ function handleExport() {
27039
+ return _handleExport.apply(this, arguments);
27040
+ }
27041
+ function _handleExport() {
27042
+ _handleExport = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
27043
+ var result, _t;
27044
+ return _regeneratorRuntime.wrap(function (_context) {
27045
+ while (1) switch (_context.prev = _context.next) {
27046
+ case 0:
27047
+ if (appId) {
27048
+ _context.next = 1;
27049
+ break;
27050
+ }
27051
+ return _context.abrupt("return");
27052
+ case 1:
27053
+ setExportStatus({
27054
+ status: "loading"
27055
+ });
27056
+ _context.prev = 2;
27057
+ _context.next = 3;
27058
+ return window.mainApi.dashboardConfig.exportDashboardConfig(appId, ws.id, {});
27059
+ case 3:
27060
+ result = _context.sent;
27061
+ if (result !== null && result !== void 0 && result.success) {
27062
+ setExportStatus({
27063
+ status: "success",
27064
+ message: "Exported successfully."
27065
+ });
27066
+ } else {
27067
+ setExportStatus({
27068
+ status: "error",
27069
+ message: (result === null || result === void 0 ? void 0 : result.error) || "Export failed."
27070
+ });
27071
+ }
27072
+ _context.next = 5;
27073
+ break;
27074
+ case 4:
27075
+ _context.prev = 4;
27076
+ _t = _context["catch"](2);
27077
+ setExportStatus({
27078
+ status: "error",
27079
+ message: _t.message || "Export failed."
27080
+ });
27081
+ case 5:
27082
+ setTimeout(function () {
27083
+ return setExportStatus(null);
27084
+ }, 3000);
27085
+ case 6:
27086
+ case "end":
27087
+ return _context.stop();
27088
+ }
27089
+ }, _callee, null, [[2, 4]]);
27090
+ }));
27091
+ return _handleExport.apply(this, arguments);
27092
+ }
27093
+ var folderOptions = menuItems.map(function (m) {
27094
+ return {
27095
+ label: m.name,
27096
+ value: String(m.id)
27097
+ };
27098
+ });
27099
+ var themeOptions = [{
27100
+ label: "App Default",
27101
+ value: ""
27102
+ }].concat(_toConsumableArray(Object.entries(themes || {}).map(function (_ref3) {
27103
+ var _ref4 = _slicedToArray(_ref3, 2),
27104
+ key = _ref4[0],
27105
+ t = _ref4[1];
27106
+ return {
27107
+ label: t.name || key,
27108
+ value: key
27109
+ };
27110
+ })));
27111
+ function handleChangeFolder(val) {
27112
+ if (!dashApi || !appId) return;
27113
+ var updated = DashReact.deepCopy(ws);
27114
+ updated.menuId = val ? Number(val) : null;
27115
+ // Strip widgetConfig from layout before saving
27116
+ updated.layout = (updated.layout || []).map(function (layoutItem) {
27117
+ var cleaned = _objectSpread$8({}, layoutItem);
27118
+ delete cleaned.widgetConfig;
27119
+ return cleaned;
27120
+ });
27121
+ dashApi.saveWorkspace(appId, updated, function () {
27122
+ onReloadWorkspaces && onReloadWorkspaces();
27123
+ }, function (e, err) {
27124
+ return (void 0);
27125
+ });
27126
+ }
27127
+ function handleChangeTheme(val) {
27128
+ if (!dashApi || !appId) return;
27129
+ var updated = DashReact.deepCopy(ws);
27130
+ updated.themeKey = val || null;
27131
+ updated.layout = (updated.layout || []).map(function (layoutItem) {
27132
+ var cleaned = _objectSpread$8({}, layoutItem);
27133
+ delete cleaned.widgetConfig;
27134
+ return cleaned;
27135
+ });
27136
+ dashApi.saveWorkspace(appId, updated, function () {
27137
+ onReloadWorkspaces && onReloadWorkspaces();
27138
+ }, function (e, err) {
27139
+ return (void 0);
27140
+ });
27141
+ }
27142
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
27143
+ className: "flex flex-col flex-1 min-h-0",
27144
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27145
+ className: "flex flex-col flex-1 min-h-0 overflow-y-auto p-6 gap-6",
27146
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27147
+ className: "flex-shrink-0 flex flex-row items-center justify-between",
27148
+ children: isEditing ? /*#__PURE__*/jsxRuntime.jsxs("div", {
27149
+ className: "flex flex-row items-center gap-2 flex-1",
27150
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
27151
+ value: editName,
27152
+ onChange: function onChange(value) {
27153
+ return setEditName(value);
27154
+ },
27155
+ placeholder: "Dashboard name",
27156
+ className: "flex-1"
27157
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.ButtonIcon, {
27158
+ icon: "check",
27159
+ onClick: function onClick() {
27160
+ return onSaveRename(ws);
27161
+ },
27162
+ size: "sm"
27163
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.ButtonIcon, {
27164
+ icon: "xmark",
27165
+ onClick: onCancelRename,
27166
+ size: "sm"
27167
+ })]
27168
+ }) : /*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading, {
27169
+ title: ws.name || "Untitled",
27170
+ padding: false
27171
+ })
27172
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27173
+ className: "flex-shrink-0 flex flex-col space-y-3",
27174
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SelectInput, {
27175
+ label: "Folder",
27176
+ value: String(ws.menuId || ""),
27177
+ onChange: function onChange(val) {
27178
+ return handleChangeFolder(val);
27179
+ },
27180
+ options: folderOptions,
27181
+ placeholder: "No folder"
27182
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.SelectInput, {
27183
+ label: "Theme",
27184
+ value: ws.themeKey || "",
27185
+ onChange: function onChange(val) {
27186
+ return handleChangeTheme(val);
27187
+ },
27188
+ options: themeOptions,
27189
+ placeholder: "App Default"
27190
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27191
+ className: "flex flex-row items-center gap-2",
27192
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27193
+ icon: "th-large",
27194
+ className: "h-3 w-3 opacity-50"
27195
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
27196
+ className: "text-sm opacity-70",
27197
+ children: [widgetCount, " widget", widgetCount !== 1 ? "s" : ""]
27198
+ })]
27199
+ })]
27200
+ }), registryPackage && /*#__PURE__*/jsxRuntime.jsxs("div", {
27201
+ className: "flex-shrink-0 flex items-center gap-2",
27202
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27203
+ icon: "store",
27204
+ className: "h-3 w-3 opacity-50"
27205
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
27206
+ className: "text-xs opacity-60",
27207
+ children: ["Imported from registry:", " ", /*#__PURE__*/jsxRuntime.jsx("span", {
27208
+ className: "font-medium",
27209
+ children: registryPackage
27210
+ })]
27211
+ })]
27212
+ }), registryPackage && appId && /*#__PURE__*/jsxRuntime.jsx("div", {
27213
+ className: "flex-shrink-0",
27214
+ children: /*#__PURE__*/jsxRuntime.jsx(StarRating, {
27215
+ appId: appId,
27216
+ packageName: registryPackage,
27217
+ interactive: true
27218
+ })
27219
+ }), exportStatus && /*#__PURE__*/jsxRuntime.jsxs("div", {
27220
+ className: "flex-shrink-0 flex items-center gap-2",
27221
+ children: [exportStatus.status === "loading" && /*#__PURE__*/jsxRuntime.jsx("div", {
27222
+ className: "animate-spin rounded-full h-3.5 w-3.5 border-b-2 border-blue-500"
27223
+ }), exportStatus.status === "success" && /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27224
+ icon: "circle-check",
27225
+ className: "h-3.5 w-3.5 text-green-400"
27226
+ }), exportStatus.status === "error" && /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27227
+ icon: "circle-xmark",
27228
+ className: "h-3.5 w-3.5 text-red-400"
27229
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27230
+ className: "text-xs ".concat(exportStatus.status === "error" ? "text-red-400" : "opacity-60"),
27231
+ children: exportStatus.message
27232
+ })]
27233
+ }), /*#__PURE__*/jsxRuntime.jsx(LayoutPreview, {
27234
+ layout: ws.layout
27235
+ })]
27236
+ }), !isEditing && /*#__PURE__*/jsxRuntime.jsxs("div", {
27237
+ className: "flex-shrink-0 flex flex-row justify-end gap-2 px-6 py-4 border-t border-white/10",
27238
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27239
+ title: "Export ZIP",
27240
+ onClick: handleExport,
27241
+ size: "sm"
27242
+ }), isShareable && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27243
+ title: "Publish",
27244
+ onClick: function onClick() {
27245
+ return setPublishOpen(true);
27246
+ },
27247
+ size: "sm"
27248
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27249
+ title: "Rename",
27250
+ onClick: function onClick() {
27251
+ return onStartRename(ws);
27252
+ },
27253
+ size: "sm"
27254
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27255
+ title: "Duplicate",
27256
+ onClick: function onClick() {
27257
+ return onDuplicate(ws);
27258
+ },
27259
+ size: "sm"
27260
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27261
+ title: "Delete",
27262
+ onClick: function onClick() {
27263
+ return onDelete(ws);
27264
+ },
27265
+ size: "sm"
27266
+ })]
27267
+ }), /*#__PURE__*/jsxRuntime.jsx(PublishDashboardModal, {
27268
+ isOpen: publishOpen,
27269
+ setIsOpen: setPublishOpen,
27270
+ appId: appId,
27271
+ workspaceId: ws.id,
27272
+ workspaceName: ws.name
27273
+ })]
27274
+ });
27275
+ };
27276
+
27277
+ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
27278
+ var dashboardPackage = _ref.dashboardPackage,
27279
+ appId = _ref.appId;
27280
+ var _useContext = React.useContext(DashReact.ThemeContext),
27281
+ currentTheme = _useContext.currentTheme;
27282
+ var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
27283
+ grow: false
27284
+ });
27285
+ var _useState = React.useState(null),
27286
+ _useState2 = _slicedToArray(_useState, 2),
27287
+ preview = _useState2[0],
27288
+ setPreview = _useState2[1];
27289
+ var _useState3 = React.useState(false),
27290
+ _useState4 = _slicedToArray(_useState3, 2),
27291
+ previewLoading = _useState4[0],
27292
+ setPreviewLoading = _useState4[1];
27293
+ var _useState5 = React.useState(false),
27294
+ _useState6 = _slicedToArray(_useState5, 2),
27295
+ isInstalling = _useState6[0],
27296
+ setIsInstalling = _useState6[1];
27297
+ var _useState7 = React.useState(null),
27298
+ _useState8 = _slicedToArray(_useState7, 2),
27299
+ installResult = _useState8[0],
27300
+ setInstallResult = _useState8[1];
27301
+ var pkg = dashboardPackage;
27302
+ if (!pkg) return null;
27303
+
27304
+ // Load preview data on mount
27305
+ // eslint-disable-next-line react-hooks/rules-of-hooks
27306
+ React.useEffect(function () {
27307
+ var _window$mainApi;
27308
+ if (!pkg.name) return;
27309
+ var cancelled = false;
27310
+ setPreviewLoading(true);
27311
+ setPreview(null);
27312
+ setInstallResult(null);
27313
+ (_window$mainApi = window.mainApi) === null || _window$mainApi === void 0 || (_window$mainApi = _window$mainApi.dashboardConfig) === null || _window$mainApi === void 0 || _window$mainApi.getDashboardPreview(pkg.name).then(function (result) {
27314
+ if (!cancelled) setPreview(result);
27315
+ })["catch"](function (err) {
27316
+ })["finally"](function () {
27317
+ if (!cancelled) setPreviewLoading(false);
27318
+ });
27319
+ return function () {
27320
+ cancelled = true;
27321
+ };
27322
+ }, [pkg.name]);
27323
+ function handleInstall() {
27324
+ return _handleInstall.apply(this, arguments);
27325
+ }
27326
+ function _handleInstall() {
27327
+ _handleInstall = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
27328
+ var _result$workspace, result, _t;
27329
+ return _regeneratorRuntime.wrap(function (_context) {
27330
+ while (1) switch (_context.prev = _context.next) {
27331
+ case 0:
27332
+ if (!(!appId || !pkg.name)) {
27333
+ _context.next = 1;
27334
+ break;
27335
+ }
27336
+ return _context.abrupt("return");
27337
+ case 1:
27338
+ setIsInstalling(true);
27339
+ setInstallResult(null);
27340
+ _context.prev = 2;
27341
+ _context.next = 3;
27342
+ return window.mainApi.dashboardConfig.installDashboardFromRegistry(appId, pkg.name);
27343
+ case 3:
27344
+ result = _context.sent;
27345
+ setInstallResult({
27346
+ status: result !== null && result !== void 0 && result.success ? "success" : "error",
27347
+ message: result !== null && result !== void 0 && result.success ? "Dashboard \"".concat(((_result$workspace = result.workspace) === null || _result$workspace === void 0 ? void 0 : _result$workspace.name) || pkg.name, "\" installed successfully.") : (result === null || result === void 0 ? void 0 : result.error) || "Installation failed."
27348
+ });
27349
+ _context.next = 5;
27350
+ break;
27351
+ case 4:
27352
+ _context.prev = 4;
27353
+ _t = _context["catch"](2);
27354
+ setInstallResult({
27355
+ status: "error",
27356
+ message: _t.message || "Failed to install dashboard."
27357
+ });
27358
+ case 5:
27359
+ _context.prev = 5;
27360
+ setIsInstalling(false);
27361
+ return _context.finish(5);
27362
+ case 6:
27363
+ case "end":
27364
+ return _context.stop();
27365
+ }
27366
+ }, _callee, null, [[2, 4, 5, 6]]);
27367
+ }));
27368
+ return _handleInstall.apply(this, arguments);
27369
+ }
27370
+ var compatibility = preview === null || preview === void 0 ? void 0 : preview.compatibility;
27371
+ var widgetDeps = (preview === null || preview === void 0 ? void 0 : preview.widgets) || pkg.widgets || [];
27372
+ var providers = (preview === null || preview === void 0 ? void 0 : preview.providers) || [];
27373
+ var wiring = (preview === null || preview === void 0 ? void 0 : preview.wiring) || [];
27374
+ function getCompatIcon(status) {
27375
+ if (status === "installed") return {
27376
+ icon: "circle-check",
27377
+ color: "text-green-400"
27378
+ };
27379
+ if (status === "available") return {
27380
+ icon: "circle-down",
27381
+ color: "text-blue-400"
27382
+ };
27383
+ return {
27384
+ icon: "circle-xmark",
27385
+ color: "text-red-400"
27386
+ };
27387
+ }
27388
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
27389
+ className: "flex flex-col flex-1 min-h-0",
27390
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27391
+ className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-6 ".concat(panelStyles.textColor || "text-gray-200"),
27392
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27393
+ className: "flex flex-row items-center gap-3",
27394
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27395
+ className: "h-5 w-5 flex-shrink-0 flex items-center justify-center",
27396
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27397
+ icon: pkg.icon || "clone",
27398
+ className: "h-5 w-5"
27399
+ })
27400
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27401
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
27402
+ title: pkg.displayName || pkg.name,
27403
+ padding: false
27404
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27405
+ className: "flex items-center gap-2 mt-0.5",
27406
+ children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
27407
+ className: "text-sm opacity-60",
27408
+ children: ["by ", pkg.author || "Unknown"]
27409
+ }), pkg.version && /*#__PURE__*/jsxRuntime.jsxs("span", {
27410
+ className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
27411
+ children: ["v", pkg.version]
27412
+ })]
27413
+ })]
27414
+ })]
27415
+ }), appId && /*#__PURE__*/jsxRuntime.jsx(StarRating, {
27416
+ appId: appId,
27417
+ packageName: pkg.name,
27418
+ interactive: false
27419
+ }), /*#__PURE__*/jsxRuntime.jsx("hr", {
27420
+ className: currentTheme["border-primary-medium"]
27421
+ }), pkg.description && /*#__PURE__*/jsxRuntime.jsx("p", {
27422
+ className: "text-sm",
27423
+ children: pkg.description
27424
+ }), pkg.tags && pkg.tags.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
27425
+ className: "flex flex-wrap gap-1",
27426
+ children: pkg.tags.map(function (tag) {
27427
+ return /*#__PURE__*/jsxRuntime.jsx("span", {
27428
+ className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-60"),
27429
+ children: tag
27430
+ }, tag);
27431
+ })
27432
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27433
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27434
+ className: "text-xs font-semibold opacity-50 mb-1 block",
27435
+ children: "REQUIRED WIDGETS"
27436
+ }), previewLoading ? /*#__PURE__*/jsxRuntime.jsxs("div", {
27437
+ className: "flex items-center gap-2 py-2",
27438
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27439
+ className: "animate-spin rounded-full h-4 w-4 border-b-2 border-blue-500"
27440
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27441
+ className: "text-xs opacity-50",
27442
+ children: "Checking compatibility..."
27443
+ })]
27444
+ }) : /*#__PURE__*/jsxRuntime.jsx("div", {
27445
+ className: "space-y-1.5",
27446
+ children: widgetDeps.map(function (w, idx) {
27447
+ var _compatibility$widget;
27448
+ var status = (compatibility === null || compatibility === void 0 || (_compatibility$widget = compatibility.widgets) === null || _compatibility$widget === void 0 ? void 0 : _compatibility$widget[w.name || w.packageName]) || "unknown";
27449
+ var compat = getCompatIcon(status);
27450
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
27451
+ className: "p-2 rounded ".concat(currentTheme["bg-primary-medium"], " flex items-center gap-2"),
27452
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27453
+ icon: compat.icon,
27454
+ className: "h-3.5 w-3.5 ".concat(compat.color)
27455
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27456
+ className: "text-sm",
27457
+ children: w.displayName || w.name || w.packageName
27458
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27459
+ className: "text-xs opacity-40 ml-auto",
27460
+ children: status === "installed" ? "Installed" : status === "available" ? "Will install" : "Unavailable"
27461
+ })]
27462
+ }, idx);
27463
+ })
27464
+ })]
27465
+ }), providers.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
27466
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27467
+ className: "text-xs font-semibold opacity-50 mb-1 block",
27468
+ children: "REQUIRED PROVIDERS"
27469
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
27470
+ className: "space-y-1",
27471
+ children: providers.map(function (p, idx) {
27472
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
27473
+ className: "flex items-center gap-2",
27474
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27475
+ className: "text-xs px-1.5 py-0.5 rounded bg-blue-900/30 text-blue-400",
27476
+ children: p.type
27477
+ }), p.required && /*#__PURE__*/jsxRuntime.jsx("span", {
27478
+ className: "text-[10px] opacity-40",
27479
+ children: "Required"
27480
+ })]
27481
+ }, idx);
27482
+ })
27483
+ })]
27484
+ }), wiring.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
27485
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27486
+ className: "text-xs font-semibold opacity-50 mb-1 block",
27487
+ children: "EVENT WIRING"
27488
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
27489
+ className: "space-y-1",
27490
+ children: wiring.map(function (w, idx) {
27491
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
27492
+ className: "text-xs p-2 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
27493
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27494
+ className: "font-medium",
27495
+ children: w.from || "Source"
27496
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27497
+ icon: "arrow-right",
27498
+ className: "h-2.5 w-2.5 mx-1.5 opacity-50"
27499
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27500
+ className: "font-medium",
27501
+ children: w.to || "Target"
27502
+ }), w.event && /*#__PURE__*/jsxRuntime.jsxs("span", {
27503
+ className: "opacity-50 ml-1.5",
27504
+ children: ["(", w.event, ")"]
27505
+ })]
27506
+ }, idx);
27507
+ })
27508
+ })]
27509
+ }), installResult && /*#__PURE__*/jsxRuntime.jsx("div", {
27510
+ className: "p-2 rounded border ".concat(installResult.status === "success" ? "bg-green-900/20 border-green-700" : "bg-red-900/30 border-red-700"),
27511
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
27512
+ className: "flex items-center gap-2",
27513
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27514
+ icon: installResult.status === "success" ? "circle-check" : "circle-xmark",
27515
+ className: "h-4 w-4 ".concat(installResult.status === "success" ? "text-green-400" : "text-red-400")
27516
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27517
+ className: "text-sm ".concat(installResult.status === "error" ? "text-red-400" : ""),
27518
+ children: installResult.message
27519
+ })]
27520
+ })
27521
+ })]
27522
+ }), (installResult === null || installResult === void 0 ? void 0 : installResult.status) !== "success" && /*#__PURE__*/jsxRuntime.jsx("div", {
27523
+ className: "flex items-center justify-end px-6 py-3 border-t ".concat(currentTheme["border-primary-medium"]),
27524
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27525
+ title: isInstalling ? "Installing..." : "Install Dashboard",
27526
+ bgColor: "bg-blue-600",
27527
+ hoverBackgroundColor: isInstalling ? "" : "hover:bg-blue-700",
27528
+ textSize: "text-sm",
27529
+ padding: "py-1.5 px-4",
27530
+ onClick: handleInstall,
27531
+ disabled: isInstalling
27532
+ })
27533
+ })]
27534
+ });
27535
+ };
27536
+
27537
+ var DiscoverDashboardsDetail = function DiscoverDashboardsDetail(_ref) {
27538
+ var onBack = _ref.onBack,
27539
+ appId = _ref.appId;
27540
+ var _useContext = React.useContext(DashReact.ThemeContext),
27541
+ currentTheme = _useContext.currentTheme;
27542
+ var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
27543
+ grow: false
27544
+ });
27545
+ var _useState = React.useState([]),
27546
+ _useState2 = _slicedToArray(_useState, 2),
27547
+ packages = _useState2[0],
27548
+ setPackages = _useState2[1];
27549
+ var _useState3 = React.useState(false),
27550
+ _useState4 = _slicedToArray(_useState3, 2),
27551
+ isLoading = _useState4[0],
27552
+ setIsLoading = _useState4[1];
27553
+ var _useState5 = React.useState(null),
27554
+ _useState6 = _slicedToArray(_useState5, 2),
27555
+ error = _useState6[0],
27556
+ setError = _useState6[1];
27557
+ var _useState7 = React.useState(""),
27558
+ _useState8 = _slicedToArray(_useState7, 2),
27559
+ searchQuery = _useState8[0],
27560
+ setSearchQuery = _useState8[1];
27561
+ var _useState9 = React.useState(null),
27562
+ _useState0 = _slicedToArray(_useState9, 2),
27563
+ selectedPackageName = _useState0[0],
27564
+ setSelectedPackageName = _useState0[1];
27565
+ var search = React.useCallback(/*#__PURE__*/function () {
27566
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(query) {
27567
+ var _window$mainApi;
27568
+ var result, _t;
27569
+ return _regeneratorRuntime.wrap(function (_context) {
27570
+ while (1) switch (_context.prev = _context.next) {
27571
+ case 0:
27572
+ if ((_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && (_window$mainApi = _window$mainApi.registry) !== null && _window$mainApi !== void 0 && _window$mainApi.searchDashboards) {
27573
+ _context.next = 1;
27574
+ break;
27575
+ }
27576
+ setPackages([]);
27577
+ return _context.abrupt("return");
27578
+ case 1:
27579
+ setIsLoading(true);
27580
+ setError(null);
27581
+ _context.prev = 2;
27582
+ _context.next = 3;
27583
+ return window.mainApi.registry.searchDashboards(query || "", {});
27584
+ case 3:
27585
+ result = _context.sent;
27586
+ setPackages((result === null || result === void 0 ? void 0 : result.packages) || []);
27587
+ _context.next = 5;
27588
+ break;
27589
+ case 4:
27590
+ _context.prev = 4;
27591
+ _t = _context["catch"](2);
27592
+ setError(_t.message || "Failed to search dashboard registry");
27593
+ setPackages([]);
27594
+ case 5:
27595
+ _context.prev = 5;
27596
+ setIsLoading(false);
27597
+ return _context.finish(5);
27598
+ case 6:
27599
+ case "end":
27600
+ return _context.stop();
27601
+ }
27602
+ }, _callee, null, [[2, 4, 5, 6]]);
27603
+ }));
27604
+ return function (_x) {
27605
+ return _ref2.apply(this, arguments);
27606
+ };
27607
+ }(), []);
27608
+
27609
+ // Debounce search on query changes
27610
+ React.useEffect(function () {
27611
+ var timer = setTimeout(function () {
27612
+ search(searchQuery);
27613
+ }, 300);
27614
+ return function () {
27615
+ return clearTimeout(timer);
27616
+ };
27617
+ // eslint-disable-next-line react-hooks/exhaustive-deps
27618
+ }, [searchQuery]);
27619
+ var retry = function retry() {
27620
+ return search(searchQuery);
27621
+ };
27622
+ var selectedPackage = selectedPackageName ? packages.find(function (p) {
27623
+ return p.name === selectedPackageName;
27624
+ }) : null;
27625
+
27626
+ // If a package is selected, show its detail inline
27627
+ if (selectedPackage) {
27628
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
27629
+ className: "flex flex-col flex-1 min-h-0",
27630
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27631
+ className: "flex-shrink-0 px-4 pt-4",
27632
+ children: /*#__PURE__*/jsxRuntime.jsxs("button", {
27633
+ type: "button",
27634
+ onClick: function onClick() {
27635
+ return setSelectedPackageName(null);
27636
+ },
27637
+ className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
27638
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27639
+ icon: "arrow-left",
27640
+ className: "h-3 w-3"
27641
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27642
+ children: "Back"
27643
+ })]
27644
+ })
27645
+ }), /*#__PURE__*/jsxRuntime.jsx(RegistryDashboardDetail, {
27646
+ dashboardPackage: selectedPackage,
27647
+ appId: appId
27648
+ })]
27649
+ });
27650
+ }
27651
+
27652
+ // Package list view
27653
+ var listBody;
27654
+ if (isLoading) {
27655
+ listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
27656
+ className: "flex items-center justify-center py-12",
27657
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
27658
+ className: "text-center",
27659
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27660
+ className: "animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500 mx-auto mb-3"
27661
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
27662
+ className: "text-sm opacity-50",
27663
+ children: "Loading dashboards..."
27664
+ })]
27665
+ })
27666
+ });
27667
+ } else if (error) {
27668
+ listBody = /*#__PURE__*/jsxRuntime.jsxs("div", {
27669
+ className: "px-4 py-8 text-center",
27670
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
27671
+ className: "text-sm text-red-400 mb-3",
27672
+ children: error
27673
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
27674
+ title: "Retry",
27675
+ bgColor: "bg-gray-700",
27676
+ hoverBackgroundColor: "hover:bg-gray-600",
27677
+ textSize: "text-sm",
27678
+ padding: "py-1 px-3",
27679
+ onClick: retry
27680
+ })]
27681
+ });
27682
+ } else if (packages.length === 0) {
27683
+ listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
27684
+ className: "px-4 py-8 text-center",
27685
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
27686
+ className: "text-sm opacity-50",
27687
+ children: searchQuery ? "No dashboards match your search." : "No dashboard packages available."
27688
+ })
27689
+ });
27690
+ } else {
27691
+ listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
27692
+ className: "space-y-1",
27693
+ children: packages.map(function (pkg) {
27694
+ var widgetCount = (pkg.widgets || []).length;
27695
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
27696
+ icon: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27697
+ icon: pkg.icon || "clone",
27698
+ className: "h-3.5 w-3.5"
27699
+ }),
27700
+ onClick: function onClick() {
27701
+ return setSelectedPackageName(pkg.name);
27702
+ },
27703
+ badge: widgetCount > 0 ? "".concat(widgetCount) : undefined,
27704
+ children: pkg.displayName || pkg.name
27705
+ }, pkg.name);
27706
+ })
27707
+ });
27708
+ }
27709
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
27710
+ className: "flex flex-col flex-1 min-h-0 ".concat(panelStyles.textColor || "text-gray-200"),
27711
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27712
+ className: "flex-shrink-0 px-4 pt-4",
27713
+ children: /*#__PURE__*/jsxRuntime.jsxs("button", {
27714
+ type: "button",
27715
+ onClick: onBack,
27716
+ className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
27717
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27718
+ icon: "arrow-left",
27719
+ className: "h-3 w-3"
27720
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27721
+ children: "Back"
27722
+ })]
27723
+ })
27724
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
27725
+ className: "flex-shrink-0 px-4 py-3",
27726
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.SearchInput, {
27727
+ value: searchQuery,
27728
+ onChange: setSearchQuery,
27729
+ placeholder: "Search dashboards...",
27730
+ inputClassName: "py-1.5 text-xs"
27731
+ })
27732
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
27733
+ className: "flex-1 min-h-0 overflow-y-auto px-2",
27734
+ children: listBody
27735
+ }), !isLoading && !error && packages.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
27736
+ className: "flex-shrink-0 px-4 py-2 text-[10px] opacity-40 border-t border-white/10",
27737
+ children: [packages.length, " dashboard", packages.length !== 1 ? "s" : ""]
27738
+ })]
27739
+ });
27740
+ };
27741
+
27742
+ function ownKeys$7(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
27743
+ function _objectSpread$7(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$7(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$7(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
27744
+ var DashboardsSection = function DashboardsSection(_ref) {
27745
+ var _ref$workspaces = _ref.workspaces,
27746
+ workspaces = _ref$workspaces === void 0 ? [] : _ref$workspaces,
27747
+ _ref$menuItems = _ref.menuItems,
26610
27748
  menuItems = _ref$menuItems === void 0 ? [] : _ref$menuItems,
26611
27749
  _ref$dashApi = _ref.dashApi,
26612
27750
  dashApi = _ref$dashApi === void 0 ? null : _ref$dashApi,
26613
27751
  _ref$credentials = _ref.credentials,
26614
27752
  credentials = _ref$credentials === void 0 ? null : _ref$credentials,
26615
27753
  _ref$onReloadWorkspac = _ref.onReloadWorkspaces,
26616
- onReloadWorkspaces = _ref$onReloadWorkspac === void 0 ? null : _ref$onReloadWorkspac;
27754
+ onReloadWorkspaces = _ref$onReloadWorkspac === void 0 ? null : _ref$onReloadWorkspac,
27755
+ _ref$createRequested = _ref.createRequested,
27756
+ createRequested = _ref$createRequested === void 0 ? false : _ref$createRequested,
27757
+ _ref$onCreateAcknowle = _ref.onCreateAcknowledged,
27758
+ onCreateAcknowledged = _ref$onCreateAcknowle === void 0 ? null : _ref$onCreateAcknowle;
26617
27759
  var _useState = React.useState(null),
26618
27760
  _useState2 = _slicedToArray(_useState, 2),
26619
27761
  selectedId = _useState2[0],
@@ -26638,6 +27780,15 @@ var DashboardsSection = function DashboardsSection(_ref) {
26638
27780
  _useState10 = _slicedToArray(_useState1, 2),
26639
27781
  viewMode = _useState10[0],
26640
27782
  setViewMode = _useState10[1];
27783
+ // null | "marketplace" | "import-result"
27784
+ var _useState11 = React.useState(null),
27785
+ _useState12 = _slicedToArray(_useState11, 2),
27786
+ installMode = _useState12[0],
27787
+ setInstallMode = _useState12[1];
27788
+ var _useState13 = React.useState(null),
27789
+ _useState14 = _slicedToArray(_useState13, 2),
27790
+ importResult = _useState14[0],
27791
+ setImportResult = _useState14[1];
26641
27792
  var appId = credentials === null || credentials === void 0 ? void 0 : credentials.appId;
26642
27793
  var _useContext = React.useContext(DashReact.ThemeContext),
26643
27794
  currentTheme = _useContext.currentTheme;
@@ -26717,6 +27868,84 @@ var DashboardsSection = function DashboardsSection(_ref) {
26717
27868
  setDeleteTarget(null);
26718
27869
  });
26719
27870
  }
27871
+
27872
+ // Respond to external create trigger from header button (marketplace)
27873
+ var prevCreateRequested = React.useRef(false);
27874
+ React.useEffect(function () {
27875
+ if (createRequested && !prevCreateRequested.current) {
27876
+ setSelectedId(null);
27877
+ setInstallMode("marketplace");
27878
+ setImportResult(null);
27879
+ }
27880
+ prevCreateRequested.current = createRequested;
27881
+ if (createRequested && onCreateAcknowledged) {
27882
+ onCreateAcknowledged();
27883
+ }
27884
+ // eslint-disable-next-line react-hooks/exhaustive-deps
27885
+ }, [createRequested]);
27886
+ function handleImport() {
27887
+ return _handleImport.apply(this, arguments);
27888
+ }
27889
+ function _handleImport() {
27890
+ _handleImport = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
27891
+ var result, _result$workspace, _t;
27892
+ return _regeneratorRuntime.wrap(function (_context) {
27893
+ while (1) switch (_context.prev = _context.next) {
27894
+ case 0:
27895
+ if (appId) {
27896
+ _context.next = 1;
27897
+ break;
27898
+ }
27899
+ return _context.abrupt("return");
27900
+ case 1:
27901
+ setInstallMode("import-result");
27902
+ setImportResult({
27903
+ status: "loading",
27904
+ message: "Importing dashboard..."
27905
+ });
27906
+ _context.prev = 2;
27907
+ _context.next = 3;
27908
+ return window.mainApi.dashboardConfig.importDashboardConfig(appId);
27909
+ case 3:
27910
+ result = _context.sent;
27911
+ if (result) {
27912
+ _context.next = 4;
27913
+ break;
27914
+ }
27915
+ // User cancelled the file picker
27916
+ setInstallMode(null);
27917
+ setImportResult(null);
27918
+ return _context.abrupt("return");
27919
+ case 4:
27920
+ if (result.success) {
27921
+ setImportResult({
27922
+ status: "success",
27923
+ message: "Dashboard \"".concat(((_result$workspace = result.workspace) === null || _result$workspace === void 0 ? void 0 : _result$workspace.name) || "Untitled", "\" imported successfully.")
27924
+ });
27925
+ onReloadWorkspaces && onReloadWorkspaces();
27926
+ } else {
27927
+ setImportResult({
27928
+ status: "error",
27929
+ message: result.error || "Import failed."
27930
+ });
27931
+ }
27932
+ _context.next = 6;
27933
+ break;
27934
+ case 5:
27935
+ _context.prev = 5;
27936
+ _t = _context["catch"](2);
27937
+ setImportResult({
27938
+ status: "error",
27939
+ message: _t.message || "Failed to import dashboard."
27940
+ });
27941
+ case 6:
27942
+ case "end":
27943
+ return _context.stop();
27944
+ }
27945
+ }, _callee, null, [[2, 5]]);
27946
+ }));
27947
+ return _handleImport.apply(this, arguments);
27948
+ }
26720
27949
  var selectedWorkspace = workspaces.find(function (ws) {
26721
27950
  return ws.id === selectedId;
26722
27951
  });
@@ -26766,13 +27995,33 @@ var DashboardsSection = function DashboardsSection(_ref) {
26766
27995
  className: "flex flex-col h-full",
26767
27996
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
26768
27997
  className: "flex-shrink-0 flex flex-col gap-2 px-3 pt-3 pb-2 ".concat(headerStyles.backgroundColor || ""),
26769
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SearchInput, {
26770
- value: searchQuery,
26771
- onChange: setSearchQuery,
26772
- placeholder: "Search dashboards..."
27998
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27999
+ className: "flex items-center gap-2",
28000
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
28001
+ className: "flex-1",
28002
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.SearchInput, {
28003
+ value: searchQuery,
28004
+ onChange: setSearchQuery,
28005
+ placeholder: "Search dashboards..."
28006
+ })
28007
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.ButtonIcon, {
28008
+ icon: "file-import",
28009
+ onClick: handleImport,
28010
+ size: "sm",
28011
+ title: "Import dashboard"
28012
+ })]
26773
28013
  }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Tabs3, {
26774
- value: viewMode,
26775
- onValueChange: setViewMode,
28014
+ value: installMode === "marketplace" ? "marketplace" : viewMode,
28015
+ onValueChange: function onValueChange(val) {
28016
+ if (val === "marketplace") {
28017
+ setInstallMode("marketplace");
28018
+ setSelectedId(null);
28019
+ } else {
28020
+ setInstallMode(null);
28021
+ setImportResult(null);
28022
+ setViewMode(val);
28023
+ }
28024
+ },
26776
28025
  backgroundColor: "bg-transparent",
26777
28026
  spacing: "p-0",
26778
28027
  children: /*#__PURE__*/jsxRuntime.jsxs(DashReact.Tabs3.List, {
@@ -26786,6 +28035,10 @@ var DashboardsSection = function DashboardsSection(_ref) {
26786
28035
  value: "alphabetical",
26787
28036
  className: "flex-1",
26788
28037
  children: "A-Z"
28038
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Tabs3.Trigger, {
28039
+ value: "marketplace",
28040
+ className: "flex-1",
28041
+ children: "Marketplace"
26789
28042
  })]
26790
28043
  })
26791
28044
  })]
@@ -26799,26 +28052,68 @@ var DashboardsSection = function DashboardsSection(_ref) {
26799
28052
  })
26800
28053
  })]
26801
28054
  });
26802
- var detailContent = selectedWorkspace ? /*#__PURE__*/jsxRuntime.jsx(DashboardDetail, {
26803
- workspace: selectedWorkspace,
26804
- menuItems: menuItems,
26805
- editingId: editingId,
26806
- editName: editName,
26807
- setEditName: setEditName,
26808
- onStartRename: handleStartRename,
26809
- onSaveRename: handleSaveRename,
26810
- onCancelRename: function onCancelRename() {
26811
- setEditingId(null);
26812
- setEditName("");
26813
- },
26814
- onDuplicate: handleDuplicate,
26815
- onDelete: function onDelete(ws) {
26816
- return setDeleteTarget(ws);
26817
- },
26818
- dashApi: dashApi,
26819
- credentials: credentials,
26820
- onReloadWorkspaces: onReloadWorkspaces
26821
- }) : null;
28055
+ var detailContent = null;
28056
+ if (installMode === "marketplace") {
28057
+ detailContent = /*#__PURE__*/jsxRuntime.jsx(DiscoverDashboardsDetail, {
28058
+ onBack: function onBack() {
28059
+ setInstallMode(null);
28060
+ setViewMode("grouped");
28061
+ },
28062
+ appId: appId
28063
+ });
28064
+ } else if (installMode === "import-result") {
28065
+ detailContent = /*#__PURE__*/jsxRuntime.jsxs("div", {
28066
+ className: "flex flex-col flex-1 min-h-0 p-6 space-y-4",
28067
+ children: [(importResult === null || importResult === void 0 ? void 0 : importResult.status) === "loading" && /*#__PURE__*/jsxRuntime.jsxs("div", {
28068
+ className: "flex items-center gap-3",
28069
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
28070
+ className: "animate-spin rounded-full h-5 w-5 border-b-2 border-blue-500"
28071
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
28072
+ className: "text-sm opacity-70",
28073
+ children: importResult.message
28074
+ })]
28075
+ }), (importResult === null || importResult === void 0 ? void 0 : importResult.status) === "success" && /*#__PURE__*/jsxRuntime.jsxs("div", {
28076
+ className: "flex items-center gap-2",
28077
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
28078
+ icon: "circle-check",
28079
+ className: "h-4 w-4 text-green-400"
28080
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
28081
+ className: "text-sm",
28082
+ children: importResult.message
28083
+ })]
28084
+ }), (importResult === null || importResult === void 0 ? void 0 : importResult.status) === "error" && /*#__PURE__*/jsxRuntime.jsxs("div", {
28085
+ className: "flex items-center gap-2",
28086
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
28087
+ icon: "circle-xmark",
28088
+ className: "h-4 w-4 text-red-400"
28089
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
28090
+ className: "text-sm text-red-400",
28091
+ children: importResult.message
28092
+ })]
28093
+ })]
28094
+ });
28095
+ } else if (selectedWorkspace) {
28096
+ detailContent = /*#__PURE__*/jsxRuntime.jsx(DashboardDetail, {
28097
+ workspace: selectedWorkspace,
28098
+ menuItems: menuItems,
28099
+ editingId: editingId,
28100
+ editName: editName,
28101
+ setEditName: setEditName,
28102
+ onStartRename: handleStartRename,
28103
+ onSaveRename: handleSaveRename,
28104
+ onCancelRename: function onCancelRename() {
28105
+ setEditingId(null);
28106
+ setEditName("");
28107
+ },
28108
+ onDuplicate: handleDuplicate,
28109
+ onDelete: function onDelete(ws) {
28110
+ return setDeleteTarget(ws);
28111
+ },
28112
+ dashApi: dashApi,
28113
+ credentials: credentials,
28114
+ onReloadWorkspaces: onReloadWorkspaces
28115
+ });
28116
+ }
26822
28117
  return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
26823
28118
  children: [/*#__PURE__*/jsxRuntime.jsx(SectionLayout, {
26824
28119
  listContent: listContent,
@@ -32149,9 +33444,9 @@ var AppSettingsModal = function AppSettingsModal(_ref) {
32149
33444
  children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading2, {
32150
33445
  title: activeDef.label,
32151
33446
  padding: false
32152
- }), (activeSection === "folders" || activeSection === "providers" || activeSection === "themes" || activeSection === "widgets") && /*#__PURE__*/jsxRuntime.jsx(DashReact.ButtonIcon3, {
33447
+ }), (activeSection === "dashboards" || activeSection === "folders" || activeSection === "providers" || activeSection === "themes" || activeSection === "widgets") && /*#__PURE__*/jsxRuntime.jsx(DashReact.ButtonIcon3, {
32153
33448
  icon: "plus",
32154
- text: activeSection === "folders" ? "New Folder" : activeSection === "providers" ? "New Provider" : activeSection === "widgets" ? "Install Widgets" : "New Theme",
33449
+ text: activeSection === "dashboards" ? "Marketplace" : activeSection === "folders" ? "New Folder" : activeSection === "providers" ? "New Provider" : activeSection === "widgets" ? "Install Widgets" : "New Theme",
32155
33450
  onClick: function onClick() {
32156
33451
  return setCreateRequested(true);
32157
33452
  },
@@ -32168,7 +33463,11 @@ var AppSettingsModal = function AppSettingsModal(_ref) {
32168
33463
  menuItems: menuItems,
32169
33464
  dashApi: dashApi,
32170
33465
  credentials: credentials,
32171
- onReloadWorkspaces: onReloadWorkspaces
33466
+ onReloadWorkspaces: onReloadWorkspaces,
33467
+ createRequested: createRequested,
33468
+ onCreateAcknowledged: function onCreateAcknowledged() {
33469
+ return setCreateRequested(false);
33470
+ }
32172
33471
  }), activeSection === "folders" && /*#__PURE__*/jsxRuntime.jsx(FoldersSection, {
32173
33472
  menuItems: menuItems,
32174
33473
  workspaces: workspaces,