@trops/dash-core 0.1.92 → 0.1.94

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -26365,6 +26365,257 @@ var ThemeManagerModal = function ThemeManagerModal(_ref) {
26365
26365
  });
26366
26366
  };
26367
26367
 
26368
+ var StarRating = function StarRating(_ref) {
26369
+ var appId = _ref.appId,
26370
+ packageName = _ref.packageName,
26371
+ _ref$interactive = _ref.interactive,
26372
+ interactive = _ref$interactive === void 0 ? true : _ref$interactive;
26373
+ var _useContext = useContext(ThemeContext),
26374
+ currentTheme = _useContext.currentTheme;
26375
+ var _useState = useState(0),
26376
+ _useState2 = _slicedToArray(_useState, 2),
26377
+ rating = _useState2[0],
26378
+ setRating = _useState2[1];
26379
+ var _useState3 = useState(0),
26380
+ _useState4 = _slicedToArray(_useState3, 2),
26381
+ hoverRating = _useState4[0],
26382
+ setHoverRating = _useState4[1];
26383
+ var _useState5 = useState(true),
26384
+ _useState6 = _slicedToArray(_useState5, 2),
26385
+ loading = _useState6[0],
26386
+ setLoading = _useState6[1];
26387
+ useEffect(function () {
26388
+ var _window$mainApi;
26389
+ if (!appId || !packageName) return;
26390
+ var cancelled = false;
26391
+ setLoading(true);
26392
+ (_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) {
26393
+ if (!cancelled && result !== null && result !== void 0 && result.rating) {
26394
+ setRating(result.rating);
26395
+ }
26396
+ })["catch"](function () {})["finally"](function () {
26397
+ if (!cancelled) setLoading(false);
26398
+ });
26399
+ return function () {
26400
+ cancelled = true;
26401
+ };
26402
+ }, [appId, packageName]);
26403
+ function handleClick(_x) {
26404
+ return _handleClick.apply(this, arguments);
26405
+ }
26406
+ function _handleClick() {
26407
+ _handleClick = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(value) {
26408
+ var newRating, _window$mainApi2;
26409
+ return _regeneratorRuntime.wrap(function (_context) {
26410
+ while (1) switch (_context.prev = _context.next) {
26411
+ case 0:
26412
+ if (!(!interactive || !appId || !packageName)) {
26413
+ _context.next = 1;
26414
+ break;
26415
+ }
26416
+ return _context.abrupt("return");
26417
+ case 1:
26418
+ newRating = value === rating ? 0 : value;
26419
+ setRating(newRating);
26420
+ _context.prev = 2;
26421
+ _context.next = 3;
26422
+ 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);
26423
+ case 3:
26424
+ _context.next = 5;
26425
+ break;
26426
+ case 4:
26427
+ _context.prev = 4;
26428
+ _context["catch"](2);
26429
+ case 5:
26430
+ case "end":
26431
+ return _context.stop();
26432
+ }
26433
+ }, _callee, null, [[2, 4]]);
26434
+ }));
26435
+ return _handleClick.apply(this, arguments);
26436
+ }
26437
+ if (loading) return null;
26438
+ var displayRating = hoverRating || rating;
26439
+ return /*#__PURE__*/jsx("div", {
26440
+ className: "flex items-center gap-0.5",
26441
+ onMouseLeave: function onMouseLeave() {
26442
+ return setHoverRating(0);
26443
+ },
26444
+ children: [1, 2, 3, 4, 5].map(function (star) {
26445
+ return /*#__PURE__*/jsx("button", {
26446
+ type: "button",
26447
+ disabled: !interactive,
26448
+ onClick: function onClick() {
26449
+ return handleClick(star);
26450
+ },
26451
+ onMouseEnter: function onMouseEnter() {
26452
+ return interactive && setHoverRating(star);
26453
+ },
26454
+ className: "p-0.5 transition-colors ".concat(interactive ? "cursor-pointer hover:scale-110" : "cursor-default"),
26455
+ children: /*#__PURE__*/jsx(FontAwesomeIcon, {
26456
+ icon: star <= displayRating ? "star" : ["far", "star"],
26457
+ className: "h-3.5 w-3.5 ".concat(star <= displayRating ? "text-yellow-400" : currentTheme["text-primary-medium"] || "text-gray-500")
26458
+ })
26459
+ }, star);
26460
+ })
26461
+ });
26462
+ };
26463
+
26464
+ var PublishDashboardModal = function PublishDashboardModal(_ref) {
26465
+ var isOpen = _ref.isOpen,
26466
+ setIsOpen = _ref.setIsOpen,
26467
+ appId = _ref.appId,
26468
+ workspaceId = _ref.workspaceId,
26469
+ workspaceName = _ref.workspaceName;
26470
+ var _useContext = useContext(ThemeContext),
26471
+ currentTheme = _useContext.currentTheme;
26472
+ var panelStyles = getStylesForItem(themeObjects.PANEL, currentTheme, {
26473
+ grow: false
26474
+ });
26475
+ var _useState = useState(""),
26476
+ _useState2 = _slicedToArray(_useState, 2),
26477
+ description = _useState2[0],
26478
+ setDescription = _useState2[1];
26479
+ var _useState3 = useState(""),
26480
+ _useState4 = _slicedToArray(_useState3, 2),
26481
+ tags = _useState4[0],
26482
+ setTags = _useState4[1];
26483
+ var _useState5 = useState(""),
26484
+ _useState6 = _slicedToArray(_useState5, 2),
26485
+ icon = _useState6[0],
26486
+ setIcon = _useState6[1];
26487
+ var _useState7 = useState(false),
26488
+ _useState8 = _slicedToArray(_useState7, 2),
26489
+ isPublishing = _useState8[0],
26490
+ setIsPublishing = _useState8[1];
26491
+ var _useState9 = useState(null),
26492
+ _useState0 = _slicedToArray(_useState9, 2),
26493
+ result = _useState0[0],
26494
+ setResult = _useState0[1];
26495
+ function handleClose() {
26496
+ setIsOpen(false);
26497
+ // Reset state after a brief delay to avoid flash
26498
+ setTimeout(function () {
26499
+ setDescription("");
26500
+ setTags("");
26501
+ setIcon("");
26502
+ setIsPublishing(false);
26503
+ setResult(null);
26504
+ }, 200);
26505
+ }
26506
+ function handlePublish() {
26507
+ return _handlePublish.apply(this, arguments);
26508
+ }
26509
+ function _handlePublish() {
26510
+ _handlePublish = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
26511
+ var options, res, _t;
26512
+ return _regeneratorRuntime.wrap(function (_context) {
26513
+ while (1) switch (_context.prev = _context.next) {
26514
+ case 0:
26515
+ if (!(!appId || !workspaceId)) {
26516
+ _context.next = 1;
26517
+ break;
26518
+ }
26519
+ return _context.abrupt("return");
26520
+ case 1:
26521
+ setIsPublishing(true);
26522
+ setResult(null);
26523
+ _context.prev = 2;
26524
+ options = {
26525
+ description: description.trim() || undefined,
26526
+ tags: tags.split(",").map(function (t) {
26527
+ return t.trim();
26528
+ }).filter(Boolean),
26529
+ icon: icon.trim() || undefined
26530
+ };
26531
+ _context.next = 3;
26532
+ return window.mainApi.dashboardConfig.prepareDashboardForPublish(appId, workspaceId, options);
26533
+ case 3:
26534
+ res = _context.sent;
26535
+ setResult(res);
26536
+ _context.next = 5;
26537
+ break;
26538
+ case 4:
26539
+ _context.prev = 4;
26540
+ _t = _context["catch"](2);
26541
+ setResult({
26542
+ success: false,
26543
+ error: _t.message || "Failed to prepare dashboard for publish."
26544
+ });
26545
+ case 5:
26546
+ _context.prev = 5;
26547
+ setIsPublishing(false);
26548
+ return _context.finish(5);
26549
+ case 6:
26550
+ case "end":
26551
+ return _context.stop();
26552
+ }
26553
+ }, _callee, null, [[2, 4, 5, 6]]);
26554
+ }));
26555
+ return _handlePublish.apply(this, arguments);
26556
+ }
26557
+ return /*#__PURE__*/jsx(ConfirmationModal, {
26558
+ isOpen: isOpen,
26559
+ setIsOpen: handleClose,
26560
+ title: "Publish \"".concat(workspaceName || "Dashboard", "\""),
26561
+ confirmLabel: isPublishing ? "Preparing..." : "Prepare for Publish",
26562
+ onConfirm: result ? handleClose : handlePublish,
26563
+ onCancel: handleClose,
26564
+ disabled: isPublishing,
26565
+ children: /*#__PURE__*/jsx("div", {
26566
+ className: "space-y-4 ".concat(panelStyles.textColor || "text-gray-200"),
26567
+ children: !result ? /*#__PURE__*/jsxs(Fragment, {
26568
+ children: [/*#__PURE__*/jsx("p", {
26569
+ className: "text-sm opacity-70",
26570
+ children: "This will create a publish-ready ZIP file that can be submitted to the dashboard registry."
26571
+ }), /*#__PURE__*/jsxs("div", {
26572
+ className: "space-y-3",
26573
+ children: [/*#__PURE__*/jsx(InputText, {
26574
+ label: "Description",
26575
+ value: description,
26576
+ onChange: setDescription,
26577
+ placeholder: "A brief description of this dashboard..."
26578
+ }), /*#__PURE__*/jsx(InputText, {
26579
+ label: "Tags (comma-separated)",
26580
+ value: tags,
26581
+ onChange: setTags,
26582
+ placeholder: "productivity, slack, monitoring"
26583
+ }), /*#__PURE__*/jsx(InputText, {
26584
+ label: "Icon (FontAwesome name)",
26585
+ value: icon,
26586
+ onChange: setIcon,
26587
+ placeholder: "chart-line"
26588
+ })]
26589
+ })]
26590
+ }) : result.success ? /*#__PURE__*/jsxs("div", {
26591
+ className: "space-y-3",
26592
+ children: [/*#__PURE__*/jsxs("div", {
26593
+ className: "flex items-center gap-2",
26594
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
26595
+ icon: "circle-check",
26596
+ className: "h-4 w-4 text-green-400"
26597
+ }), /*#__PURE__*/jsx("span", {
26598
+ className: "text-sm",
26599
+ children: "Dashboard prepared for publishing."
26600
+ })]
26601
+ }), result.filePath && /*#__PURE__*/jsxs("div", {
26602
+ className: "text-xs opacity-50 break-all",
26603
+ children: ["Saved to: ", result.filePath]
26604
+ })]
26605
+ }) : /*#__PURE__*/jsxs("div", {
26606
+ className: "flex items-center gap-2",
26607
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
26608
+ icon: "circle-xmark",
26609
+ className: "h-4 w-4 text-red-400"
26610
+ }), /*#__PURE__*/jsx("span", {
26611
+ className: "text-sm text-red-400",
26612
+ children: result.error || "Publish preparation failed."
26613
+ })]
26614
+ })
26615
+ })
26616
+ });
26617
+ };
26618
+
26368
26619
  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; }
26369
26620
  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; }
26370
26621
  var LayoutPreview = function LayoutPreview(_ref) {
@@ -26424,6 +26675,7 @@ var LayoutPreview = function LayoutPreview(_ref) {
26424
26675
  });
26425
26676
  };
26426
26677
  var DashboardDetail = function DashboardDetail(_ref2) {
26678
+ var _ws$_dashboardConfig, _ws$_dashboardConfig2;
26427
26679
  var workspace = _ref2.workspace,
26428
26680
  _ref2$menuItems = _ref2.menuItems,
26429
26681
  menuItems = _ref2$menuItems === void 0 ? [] : _ref2$menuItems,
@@ -26447,6 +26699,71 @@ var DashboardDetail = function DashboardDetail(_ref2) {
26447
26699
  var appId = credentials === null || credentials === void 0 ? void 0 : credentials.appId;
26448
26700
  var _useContext = useContext(ThemeContext),
26449
26701
  themes = _useContext.themes;
26702
+ var _useState = useState(null),
26703
+ _useState2 = _slicedToArray(_useState, 2),
26704
+ exportStatus = _useState2[0],
26705
+ setExportStatus = _useState2[1];
26706
+ var _useState3 = useState(false),
26707
+ _useState4 = _slicedToArray(_useState3, 2),
26708
+ publishOpen = _useState4[0],
26709
+ setPublishOpen = _useState4[1];
26710
+ var registryPackage = (_ws$_dashboardConfig = ws._dashboardConfig) === null || _ws$_dashboardConfig === void 0 ? void 0 : _ws$_dashboardConfig.registryPackage;
26711
+ var isShareable = ((_ws$_dashboardConfig2 = ws._dashboardConfig) === null || _ws$_dashboardConfig2 === void 0 ? void 0 : _ws$_dashboardConfig2.shareable) !== false;
26712
+ function handleExport() {
26713
+ return _handleExport.apply(this, arguments);
26714
+ }
26715
+ function _handleExport() {
26716
+ _handleExport = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
26717
+ var result, _t;
26718
+ return _regeneratorRuntime.wrap(function (_context) {
26719
+ while (1) switch (_context.prev = _context.next) {
26720
+ case 0:
26721
+ if (appId) {
26722
+ _context.next = 1;
26723
+ break;
26724
+ }
26725
+ return _context.abrupt("return");
26726
+ case 1:
26727
+ setExportStatus({
26728
+ status: "loading"
26729
+ });
26730
+ _context.prev = 2;
26731
+ _context.next = 3;
26732
+ return window.mainApi.dashboardConfig.exportDashboardConfig(appId, ws.id, {});
26733
+ case 3:
26734
+ result = _context.sent;
26735
+ if (result !== null && result !== void 0 && result.success) {
26736
+ setExportStatus({
26737
+ status: "success",
26738
+ message: "Exported successfully."
26739
+ });
26740
+ } else {
26741
+ setExportStatus({
26742
+ status: "error",
26743
+ message: (result === null || result === void 0 ? void 0 : result.error) || "Export failed."
26744
+ });
26745
+ }
26746
+ _context.next = 5;
26747
+ break;
26748
+ case 4:
26749
+ _context.prev = 4;
26750
+ _t = _context["catch"](2);
26751
+ setExportStatus({
26752
+ status: "error",
26753
+ message: _t.message || "Export failed."
26754
+ });
26755
+ case 5:
26756
+ setTimeout(function () {
26757
+ return setExportStatus(null);
26758
+ }, 3000);
26759
+ case 6:
26760
+ case "end":
26761
+ return _context.stop();
26762
+ }
26763
+ }, _callee, null, [[2, 4]]);
26764
+ }));
26765
+ return _handleExport.apply(this, arguments);
26766
+ }
26450
26767
  var folderOptions = menuItems.map(function (m) {
26451
26768
  return {
26452
26769
  label: m.name,
@@ -26542,42 +26859,556 @@ var DashboardDetail = function DashboardDetail(_ref2) {
26542
26859
  onChange: function onChange(val) {
26543
26860
  return handleChangeTheme(val);
26544
26861
  },
26545
- options: themeOptions,
26546
- placeholder: "App Default"
26547
- }), /*#__PURE__*/jsxs("div", {
26548
- className: "flex flex-row items-center gap-2",
26862
+ options: themeOptions,
26863
+ placeholder: "App Default"
26864
+ }), /*#__PURE__*/jsxs("div", {
26865
+ className: "flex flex-row items-center gap-2",
26866
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
26867
+ icon: "th-large",
26868
+ className: "h-3 w-3 opacity-50"
26869
+ }), /*#__PURE__*/jsxs("span", {
26870
+ className: "text-sm opacity-70",
26871
+ children: [widgetCount, " widget", widgetCount !== 1 ? "s" : ""]
26872
+ })]
26873
+ })]
26874
+ }), registryPackage && /*#__PURE__*/jsxs("div", {
26875
+ className: "flex-shrink-0 flex items-center gap-2",
26876
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
26877
+ icon: "store",
26878
+ className: "h-3 w-3 opacity-50"
26879
+ }), /*#__PURE__*/jsxs("span", {
26880
+ className: "text-xs opacity-60",
26881
+ children: ["Imported from registry:", " ", /*#__PURE__*/jsx("span", {
26882
+ className: "font-medium",
26883
+ children: registryPackage
26884
+ })]
26885
+ })]
26886
+ }), registryPackage && appId && /*#__PURE__*/jsx("div", {
26887
+ className: "flex-shrink-0",
26888
+ children: /*#__PURE__*/jsx(StarRating, {
26889
+ appId: appId,
26890
+ packageName: registryPackage,
26891
+ interactive: true
26892
+ })
26893
+ }), exportStatus && /*#__PURE__*/jsxs("div", {
26894
+ className: "flex-shrink-0 flex items-center gap-2",
26895
+ children: [exportStatus.status === "loading" && /*#__PURE__*/jsx("div", {
26896
+ className: "animate-spin rounded-full h-3.5 w-3.5 border-b-2 border-blue-500"
26897
+ }), exportStatus.status === "success" && /*#__PURE__*/jsx(FontAwesomeIcon, {
26898
+ icon: "circle-check",
26899
+ className: "h-3.5 w-3.5 text-green-400"
26900
+ }), exportStatus.status === "error" && /*#__PURE__*/jsx(FontAwesomeIcon, {
26901
+ icon: "circle-xmark",
26902
+ className: "h-3.5 w-3.5 text-red-400"
26903
+ }), /*#__PURE__*/jsx("span", {
26904
+ className: "text-xs ".concat(exportStatus.status === "error" ? "text-red-400" : "opacity-60"),
26905
+ children: exportStatus.message
26906
+ })]
26907
+ }), /*#__PURE__*/jsx(LayoutPreview, {
26908
+ layout: ws.layout
26909
+ })]
26910
+ }), !isEditing && /*#__PURE__*/jsxs("div", {
26911
+ className: "flex-shrink-0 flex flex-row justify-end gap-2 px-6 py-4 border-t border-white/10",
26912
+ children: [/*#__PURE__*/jsx(Button, {
26913
+ title: "Export ZIP",
26914
+ onClick: handleExport,
26915
+ size: "sm"
26916
+ }), isShareable && /*#__PURE__*/jsx(Button, {
26917
+ title: "Publish",
26918
+ onClick: function onClick() {
26919
+ return setPublishOpen(true);
26920
+ },
26921
+ size: "sm"
26922
+ }), /*#__PURE__*/jsx(Button, {
26923
+ title: "Rename",
26924
+ onClick: function onClick() {
26925
+ return onStartRename(ws);
26926
+ },
26927
+ size: "sm"
26928
+ }), /*#__PURE__*/jsx(Button, {
26929
+ title: "Duplicate",
26930
+ onClick: function onClick() {
26931
+ return onDuplicate(ws);
26932
+ },
26933
+ size: "sm"
26934
+ }), /*#__PURE__*/jsx(Button, {
26935
+ title: "Delete",
26936
+ onClick: function onClick() {
26937
+ return onDelete(ws);
26938
+ },
26939
+ size: "sm"
26940
+ })]
26941
+ }), /*#__PURE__*/jsx(PublishDashboardModal, {
26942
+ isOpen: publishOpen,
26943
+ setIsOpen: setPublishOpen,
26944
+ appId: appId,
26945
+ workspaceId: ws.id,
26946
+ workspaceName: ws.name
26947
+ })]
26948
+ });
26949
+ };
26950
+
26951
+ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
26952
+ var dashboardPackage = _ref.dashboardPackage,
26953
+ appId = _ref.appId;
26954
+ var _useContext = useContext(ThemeContext),
26955
+ currentTheme = _useContext.currentTheme;
26956
+ var panelStyles = getStylesForItem(themeObjects.PANEL, currentTheme, {
26957
+ grow: false
26958
+ });
26959
+ var _useState = useState(null),
26960
+ _useState2 = _slicedToArray(_useState, 2),
26961
+ preview = _useState2[0],
26962
+ setPreview = _useState2[1];
26963
+ var _useState3 = useState(false),
26964
+ _useState4 = _slicedToArray(_useState3, 2),
26965
+ previewLoading = _useState4[0],
26966
+ setPreviewLoading = _useState4[1];
26967
+ var _useState5 = useState(false),
26968
+ _useState6 = _slicedToArray(_useState5, 2),
26969
+ isInstalling = _useState6[0],
26970
+ setIsInstalling = _useState6[1];
26971
+ var _useState7 = useState(null),
26972
+ _useState8 = _slicedToArray(_useState7, 2),
26973
+ installResult = _useState8[0],
26974
+ setInstallResult = _useState8[1];
26975
+ var pkg = dashboardPackage;
26976
+ if (!pkg) return null;
26977
+
26978
+ // Load preview data on mount
26979
+ // eslint-disable-next-line react-hooks/rules-of-hooks
26980
+ useEffect(function () {
26981
+ var _window$mainApi;
26982
+ if (!pkg.name) return;
26983
+ var cancelled = false;
26984
+ setPreviewLoading(true);
26985
+ setPreview(null);
26986
+ setInstallResult(null);
26987
+ (_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) {
26988
+ if (!cancelled) setPreview(result);
26989
+ })["catch"](function (err) {
26990
+ })["finally"](function () {
26991
+ if (!cancelled) setPreviewLoading(false);
26992
+ });
26993
+ return function () {
26994
+ cancelled = true;
26995
+ };
26996
+ }, [pkg.name]);
26997
+ function handleInstall() {
26998
+ return _handleInstall.apply(this, arguments);
26999
+ }
27000
+ function _handleInstall() {
27001
+ _handleInstall = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
27002
+ var _result$workspace, result, _t;
27003
+ return _regeneratorRuntime.wrap(function (_context) {
27004
+ while (1) switch (_context.prev = _context.next) {
27005
+ case 0:
27006
+ if (!(!appId || !pkg.name)) {
27007
+ _context.next = 1;
27008
+ break;
27009
+ }
27010
+ return _context.abrupt("return");
27011
+ case 1:
27012
+ setIsInstalling(true);
27013
+ setInstallResult(null);
27014
+ _context.prev = 2;
27015
+ _context.next = 3;
27016
+ return window.mainApi.dashboardConfig.installDashboardFromRegistry(appId, pkg.name);
27017
+ case 3:
27018
+ result = _context.sent;
27019
+ setInstallResult({
27020
+ status: result !== null && result !== void 0 && result.success ? "success" : "error",
27021
+ 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."
27022
+ });
27023
+ _context.next = 5;
27024
+ break;
27025
+ case 4:
27026
+ _context.prev = 4;
27027
+ _t = _context["catch"](2);
27028
+ setInstallResult({
27029
+ status: "error",
27030
+ message: _t.message || "Failed to install dashboard."
27031
+ });
27032
+ case 5:
27033
+ _context.prev = 5;
27034
+ setIsInstalling(false);
27035
+ return _context.finish(5);
27036
+ case 6:
27037
+ case "end":
27038
+ return _context.stop();
27039
+ }
27040
+ }, _callee, null, [[2, 4, 5, 6]]);
27041
+ }));
27042
+ return _handleInstall.apply(this, arguments);
27043
+ }
27044
+ var compatibility = preview === null || preview === void 0 ? void 0 : preview.compatibility;
27045
+ var widgetDeps = (preview === null || preview === void 0 ? void 0 : preview.widgets) || pkg.widgets || [];
27046
+ var providers = (preview === null || preview === void 0 ? void 0 : preview.providers) || [];
27047
+ var wiring = (preview === null || preview === void 0 ? void 0 : preview.wiring) || [];
27048
+ function getCompatIcon(status) {
27049
+ if (status === "installed") return {
27050
+ icon: "circle-check",
27051
+ color: "text-green-400"
27052
+ };
27053
+ if (status === "available") return {
27054
+ icon: "circle-down",
27055
+ color: "text-blue-400"
27056
+ };
27057
+ return {
27058
+ icon: "circle-xmark",
27059
+ color: "text-red-400"
27060
+ };
27061
+ }
27062
+ return /*#__PURE__*/jsxs("div", {
27063
+ className: "flex flex-col flex-1 min-h-0",
27064
+ children: [/*#__PURE__*/jsxs("div", {
27065
+ className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-6 ".concat(panelStyles.textColor || "text-gray-200"),
27066
+ children: [/*#__PURE__*/jsxs("div", {
27067
+ className: "flex flex-row items-center gap-3",
27068
+ children: [/*#__PURE__*/jsx("div", {
27069
+ className: "h-5 w-5 flex-shrink-0 flex items-center justify-center",
27070
+ children: /*#__PURE__*/jsx(FontAwesomeIcon, {
27071
+ icon: pkg.icon || "clone",
27072
+ className: "h-5 w-5"
27073
+ })
27074
+ }), /*#__PURE__*/jsxs("div", {
27075
+ children: [/*#__PURE__*/jsx(SubHeading3, {
27076
+ title: pkg.displayName || pkg.name,
27077
+ padding: false
27078
+ }), /*#__PURE__*/jsxs("div", {
27079
+ className: "flex items-center gap-2 mt-0.5",
27080
+ children: [/*#__PURE__*/jsxs("span", {
27081
+ className: "text-sm opacity-60",
27082
+ children: ["by ", pkg.author || "Unknown"]
27083
+ }), pkg.version && /*#__PURE__*/jsxs("span", {
27084
+ className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
27085
+ children: ["v", pkg.version]
27086
+ })]
27087
+ })]
27088
+ })]
27089
+ }), appId && /*#__PURE__*/jsx(StarRating, {
27090
+ appId: appId,
27091
+ packageName: pkg.name,
27092
+ interactive: false
27093
+ }), /*#__PURE__*/jsx("hr", {
27094
+ className: currentTheme["border-primary-medium"]
27095
+ }), pkg.description && /*#__PURE__*/jsx("p", {
27096
+ className: "text-sm",
27097
+ children: pkg.description
27098
+ }), pkg.tags && pkg.tags.length > 0 && /*#__PURE__*/jsx("div", {
27099
+ className: "flex flex-wrap gap-1",
27100
+ children: pkg.tags.map(function (tag) {
27101
+ return /*#__PURE__*/jsx("span", {
27102
+ className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-60"),
27103
+ children: tag
27104
+ }, tag);
27105
+ })
27106
+ }), /*#__PURE__*/jsxs("div", {
27107
+ children: [/*#__PURE__*/jsx("span", {
27108
+ className: "text-xs font-semibold opacity-50 mb-1 block",
27109
+ children: "REQUIRED WIDGETS"
27110
+ }), previewLoading ? /*#__PURE__*/jsxs("div", {
27111
+ className: "flex items-center gap-2 py-2",
27112
+ children: [/*#__PURE__*/jsx("div", {
27113
+ className: "animate-spin rounded-full h-4 w-4 border-b-2 border-blue-500"
27114
+ }), /*#__PURE__*/jsx("span", {
27115
+ className: "text-xs opacity-50",
27116
+ children: "Checking compatibility..."
27117
+ })]
27118
+ }) : /*#__PURE__*/jsx("div", {
27119
+ className: "space-y-1.5",
27120
+ children: widgetDeps.map(function (w, idx) {
27121
+ var _compatibility$widget;
27122
+ 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";
27123
+ var compat = getCompatIcon(status);
27124
+ return /*#__PURE__*/jsxs("div", {
27125
+ className: "p-2 rounded ".concat(currentTheme["bg-primary-medium"], " flex items-center gap-2"),
27126
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
27127
+ icon: compat.icon,
27128
+ className: "h-3.5 w-3.5 ".concat(compat.color)
27129
+ }), /*#__PURE__*/jsx("span", {
27130
+ className: "text-sm",
27131
+ children: w.displayName || w.name || w.packageName
27132
+ }), /*#__PURE__*/jsx("span", {
27133
+ className: "text-xs opacity-40 ml-auto",
27134
+ children: status === "installed" ? "Installed" : status === "available" ? "Will install" : "Unavailable"
27135
+ })]
27136
+ }, idx);
27137
+ })
27138
+ })]
27139
+ }), providers.length > 0 && /*#__PURE__*/jsxs("div", {
27140
+ children: [/*#__PURE__*/jsx("span", {
27141
+ className: "text-xs font-semibold opacity-50 mb-1 block",
27142
+ children: "REQUIRED PROVIDERS"
27143
+ }), /*#__PURE__*/jsx("div", {
27144
+ className: "space-y-1",
27145
+ children: providers.map(function (p, idx) {
27146
+ return /*#__PURE__*/jsxs("div", {
27147
+ className: "flex items-center gap-2",
27148
+ children: [/*#__PURE__*/jsx("span", {
27149
+ className: "text-xs px-1.5 py-0.5 rounded bg-blue-900/30 text-blue-400",
27150
+ children: p.type
27151
+ }), p.required && /*#__PURE__*/jsx("span", {
27152
+ className: "text-[10px] opacity-40",
27153
+ children: "Required"
27154
+ })]
27155
+ }, idx);
27156
+ })
27157
+ })]
27158
+ }), wiring.length > 0 && /*#__PURE__*/jsxs("div", {
27159
+ children: [/*#__PURE__*/jsx("span", {
27160
+ className: "text-xs font-semibold opacity-50 mb-1 block",
27161
+ children: "EVENT WIRING"
27162
+ }), /*#__PURE__*/jsx("div", {
27163
+ className: "space-y-1",
27164
+ children: wiring.map(function (w, idx) {
27165
+ return /*#__PURE__*/jsxs("div", {
27166
+ className: "text-xs p-2 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
27167
+ children: [/*#__PURE__*/jsx("span", {
27168
+ className: "font-medium",
27169
+ children: w.from || "Source"
27170
+ }), /*#__PURE__*/jsx(FontAwesomeIcon, {
27171
+ icon: "arrow-right",
27172
+ className: "h-2.5 w-2.5 mx-1.5 opacity-50"
27173
+ }), /*#__PURE__*/jsx("span", {
27174
+ className: "font-medium",
27175
+ children: w.to || "Target"
27176
+ }), w.event && /*#__PURE__*/jsxs("span", {
27177
+ className: "opacity-50 ml-1.5",
27178
+ children: ["(", w.event, ")"]
27179
+ })]
27180
+ }, idx);
27181
+ })
27182
+ })]
27183
+ }), installResult && /*#__PURE__*/jsx("div", {
27184
+ className: "p-2 rounded border ".concat(installResult.status === "success" ? "bg-green-900/20 border-green-700" : "bg-red-900/30 border-red-700"),
27185
+ children: /*#__PURE__*/jsxs("div", {
27186
+ className: "flex items-center gap-2",
27187
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
27188
+ icon: installResult.status === "success" ? "circle-check" : "circle-xmark",
27189
+ className: "h-4 w-4 ".concat(installResult.status === "success" ? "text-green-400" : "text-red-400")
27190
+ }), /*#__PURE__*/jsx("span", {
27191
+ className: "text-sm ".concat(installResult.status === "error" ? "text-red-400" : ""),
27192
+ children: installResult.message
27193
+ })]
27194
+ })
27195
+ })]
27196
+ }), (installResult === null || installResult === void 0 ? void 0 : installResult.status) !== "success" && /*#__PURE__*/jsx("div", {
27197
+ className: "flex items-center justify-end px-6 py-3 border-t ".concat(currentTheme["border-primary-medium"]),
27198
+ children: /*#__PURE__*/jsx(Button, {
27199
+ title: isInstalling ? "Installing..." : "Install Dashboard",
27200
+ bgColor: "bg-blue-600",
27201
+ hoverBackgroundColor: isInstalling ? "" : "hover:bg-blue-700",
27202
+ textSize: "text-sm",
27203
+ padding: "py-1.5 px-4",
27204
+ onClick: handleInstall,
27205
+ disabled: isInstalling
27206
+ })
27207
+ })]
27208
+ });
27209
+ };
27210
+
27211
+ var DiscoverDashboardsDetail = function DiscoverDashboardsDetail(_ref) {
27212
+ var onBack = _ref.onBack,
27213
+ appId = _ref.appId;
27214
+ var _useContext = useContext(ThemeContext),
27215
+ currentTheme = _useContext.currentTheme;
27216
+ var panelStyles = getStylesForItem(themeObjects.PANEL, currentTheme, {
27217
+ grow: false
27218
+ });
27219
+ var _useState = useState([]),
27220
+ _useState2 = _slicedToArray(_useState, 2),
27221
+ packages = _useState2[0],
27222
+ setPackages = _useState2[1];
27223
+ var _useState3 = useState(false),
27224
+ _useState4 = _slicedToArray(_useState3, 2),
27225
+ isLoading = _useState4[0],
27226
+ setIsLoading = _useState4[1];
27227
+ var _useState5 = useState(null),
27228
+ _useState6 = _slicedToArray(_useState5, 2),
27229
+ error = _useState6[0],
27230
+ setError = _useState6[1];
27231
+ var _useState7 = useState(""),
27232
+ _useState8 = _slicedToArray(_useState7, 2),
27233
+ searchQuery = _useState8[0],
27234
+ setSearchQuery = _useState8[1];
27235
+ var _useState9 = useState(null),
27236
+ _useState0 = _slicedToArray(_useState9, 2),
27237
+ selectedPackageName = _useState0[0],
27238
+ setSelectedPackageName = _useState0[1];
27239
+ var search = useCallback(/*#__PURE__*/function () {
27240
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(query) {
27241
+ var _window$mainApi;
27242
+ var result, _t;
27243
+ return _regeneratorRuntime.wrap(function (_context) {
27244
+ while (1) switch (_context.prev = _context.next) {
27245
+ case 0:
27246
+ if ((_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && (_window$mainApi = _window$mainApi.registry) !== null && _window$mainApi !== void 0 && _window$mainApi.searchDashboards) {
27247
+ _context.next = 1;
27248
+ break;
27249
+ }
27250
+ setPackages([]);
27251
+ return _context.abrupt("return");
27252
+ case 1:
27253
+ setIsLoading(true);
27254
+ setError(null);
27255
+ _context.prev = 2;
27256
+ _context.next = 3;
27257
+ return window.mainApi.registry.searchDashboards(query || "", {});
27258
+ case 3:
27259
+ result = _context.sent;
27260
+ setPackages((result === null || result === void 0 ? void 0 : result.packages) || []);
27261
+ _context.next = 5;
27262
+ break;
27263
+ case 4:
27264
+ _context.prev = 4;
27265
+ _t = _context["catch"](2);
27266
+ setError(_t.message || "Failed to search dashboard registry");
27267
+ setPackages([]);
27268
+ case 5:
27269
+ _context.prev = 5;
27270
+ setIsLoading(false);
27271
+ return _context.finish(5);
27272
+ case 6:
27273
+ case "end":
27274
+ return _context.stop();
27275
+ }
27276
+ }, _callee, null, [[2, 4, 5, 6]]);
27277
+ }));
27278
+ return function (_x) {
27279
+ return _ref2.apply(this, arguments);
27280
+ };
27281
+ }(), []);
27282
+
27283
+ // Debounce search on query changes
27284
+ useEffect(function () {
27285
+ var timer = setTimeout(function () {
27286
+ search(searchQuery);
27287
+ }, 300);
27288
+ return function () {
27289
+ return clearTimeout(timer);
27290
+ };
27291
+ // eslint-disable-next-line react-hooks/exhaustive-deps
27292
+ }, [searchQuery]);
27293
+ var retry = function retry() {
27294
+ return search(searchQuery);
27295
+ };
27296
+ var selectedPackage = selectedPackageName ? packages.find(function (p) {
27297
+ return p.name === selectedPackageName;
27298
+ }) : null;
27299
+
27300
+ // If a package is selected, show its detail inline
27301
+ if (selectedPackage) {
27302
+ return /*#__PURE__*/jsxs("div", {
27303
+ className: "flex flex-col flex-1 min-h-0",
27304
+ children: [/*#__PURE__*/jsx("div", {
27305
+ className: "flex-shrink-0 px-4 pt-4",
27306
+ children: /*#__PURE__*/jsxs("button", {
27307
+ type: "button",
27308
+ onClick: function onClick() {
27309
+ return setSelectedPackageName(null);
27310
+ },
27311
+ className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
26549
27312
  children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
26550
- icon: "th-large",
26551
- className: "h-3 w-3 opacity-50"
26552
- }), /*#__PURE__*/jsxs("span", {
26553
- className: "text-sm opacity-70",
26554
- children: [widgetCount, " widget", widgetCount !== 1 ? "s" : ""]
27313
+ icon: "arrow-left",
27314
+ className: "h-3 w-3"
27315
+ }), /*#__PURE__*/jsx("span", {
27316
+ children: "Back"
26555
27317
  })]
26556
- })]
26557
- }), /*#__PURE__*/jsx(LayoutPreview, {
26558
- layout: ws.layout
27318
+ })
27319
+ }), /*#__PURE__*/jsx(RegistryDashboardDetail, {
27320
+ dashboardPackage: selectedPackage,
27321
+ appId: appId
26559
27322
  })]
26560
- }), !isEditing && /*#__PURE__*/jsxs("div", {
26561
- className: "flex-shrink-0 flex flex-row justify-end gap-2 px-6 py-4 border-t border-white/10",
26562
- children: [/*#__PURE__*/jsx(Button, {
26563
- title: "Rename",
26564
- onClick: function onClick() {
26565
- return onStartRename(ws);
26566
- },
26567
- size: "sm"
26568
- }), /*#__PURE__*/jsx(Button, {
26569
- title: "Duplicate",
26570
- onClick: function onClick() {
26571
- return onDuplicate(ws);
26572
- },
26573
- size: "sm"
27323
+ });
27324
+ }
27325
+
27326
+ // Package list view
27327
+ var listBody;
27328
+ if (isLoading) {
27329
+ listBody = /*#__PURE__*/jsx("div", {
27330
+ className: "flex items-center justify-center py-12",
27331
+ children: /*#__PURE__*/jsxs("div", {
27332
+ className: "text-center",
27333
+ children: [/*#__PURE__*/jsx("div", {
27334
+ className: "animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500 mx-auto mb-3"
27335
+ }), /*#__PURE__*/jsx(Paragraph, {
27336
+ className: "text-sm opacity-50",
27337
+ children: "Loading dashboards..."
27338
+ })]
27339
+ })
27340
+ });
27341
+ } else if (error) {
27342
+ listBody = /*#__PURE__*/jsxs("div", {
27343
+ className: "px-4 py-8 text-center",
27344
+ children: [/*#__PURE__*/jsx(Paragraph, {
27345
+ className: "text-sm text-red-400 mb-3",
27346
+ children: error
26574
27347
  }), /*#__PURE__*/jsx(Button, {
26575
- title: "Delete",
26576
- onClick: function onClick() {
26577
- return onDelete(ws);
26578
- },
26579
- size: "sm"
27348
+ title: "Retry",
27349
+ bgColor: "bg-gray-700",
27350
+ hoverBackgroundColor: "hover:bg-gray-600",
27351
+ textSize: "text-sm",
27352
+ padding: "py-1 px-3",
27353
+ onClick: retry
26580
27354
  })]
27355
+ });
27356
+ } else if (packages.length === 0) {
27357
+ listBody = /*#__PURE__*/jsx("div", {
27358
+ className: "px-4 py-8 text-center",
27359
+ children: /*#__PURE__*/jsx(Paragraph, {
27360
+ className: "text-sm opacity-50",
27361
+ children: searchQuery ? "No dashboards match your search." : "No dashboard packages available."
27362
+ })
27363
+ });
27364
+ } else {
27365
+ listBody = /*#__PURE__*/jsx("div", {
27366
+ className: "space-y-1",
27367
+ children: packages.map(function (pkg) {
27368
+ var widgetCount = (pkg.widgets || []).length;
27369
+ return /*#__PURE__*/jsx(Sidebar.Item, {
27370
+ icon: /*#__PURE__*/jsx(FontAwesomeIcon, {
27371
+ icon: pkg.icon || "clone",
27372
+ className: "h-3.5 w-3.5"
27373
+ }),
27374
+ onClick: function onClick() {
27375
+ return setSelectedPackageName(pkg.name);
27376
+ },
27377
+ badge: widgetCount > 0 ? "".concat(widgetCount) : undefined,
27378
+ children: pkg.displayName || pkg.name
27379
+ }, pkg.name);
27380
+ })
27381
+ });
27382
+ }
27383
+ return /*#__PURE__*/jsxs("div", {
27384
+ className: "flex flex-col flex-1 min-h-0 ".concat(panelStyles.textColor || "text-gray-200"),
27385
+ children: [/*#__PURE__*/jsx("div", {
27386
+ className: "flex-shrink-0 px-4 pt-4",
27387
+ children: /*#__PURE__*/jsxs("button", {
27388
+ type: "button",
27389
+ onClick: onBack,
27390
+ className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
27391
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
27392
+ icon: "arrow-left",
27393
+ className: "h-3 w-3"
27394
+ }), /*#__PURE__*/jsx("span", {
27395
+ children: "Back"
27396
+ })]
27397
+ })
27398
+ }), /*#__PURE__*/jsx("div", {
27399
+ className: "flex-shrink-0 px-4 py-3",
27400
+ children: /*#__PURE__*/jsx(SearchInput, {
27401
+ value: searchQuery,
27402
+ onChange: setSearchQuery,
27403
+ placeholder: "Search dashboards...",
27404
+ inputClassName: "py-1.5 text-xs"
27405
+ })
27406
+ }), /*#__PURE__*/jsx("div", {
27407
+ className: "flex-1 min-h-0 overflow-y-auto px-2",
27408
+ children: listBody
27409
+ }), !isLoading && !error && packages.length > 0 && /*#__PURE__*/jsxs("div", {
27410
+ className: "flex-shrink-0 px-4 py-2 text-[10px] opacity-40 border-t border-white/10",
27411
+ children: [packages.length, " dashboard", packages.length !== 1 ? "s" : ""]
26581
27412
  })]
26582
27413
  });
26583
27414
  };
@@ -26594,7 +27425,11 @@ var DashboardsSection = function DashboardsSection(_ref) {
26594
27425
  _ref$credentials = _ref.credentials,
26595
27426
  credentials = _ref$credentials === void 0 ? null : _ref$credentials,
26596
27427
  _ref$onReloadWorkspac = _ref.onReloadWorkspaces,
26597
- onReloadWorkspaces = _ref$onReloadWorkspac === void 0 ? null : _ref$onReloadWorkspac;
27428
+ onReloadWorkspaces = _ref$onReloadWorkspac === void 0 ? null : _ref$onReloadWorkspac,
27429
+ _ref$createRequested = _ref.createRequested,
27430
+ createRequested = _ref$createRequested === void 0 ? false : _ref$createRequested,
27431
+ _ref$onCreateAcknowle = _ref.onCreateAcknowledged,
27432
+ onCreateAcknowledged = _ref$onCreateAcknowle === void 0 ? null : _ref$onCreateAcknowle;
26598
27433
  var _useState = useState(null),
26599
27434
  _useState2 = _slicedToArray(_useState, 2),
26600
27435
  selectedId = _useState2[0],
@@ -26619,6 +27454,15 @@ var DashboardsSection = function DashboardsSection(_ref) {
26619
27454
  _useState10 = _slicedToArray(_useState1, 2),
26620
27455
  viewMode = _useState10[0],
26621
27456
  setViewMode = _useState10[1];
27457
+ // null | "marketplace" | "import-result"
27458
+ var _useState11 = useState(null),
27459
+ _useState12 = _slicedToArray(_useState11, 2),
27460
+ installMode = _useState12[0],
27461
+ setInstallMode = _useState12[1];
27462
+ var _useState13 = useState(null),
27463
+ _useState14 = _slicedToArray(_useState13, 2),
27464
+ importResult = _useState14[0],
27465
+ setImportResult = _useState14[1];
26622
27466
  var appId = credentials === null || credentials === void 0 ? void 0 : credentials.appId;
26623
27467
  var _useContext = useContext(ThemeContext),
26624
27468
  currentTheme = _useContext.currentTheme;
@@ -26698,6 +27542,84 @@ var DashboardsSection = function DashboardsSection(_ref) {
26698
27542
  setDeleteTarget(null);
26699
27543
  });
26700
27544
  }
27545
+
27546
+ // Respond to external create trigger from header button (marketplace)
27547
+ var prevCreateRequested = useRef(false);
27548
+ useEffect(function () {
27549
+ if (createRequested && !prevCreateRequested.current) {
27550
+ setSelectedId(null);
27551
+ setInstallMode("marketplace");
27552
+ setImportResult(null);
27553
+ }
27554
+ prevCreateRequested.current = createRequested;
27555
+ if (createRequested && onCreateAcknowledged) {
27556
+ onCreateAcknowledged();
27557
+ }
27558
+ // eslint-disable-next-line react-hooks/exhaustive-deps
27559
+ }, [createRequested]);
27560
+ function handleImport() {
27561
+ return _handleImport.apply(this, arguments);
27562
+ }
27563
+ function _handleImport() {
27564
+ _handleImport = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
27565
+ var result, _result$workspace, _t;
27566
+ return _regeneratorRuntime.wrap(function (_context) {
27567
+ while (1) switch (_context.prev = _context.next) {
27568
+ case 0:
27569
+ if (appId) {
27570
+ _context.next = 1;
27571
+ break;
27572
+ }
27573
+ return _context.abrupt("return");
27574
+ case 1:
27575
+ setInstallMode("import-result");
27576
+ setImportResult({
27577
+ status: "loading",
27578
+ message: "Importing dashboard..."
27579
+ });
27580
+ _context.prev = 2;
27581
+ _context.next = 3;
27582
+ return window.mainApi.dashboardConfig.importDashboardConfig(appId);
27583
+ case 3:
27584
+ result = _context.sent;
27585
+ if (result) {
27586
+ _context.next = 4;
27587
+ break;
27588
+ }
27589
+ // User cancelled the file picker
27590
+ setInstallMode(null);
27591
+ setImportResult(null);
27592
+ return _context.abrupt("return");
27593
+ case 4:
27594
+ if (result.success) {
27595
+ setImportResult({
27596
+ status: "success",
27597
+ message: "Dashboard \"".concat(((_result$workspace = result.workspace) === null || _result$workspace === void 0 ? void 0 : _result$workspace.name) || "Untitled", "\" imported successfully.")
27598
+ });
27599
+ onReloadWorkspaces && onReloadWorkspaces();
27600
+ } else {
27601
+ setImportResult({
27602
+ status: "error",
27603
+ message: result.error || "Import failed."
27604
+ });
27605
+ }
27606
+ _context.next = 6;
27607
+ break;
27608
+ case 5:
27609
+ _context.prev = 5;
27610
+ _t = _context["catch"](2);
27611
+ setImportResult({
27612
+ status: "error",
27613
+ message: _t.message || "Failed to import dashboard."
27614
+ });
27615
+ case 6:
27616
+ case "end":
27617
+ return _context.stop();
27618
+ }
27619
+ }, _callee, null, [[2, 5]]);
27620
+ }));
27621
+ return _handleImport.apply(this, arguments);
27622
+ }
26701
27623
  var selectedWorkspace = workspaces.find(function (ws) {
26702
27624
  return ws.id === selectedId;
26703
27625
  });
@@ -26747,13 +27669,33 @@ var DashboardsSection = function DashboardsSection(_ref) {
26747
27669
  className: "flex flex-col h-full",
26748
27670
  children: [/*#__PURE__*/jsxs("div", {
26749
27671
  className: "flex-shrink-0 flex flex-col gap-2 px-3 pt-3 pb-2 ".concat(headerStyles.backgroundColor || ""),
26750
- children: [/*#__PURE__*/jsx(SearchInput, {
26751
- value: searchQuery,
26752
- onChange: setSearchQuery,
26753
- placeholder: "Search dashboards..."
27672
+ children: [/*#__PURE__*/jsxs("div", {
27673
+ className: "flex items-center gap-2",
27674
+ children: [/*#__PURE__*/jsx("div", {
27675
+ className: "flex-1",
27676
+ children: /*#__PURE__*/jsx(SearchInput, {
27677
+ value: searchQuery,
27678
+ onChange: setSearchQuery,
27679
+ placeholder: "Search dashboards..."
27680
+ })
27681
+ }), /*#__PURE__*/jsx(ButtonIcon, {
27682
+ icon: "file-import",
27683
+ onClick: handleImport,
27684
+ size: "sm",
27685
+ title: "Import dashboard"
27686
+ })]
26754
27687
  }), /*#__PURE__*/jsx(Tabs3, {
26755
- value: viewMode,
26756
- onValueChange: setViewMode,
27688
+ value: installMode === "marketplace" ? "marketplace" : viewMode,
27689
+ onValueChange: function onValueChange(val) {
27690
+ if (val === "marketplace") {
27691
+ setInstallMode("marketplace");
27692
+ setSelectedId(null);
27693
+ } else {
27694
+ setInstallMode(null);
27695
+ setImportResult(null);
27696
+ setViewMode(val);
27697
+ }
27698
+ },
26757
27699
  backgroundColor: "bg-transparent",
26758
27700
  spacing: "p-0",
26759
27701
  children: /*#__PURE__*/jsxs(Tabs3.List, {
@@ -26767,6 +27709,10 @@ var DashboardsSection = function DashboardsSection(_ref) {
26767
27709
  value: "alphabetical",
26768
27710
  className: "flex-1",
26769
27711
  children: "A-Z"
27712
+ }), /*#__PURE__*/jsx(Tabs3.Trigger, {
27713
+ value: "marketplace",
27714
+ className: "flex-1",
27715
+ children: "Marketplace"
26770
27716
  })]
26771
27717
  })
26772
27718
  })]
@@ -26780,26 +27726,68 @@ var DashboardsSection = function DashboardsSection(_ref) {
26780
27726
  })
26781
27727
  })]
26782
27728
  });
26783
- var detailContent = selectedWorkspace ? /*#__PURE__*/jsx(DashboardDetail, {
26784
- workspace: selectedWorkspace,
26785
- menuItems: menuItems,
26786
- editingId: editingId,
26787
- editName: editName,
26788
- setEditName: setEditName,
26789
- onStartRename: handleStartRename,
26790
- onSaveRename: handleSaveRename,
26791
- onCancelRename: function onCancelRename() {
26792
- setEditingId(null);
26793
- setEditName("");
26794
- },
26795
- onDuplicate: handleDuplicate,
26796
- onDelete: function onDelete(ws) {
26797
- return setDeleteTarget(ws);
26798
- },
26799
- dashApi: dashApi,
26800
- credentials: credentials,
26801
- onReloadWorkspaces: onReloadWorkspaces
26802
- }) : null;
27729
+ var detailContent = null;
27730
+ if (installMode === "marketplace") {
27731
+ detailContent = /*#__PURE__*/jsx(DiscoverDashboardsDetail, {
27732
+ onBack: function onBack() {
27733
+ setInstallMode(null);
27734
+ setViewMode("grouped");
27735
+ },
27736
+ appId: appId
27737
+ });
27738
+ } else if (installMode === "import-result") {
27739
+ detailContent = /*#__PURE__*/jsxs("div", {
27740
+ className: "flex flex-col flex-1 min-h-0 p-6 space-y-4",
27741
+ children: [(importResult === null || importResult === void 0 ? void 0 : importResult.status) === "loading" && /*#__PURE__*/jsxs("div", {
27742
+ className: "flex items-center gap-3",
27743
+ children: [/*#__PURE__*/jsx("div", {
27744
+ className: "animate-spin rounded-full h-5 w-5 border-b-2 border-blue-500"
27745
+ }), /*#__PURE__*/jsx("span", {
27746
+ className: "text-sm opacity-70",
27747
+ children: importResult.message
27748
+ })]
27749
+ }), (importResult === null || importResult === void 0 ? void 0 : importResult.status) === "success" && /*#__PURE__*/jsxs("div", {
27750
+ className: "flex items-center gap-2",
27751
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
27752
+ icon: "circle-check",
27753
+ className: "h-4 w-4 text-green-400"
27754
+ }), /*#__PURE__*/jsx("span", {
27755
+ className: "text-sm",
27756
+ children: importResult.message
27757
+ })]
27758
+ }), (importResult === null || importResult === void 0 ? void 0 : importResult.status) === "error" && /*#__PURE__*/jsxs("div", {
27759
+ className: "flex items-center gap-2",
27760
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
27761
+ icon: "circle-xmark",
27762
+ className: "h-4 w-4 text-red-400"
27763
+ }), /*#__PURE__*/jsx("span", {
27764
+ className: "text-sm text-red-400",
27765
+ children: importResult.message
27766
+ })]
27767
+ })]
27768
+ });
27769
+ } else if (selectedWorkspace) {
27770
+ detailContent = /*#__PURE__*/jsx(DashboardDetail, {
27771
+ workspace: selectedWorkspace,
27772
+ menuItems: menuItems,
27773
+ editingId: editingId,
27774
+ editName: editName,
27775
+ setEditName: setEditName,
27776
+ onStartRename: handleStartRename,
27777
+ onSaveRename: handleSaveRename,
27778
+ onCancelRename: function onCancelRename() {
27779
+ setEditingId(null);
27780
+ setEditName("");
27781
+ },
27782
+ onDuplicate: handleDuplicate,
27783
+ onDelete: function onDelete(ws) {
27784
+ return setDeleteTarget(ws);
27785
+ },
27786
+ dashApi: dashApi,
27787
+ credentials: credentials,
27788
+ onReloadWorkspaces: onReloadWorkspaces
27789
+ });
27790
+ }
26803
27791
  return /*#__PURE__*/jsxs(Fragment, {
26804
27792
  children: [/*#__PURE__*/jsx(SectionLayout, {
26805
27793
  listContent: listContent,
@@ -32130,9 +33118,9 @@ var AppSettingsModal = function AppSettingsModal(_ref) {
32130
33118
  children: [/*#__PURE__*/jsx(SubHeading2, {
32131
33119
  title: activeDef.label,
32132
33120
  padding: false
32133
- }), (activeSection === "folders" || activeSection === "providers" || activeSection === "themes" || activeSection === "widgets") && /*#__PURE__*/jsx(ButtonIcon3, {
33121
+ }), (activeSection === "dashboards" || activeSection === "folders" || activeSection === "providers" || activeSection === "themes" || activeSection === "widgets") && /*#__PURE__*/jsx(ButtonIcon3, {
32134
33122
  icon: "plus",
32135
- text: activeSection === "folders" ? "New Folder" : activeSection === "providers" ? "New Provider" : activeSection === "widgets" ? "Install Widgets" : "New Theme",
33123
+ text: activeSection === "dashboards" ? "Marketplace" : activeSection === "folders" ? "New Folder" : activeSection === "providers" ? "New Provider" : activeSection === "widgets" ? "Install Widgets" : "New Theme",
32136
33124
  onClick: function onClick() {
32137
33125
  return setCreateRequested(true);
32138
33126
  },
@@ -32149,7 +33137,11 @@ var AppSettingsModal = function AppSettingsModal(_ref) {
32149
33137
  menuItems: menuItems,
32150
33138
  dashApi: dashApi,
32151
33139
  credentials: credentials,
32152
- onReloadWorkspaces: onReloadWorkspaces
33140
+ onReloadWorkspaces: onReloadWorkspaces,
33141
+ createRequested: createRequested,
33142
+ onCreateAcknowledged: function onCreateAcknowledged() {
33143
+ return setCreateRequested(false);
33144
+ }
32153
33145
  }), activeSection === "folders" && /*#__PURE__*/jsx(FoldersSection, {
32154
33146
  menuItems: menuItems,
32155
33147
  workspaces: workspaces,