@trops/dash-core 0.1.116 → 0.1.117

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
@@ -10,13 +10,13 @@ var _classCallCheck = require('@babel/runtime/helpers/classCallCheck');
10
10
  var _createClass = require('@babel/runtime/helpers/createClass');
11
11
  var jsxRuntime = require('react/jsx-runtime');
12
12
  var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
13
+ var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator');
14
+ var _regeneratorRuntime = require('@babel/runtime/regenerator');
13
15
  var react = require('@headlessui/react');
14
16
  var solid = require('@heroicons/react/20/solid');
15
17
  var clsx = require('clsx');
16
18
  var reactDnd = require('react-dnd');
17
19
  var reactDndHtml5Backend = require('react-dnd-html5-backend');
18
- var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator');
19
- var _regeneratorRuntime = require('@babel/runtime/regenerator');
20
20
  var _possibleConstructorReturn = require('@babel/runtime/helpers/possibleConstructorReturn');
21
21
  var _getPrototypeOf = require('@babel/runtime/helpers/getPrototypeOf');
22
22
  var _inherits = require('@babel/runtime/helpers/inherits');
@@ -3291,6 +3291,642 @@ var FolderDetail = function FolderDetail(_ref) {
3291
3291
  });
3292
3292
  };
3293
3293
 
3294
+ var OptionCard$1 = function OptionCard(_ref) {
3295
+ var icon = _ref.icon,
3296
+ title = _ref.title,
3297
+ description = _ref.description,
3298
+ onClick = _ref.onClick;
3299
+ return /*#__PURE__*/jsxRuntime.jsxs("button", {
3300
+ type: "button",
3301
+ onClick: onClick,
3302
+ className: "w-full flex flex-row items-center gap-4 p-4 rounded-lg text-left transition-all bg-gray-700/50 hover:bg-gray-700 hover:ring-1 hover:ring-gray-600",
3303
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
3304
+ className: "flex-shrink-0 h-8 w-8 flex items-center justify-center text-gray-400",
3305
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
3306
+ icon: icon,
3307
+ className: "h-5 w-5"
3308
+ })
3309
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
3310
+ className: "flex flex-col min-w-0",
3311
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
3312
+ className: "text-sm font-medium text-gray-200",
3313
+ children: title
3314
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
3315
+ className: "text-xs text-gray-500 mt-0.5",
3316
+ children: description
3317
+ })]
3318
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
3319
+ className: "flex-shrink-0 ml-auto text-gray-600",
3320
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
3321
+ icon: "chevron-right",
3322
+ className: "h-3 w-3"
3323
+ })
3324
+ })]
3325
+ });
3326
+ };
3327
+ var CreationMethodPicker = function CreationMethodPicker(_ref2) {
3328
+ var onSelect = _ref2.onSelect;
3329
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
3330
+ className: "flex flex-row w-full h-full",
3331
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
3332
+ className: "flex flex-col w-1/3 p-6 py-10 space-y-4 justify-start",
3333
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Heading, {
3334
+ title: "New Dashboard",
3335
+ padding: false,
3336
+ textColor: "text-gray-300"
3337
+ }), /*#__PURE__*/jsxRuntime.jsx("p", {
3338
+ className: "text-base font-normal text-gray-400",
3339
+ children: "Choose how you'd like to create your new dashboard."
3340
+ })]
3341
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
3342
+ className: "flex flex-col w-2/3 p-6 pt-10 space-y-3",
3343
+ children: [/*#__PURE__*/jsxRuntime.jsx(OptionCard$1, {
3344
+ icon: "plus",
3345
+ title: "New Dashboard",
3346
+ description: "Start from a blank template and customize your layout",
3347
+ onClick: function onClick() {
3348
+ return onSelect("template");
3349
+ }
3350
+ }), /*#__PURE__*/jsxRuntime.jsx(OptionCard$1, {
3351
+ icon: "file-zipper",
3352
+ title: "Import from File",
3353
+ description: "Import a dashboard from a .zip file on your computer",
3354
+ onClick: function onClick() {
3355
+ return onSelect("import");
3356
+ }
3357
+ }), /*#__PURE__*/jsxRuntime.jsx(OptionCard$1, {
3358
+ icon: "compass",
3359
+ title: "Search Registry",
3360
+ description: "Browse and install dashboards from the online registry",
3361
+ onClick: function onClick() {
3362
+ return onSelect("registry");
3363
+ }
3364
+ })]
3365
+ })]
3366
+ });
3367
+ };
3368
+
3369
+ var StarRating = function StarRating(_ref) {
3370
+ var appId = _ref.appId,
3371
+ packageName = _ref.packageName,
3372
+ _ref$interactive = _ref.interactive,
3373
+ interactive = _ref$interactive === void 0 ? true : _ref$interactive;
3374
+ var _useContext = React.useContext(DashReact.ThemeContext),
3375
+ currentTheme = _useContext.currentTheme;
3376
+ var _useState = React.useState(0),
3377
+ _useState2 = _slicedToArray(_useState, 2),
3378
+ rating = _useState2[0],
3379
+ setRating = _useState2[1];
3380
+ var _useState3 = React.useState(0),
3381
+ _useState4 = _slicedToArray(_useState3, 2),
3382
+ hoverRating = _useState4[0],
3383
+ setHoverRating = _useState4[1];
3384
+ var _useState5 = React.useState(true),
3385
+ _useState6 = _slicedToArray(_useState5, 2),
3386
+ loading = _useState6[0],
3387
+ setLoading = _useState6[1];
3388
+ React.useEffect(function () {
3389
+ var _window$mainApi;
3390
+ if (!appId || !packageName) return;
3391
+ var cancelled = false;
3392
+ setLoading(true);
3393
+ (_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) {
3394
+ if (!cancelled && result !== null && result !== void 0 && result.rating) {
3395
+ setRating(result.rating);
3396
+ }
3397
+ })["catch"](function () {})["finally"](function () {
3398
+ if (!cancelled) setLoading(false);
3399
+ });
3400
+ return function () {
3401
+ cancelled = true;
3402
+ };
3403
+ }, [appId, packageName]);
3404
+ function handleClick(_x) {
3405
+ return _handleClick.apply(this, arguments);
3406
+ }
3407
+ function _handleClick() {
3408
+ _handleClick = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(value) {
3409
+ var newRating, _window$mainApi2;
3410
+ return _regeneratorRuntime.wrap(function (_context) {
3411
+ while (1) switch (_context.prev = _context.next) {
3412
+ case 0:
3413
+ if (!(!interactive || !appId || !packageName)) {
3414
+ _context.next = 1;
3415
+ break;
3416
+ }
3417
+ return _context.abrupt("return");
3418
+ case 1:
3419
+ newRating = value === rating ? 0 : value;
3420
+ setRating(newRating);
3421
+ _context.prev = 2;
3422
+ _context.next = 3;
3423
+ 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);
3424
+ case 3:
3425
+ _context.next = 5;
3426
+ break;
3427
+ case 4:
3428
+ _context.prev = 4;
3429
+ _context["catch"](2);
3430
+ case 5:
3431
+ case "end":
3432
+ return _context.stop();
3433
+ }
3434
+ }, _callee, null, [[2, 4]]);
3435
+ }));
3436
+ return _handleClick.apply(this, arguments);
3437
+ }
3438
+ if (loading) return null;
3439
+ var displayRating = hoverRating || rating;
3440
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
3441
+ className: "flex items-center gap-0.5",
3442
+ onMouseLeave: function onMouseLeave() {
3443
+ return setHoverRating(0);
3444
+ },
3445
+ children: [1, 2, 3, 4, 5].map(function (star) {
3446
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
3447
+ type: "button",
3448
+ disabled: !interactive,
3449
+ onClick: function onClick() {
3450
+ return handleClick(star);
3451
+ },
3452
+ onMouseEnter: function onMouseEnter() {
3453
+ return interactive && setHoverRating(star);
3454
+ },
3455
+ className: "p-0.5 transition-colors ".concat(interactive ? "cursor-pointer hover:scale-110" : "cursor-default"),
3456
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
3457
+ icon: star <= displayRating ? "star" : ["far", "star"],
3458
+ className: "h-3.5 w-3.5 ".concat(star <= displayRating ? "text-yellow-400" : currentTheme["text-primary-medium"] || "text-gray-500")
3459
+ })
3460
+ }, star);
3461
+ })
3462
+ });
3463
+ };
3464
+
3465
+ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
3466
+ var dashboardPackage = _ref.dashboardPackage,
3467
+ appId = _ref.appId;
3468
+ var _useContext = React.useContext(DashReact.ThemeContext),
3469
+ currentTheme = _useContext.currentTheme;
3470
+ var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
3471
+ grow: false
3472
+ });
3473
+ var _useState = React.useState(null),
3474
+ _useState2 = _slicedToArray(_useState, 2),
3475
+ preview = _useState2[0],
3476
+ setPreview = _useState2[1];
3477
+ var _useState3 = React.useState(false),
3478
+ _useState4 = _slicedToArray(_useState3, 2),
3479
+ previewLoading = _useState4[0],
3480
+ setPreviewLoading = _useState4[1];
3481
+ var _useState5 = React.useState(false),
3482
+ _useState6 = _slicedToArray(_useState5, 2),
3483
+ isInstalling = _useState6[0],
3484
+ setIsInstalling = _useState6[1];
3485
+ var _useState7 = React.useState(null),
3486
+ _useState8 = _slicedToArray(_useState7, 2),
3487
+ installResult = _useState8[0],
3488
+ setInstallResult = _useState8[1];
3489
+ var pkg = dashboardPackage;
3490
+ if (!pkg) return null;
3491
+
3492
+ // Load preview data on mount
3493
+ // eslint-disable-next-line react-hooks/rules-of-hooks
3494
+ React.useEffect(function () {
3495
+ var _window$mainApi;
3496
+ if (!pkg.name) return;
3497
+ var cancelled = false;
3498
+ setPreviewLoading(true);
3499
+ setPreview(null);
3500
+ setInstallResult(null);
3501
+ (_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) {
3502
+ if (!cancelled) setPreview(result);
3503
+ })["catch"](function (err) {
3504
+ })["finally"](function () {
3505
+ if (!cancelled) setPreviewLoading(false);
3506
+ });
3507
+ return function () {
3508
+ cancelled = true;
3509
+ };
3510
+ }, [pkg.name]);
3511
+ function handleInstall() {
3512
+ return _handleInstall.apply(this, arguments);
3513
+ }
3514
+ function _handleInstall() {
3515
+ _handleInstall = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
3516
+ var _result$workspace, result, _t;
3517
+ return _regeneratorRuntime.wrap(function (_context) {
3518
+ while (1) switch (_context.prev = _context.next) {
3519
+ case 0:
3520
+ if (!(!appId || !pkg.name)) {
3521
+ _context.next = 1;
3522
+ break;
3523
+ }
3524
+ return _context.abrupt("return");
3525
+ case 1:
3526
+ setIsInstalling(true);
3527
+ setInstallResult(null);
3528
+ _context.prev = 2;
3529
+ _context.next = 3;
3530
+ return window.mainApi.dashboardConfig.installDashboardFromRegistry(appId, pkg.name);
3531
+ case 3:
3532
+ result = _context.sent;
3533
+ setInstallResult({
3534
+ status: result !== null && result !== void 0 && result.success ? "success" : "error",
3535
+ 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."
3536
+ });
3537
+ _context.next = 5;
3538
+ break;
3539
+ case 4:
3540
+ _context.prev = 4;
3541
+ _t = _context["catch"](2);
3542
+ setInstallResult({
3543
+ status: "error",
3544
+ message: _t.message || "Failed to install dashboard."
3545
+ });
3546
+ case 5:
3547
+ _context.prev = 5;
3548
+ setIsInstalling(false);
3549
+ return _context.finish(5);
3550
+ case 6:
3551
+ case "end":
3552
+ return _context.stop();
3553
+ }
3554
+ }, _callee, null, [[2, 4, 5, 6]]);
3555
+ }));
3556
+ return _handleInstall.apply(this, arguments);
3557
+ }
3558
+ var compatibility = preview === null || preview === void 0 ? void 0 : preview.compatibility;
3559
+ var widgetDeps = (preview === null || preview === void 0 ? void 0 : preview.widgets) || pkg.widgets || [];
3560
+ var providers = (preview === null || preview === void 0 ? void 0 : preview.providers) || [];
3561
+ var wiring = (preview === null || preview === void 0 ? void 0 : preview.wiring) || [];
3562
+ function getCompatIcon(status) {
3563
+ if (status === "installed") return {
3564
+ icon: "circle-check",
3565
+ color: "text-green-400"
3566
+ };
3567
+ if (status === "available") return {
3568
+ icon: "circle-down",
3569
+ color: "text-blue-400"
3570
+ };
3571
+ return {
3572
+ icon: "circle-xmark",
3573
+ color: "text-red-400"
3574
+ };
3575
+ }
3576
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
3577
+ className: "flex flex-col flex-1 min-h-0",
3578
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
3579
+ className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-6 ".concat(panelStyles.textColor || "text-gray-200"),
3580
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
3581
+ className: "flex flex-row items-center gap-3",
3582
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
3583
+ className: "h-5 w-5 flex-shrink-0 flex items-center justify-center",
3584
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
3585
+ icon: pkg.icon || "clone",
3586
+ className: "h-5 w-5"
3587
+ })
3588
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
3589
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
3590
+ title: pkg.displayName || pkg.name,
3591
+ padding: false
3592
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
3593
+ className: "flex items-center gap-2 mt-0.5",
3594
+ children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
3595
+ className: "text-sm opacity-60",
3596
+ children: ["by ", pkg.author || "Unknown"]
3597
+ }), pkg.version && /*#__PURE__*/jsxRuntime.jsxs("span", {
3598
+ className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
3599
+ children: ["v", pkg.version]
3600
+ })]
3601
+ })]
3602
+ })]
3603
+ }), appId && /*#__PURE__*/jsxRuntime.jsx(StarRating, {
3604
+ appId: appId,
3605
+ packageName: pkg.name,
3606
+ interactive: false
3607
+ }), /*#__PURE__*/jsxRuntime.jsx("hr", {
3608
+ className: currentTheme["border-primary-medium"]
3609
+ }), pkg.description && /*#__PURE__*/jsxRuntime.jsx("p", {
3610
+ className: "text-sm",
3611
+ children: pkg.description
3612
+ }), pkg.tags && pkg.tags.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
3613
+ className: "flex flex-wrap gap-1",
3614
+ children: pkg.tags.map(function (tag) {
3615
+ return /*#__PURE__*/jsxRuntime.jsx("span", {
3616
+ className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-60"),
3617
+ children: tag
3618
+ }, tag);
3619
+ })
3620
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
3621
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
3622
+ className: "text-xs font-semibold opacity-50 mb-1 block",
3623
+ children: "REQUIRED WIDGETS"
3624
+ }), previewLoading ? /*#__PURE__*/jsxRuntime.jsxs("div", {
3625
+ className: "flex items-center gap-2 py-2",
3626
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
3627
+ className: "animate-spin rounded-full h-4 w-4 border-b-2 border-blue-500"
3628
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
3629
+ className: "text-xs opacity-50",
3630
+ children: "Checking compatibility..."
3631
+ })]
3632
+ }) : /*#__PURE__*/jsxRuntime.jsx("div", {
3633
+ className: "space-y-1.5",
3634
+ children: widgetDeps.map(function (w, idx) {
3635
+ var _compatibility$widget;
3636
+ 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";
3637
+ var compat = getCompatIcon(status);
3638
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
3639
+ className: "p-2 rounded ".concat(currentTheme["bg-primary-medium"], " flex items-center gap-2"),
3640
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
3641
+ icon: compat.icon,
3642
+ className: "h-3.5 w-3.5 ".concat(compat.color)
3643
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
3644
+ className: "text-sm",
3645
+ children: w.displayName || w.name || w.packageName
3646
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
3647
+ className: "text-xs opacity-40 ml-auto",
3648
+ children: status === "installed" ? "Installed" : status === "available" ? "Will install" : "Unavailable"
3649
+ })]
3650
+ }, idx);
3651
+ })
3652
+ })]
3653
+ }), providers.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
3654
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
3655
+ className: "text-xs font-semibold opacity-50 mb-1 block",
3656
+ children: "REQUIRED PROVIDERS"
3657
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
3658
+ className: "space-y-1",
3659
+ children: providers.map(function (p, idx) {
3660
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
3661
+ className: "flex items-center gap-2",
3662
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
3663
+ className: "text-xs px-1.5 py-0.5 rounded bg-blue-900/30 text-blue-400",
3664
+ children: p.type
3665
+ }), p.required && /*#__PURE__*/jsxRuntime.jsx("span", {
3666
+ className: "text-[10px] opacity-40",
3667
+ children: "Required"
3668
+ })]
3669
+ }, idx);
3670
+ })
3671
+ })]
3672
+ }), wiring.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
3673
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
3674
+ className: "text-xs font-semibold opacity-50 mb-1 block",
3675
+ children: "EVENT WIRING"
3676
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
3677
+ className: "space-y-1",
3678
+ children: wiring.map(function (w, idx) {
3679
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
3680
+ className: "text-xs p-2 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
3681
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
3682
+ className: "font-medium",
3683
+ children: w.from || "Source"
3684
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
3685
+ icon: "arrow-right",
3686
+ className: "h-2.5 w-2.5 mx-1.5 opacity-50"
3687
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
3688
+ className: "font-medium",
3689
+ children: w.to || "Target"
3690
+ }), w.event && /*#__PURE__*/jsxRuntime.jsxs("span", {
3691
+ className: "opacity-50 ml-1.5",
3692
+ children: ["(", w.event, ")"]
3693
+ })]
3694
+ }, idx);
3695
+ })
3696
+ })]
3697
+ }), installResult && /*#__PURE__*/jsxRuntime.jsx("div", {
3698
+ className: "p-2 rounded border ".concat(installResult.status === "success" ? "bg-green-900/20 border-green-700" : "bg-red-900/30 border-red-700"),
3699
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
3700
+ className: "flex items-center gap-2",
3701
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
3702
+ icon: installResult.status === "success" ? "circle-check" : "circle-xmark",
3703
+ className: "h-4 w-4 ".concat(installResult.status === "success" ? "text-green-400" : "text-red-400")
3704
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
3705
+ className: "text-sm ".concat(installResult.status === "error" ? "text-red-400" : ""),
3706
+ children: installResult.message
3707
+ })]
3708
+ })
3709
+ })]
3710
+ }), (installResult === null || installResult === void 0 ? void 0 : installResult.status) !== "success" && /*#__PURE__*/jsxRuntime.jsx("div", {
3711
+ className: "flex items-center justify-end px-6 py-3 border-t ".concat(currentTheme["border-primary-medium"]),
3712
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
3713
+ title: isInstalling ? "Installing..." : "Install Dashboard",
3714
+ bgColor: "bg-blue-600",
3715
+ hoverBackgroundColor: isInstalling ? "" : "hover:bg-blue-700",
3716
+ textSize: "text-sm",
3717
+ padding: "py-1.5 px-4",
3718
+ onClick: handleInstall,
3719
+ disabled: isInstalling
3720
+ })
3721
+ })]
3722
+ });
3723
+ };
3724
+
3725
+ var DiscoverDashboardsDetail = function DiscoverDashboardsDetail(_ref) {
3726
+ var onBack = _ref.onBack,
3727
+ appId = _ref.appId;
3728
+ var _useContext = React.useContext(DashReact.ThemeContext),
3729
+ currentTheme = _useContext.currentTheme;
3730
+ var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
3731
+ grow: false
3732
+ });
3733
+ var _useState = React.useState([]),
3734
+ _useState2 = _slicedToArray(_useState, 2),
3735
+ packages = _useState2[0],
3736
+ setPackages = _useState2[1];
3737
+ var _useState3 = React.useState(false),
3738
+ _useState4 = _slicedToArray(_useState3, 2),
3739
+ isLoading = _useState4[0],
3740
+ setIsLoading = _useState4[1];
3741
+ var _useState5 = React.useState(null),
3742
+ _useState6 = _slicedToArray(_useState5, 2),
3743
+ error = _useState6[0],
3744
+ setError = _useState6[1];
3745
+ var _useState7 = React.useState(""),
3746
+ _useState8 = _slicedToArray(_useState7, 2),
3747
+ searchQuery = _useState8[0],
3748
+ setSearchQuery = _useState8[1];
3749
+ var _useState9 = React.useState(null),
3750
+ _useState0 = _slicedToArray(_useState9, 2),
3751
+ selectedPackageName = _useState0[0],
3752
+ setSelectedPackageName = _useState0[1];
3753
+ var search = React.useCallback(/*#__PURE__*/function () {
3754
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(query) {
3755
+ var _window$mainApi;
3756
+ var result, _t;
3757
+ return _regeneratorRuntime.wrap(function (_context) {
3758
+ while (1) switch (_context.prev = _context.next) {
3759
+ case 0:
3760
+ if ((_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && (_window$mainApi = _window$mainApi.registry) !== null && _window$mainApi !== void 0 && _window$mainApi.searchDashboards) {
3761
+ _context.next = 1;
3762
+ break;
3763
+ }
3764
+ setPackages([]);
3765
+ return _context.abrupt("return");
3766
+ case 1:
3767
+ setIsLoading(true);
3768
+ setError(null);
3769
+ _context.prev = 2;
3770
+ _context.next = 3;
3771
+ return window.mainApi.registry.searchDashboards(query || "", {});
3772
+ case 3:
3773
+ result = _context.sent;
3774
+ setPackages((result === null || result === void 0 ? void 0 : result.packages) || []);
3775
+ _context.next = 5;
3776
+ break;
3777
+ case 4:
3778
+ _context.prev = 4;
3779
+ _t = _context["catch"](2);
3780
+ setError(_t.message || "Failed to search dashboard registry");
3781
+ setPackages([]);
3782
+ case 5:
3783
+ _context.prev = 5;
3784
+ setIsLoading(false);
3785
+ return _context.finish(5);
3786
+ case 6:
3787
+ case "end":
3788
+ return _context.stop();
3789
+ }
3790
+ }, _callee, null, [[2, 4, 5, 6]]);
3791
+ }));
3792
+ return function (_x) {
3793
+ return _ref2.apply(this, arguments);
3794
+ };
3795
+ }(), []);
3796
+
3797
+ // Debounce search on query changes
3798
+ React.useEffect(function () {
3799
+ var timer = setTimeout(function () {
3800
+ search(searchQuery);
3801
+ }, 300);
3802
+ return function () {
3803
+ return clearTimeout(timer);
3804
+ };
3805
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3806
+ }, [searchQuery]);
3807
+ var retry = function retry() {
3808
+ return search(searchQuery);
3809
+ };
3810
+ var selectedPackage = selectedPackageName ? packages.find(function (p) {
3811
+ return p.name === selectedPackageName;
3812
+ }) : null;
3813
+
3814
+ // If a package is selected, show its detail inline
3815
+ if (selectedPackage) {
3816
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
3817
+ className: "flex flex-col flex-1 min-h-0",
3818
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
3819
+ className: "flex-shrink-0 px-4 pt-4",
3820
+ children: /*#__PURE__*/jsxRuntime.jsxs("button", {
3821
+ type: "button",
3822
+ onClick: function onClick() {
3823
+ return setSelectedPackageName(null);
3824
+ },
3825
+ className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
3826
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
3827
+ icon: "arrow-left",
3828
+ className: "h-3 w-3"
3829
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
3830
+ children: "Back"
3831
+ })]
3832
+ })
3833
+ }), /*#__PURE__*/jsxRuntime.jsx(RegistryDashboardDetail, {
3834
+ dashboardPackage: selectedPackage,
3835
+ appId: appId
3836
+ })]
3837
+ });
3838
+ }
3839
+
3840
+ // Package list view
3841
+ var listBody;
3842
+ if (isLoading) {
3843
+ listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
3844
+ className: "flex items-center justify-center py-12",
3845
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
3846
+ className: "text-center",
3847
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
3848
+ className: "animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500 mx-auto mb-3"
3849
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
3850
+ className: "text-sm opacity-50",
3851
+ children: "Loading dashboards..."
3852
+ })]
3853
+ })
3854
+ });
3855
+ } else if (error) {
3856
+ listBody = /*#__PURE__*/jsxRuntime.jsxs("div", {
3857
+ className: "px-4 py-8 text-center",
3858
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
3859
+ className: "text-sm text-red-400 mb-3",
3860
+ children: error
3861
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
3862
+ title: "Retry",
3863
+ bgColor: "bg-gray-700",
3864
+ hoverBackgroundColor: "hover:bg-gray-600",
3865
+ textSize: "text-sm",
3866
+ padding: "py-1 px-3",
3867
+ onClick: retry
3868
+ })]
3869
+ });
3870
+ } else if (packages.length === 0) {
3871
+ listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
3872
+ className: "px-4 py-8 text-center",
3873
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
3874
+ className: "text-sm opacity-50",
3875
+ children: searchQuery ? "No dashboards match your search." : "No dashboard packages available."
3876
+ })
3877
+ });
3878
+ } else {
3879
+ listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
3880
+ className: "space-y-1",
3881
+ children: packages.map(function (pkg) {
3882
+ var widgetCount = (pkg.widgets || []).length;
3883
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
3884
+ icon: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
3885
+ icon: pkg.icon || "clone",
3886
+ className: "h-3.5 w-3.5"
3887
+ }),
3888
+ onClick: function onClick() {
3889
+ return setSelectedPackageName(pkg.name);
3890
+ },
3891
+ badge: widgetCount > 0 ? "".concat(widgetCount) : undefined,
3892
+ children: pkg.displayName || pkg.name
3893
+ }, pkg.name);
3894
+ })
3895
+ });
3896
+ }
3897
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
3898
+ className: "flex flex-col flex-1 min-h-0 ".concat(panelStyles.textColor || "text-gray-200"),
3899
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
3900
+ className: "flex-shrink-0 px-4 pt-4",
3901
+ children: /*#__PURE__*/jsxRuntime.jsxs("button", {
3902
+ type: "button",
3903
+ onClick: onBack,
3904
+ className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
3905
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
3906
+ icon: "arrow-left",
3907
+ className: "h-3 w-3"
3908
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
3909
+ children: "Back"
3910
+ })]
3911
+ })
3912
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
3913
+ className: "flex-shrink-0 px-4 py-3",
3914
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.SearchInput, {
3915
+ value: searchQuery,
3916
+ onChange: setSearchQuery,
3917
+ placeholder: "Search dashboards...",
3918
+ inputClassName: "py-1.5 text-xs"
3919
+ })
3920
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
3921
+ className: "flex-1 min-h-0 overflow-y-auto px-2",
3922
+ children: listBody
3923
+ }), !isLoading && !error && packages.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
3924
+ className: "flex-shrink-0 px-4 py-2 text-[10px] opacity-40 border-t border-white/10",
3925
+ children: [packages.length, " dashboard", packages.length !== 1 ? "s" : ""]
3926
+ })]
3927
+ });
3928
+ };
3929
+
3294
3930
  var LayoutManagerModal = function LayoutManagerModal(_ref) {
3295
3931
  var open = _ref.open,
3296
3932
  setIsOpen = _ref.setIsOpen,
@@ -3298,52 +3934,59 @@ var LayoutManagerModal = function LayoutManagerModal(_ref) {
3298
3934
  _ref$menuItems = _ref.menuItems,
3299
3935
  menuItems = _ref$menuItems === void 0 ? [] : _ref$menuItems,
3300
3936
  _ref$onSaveMenuItem = _ref.onSaveMenuItem,
3301
- onSaveMenuItem = _ref$onSaveMenuItem === void 0 ? null : _ref$onSaveMenuItem;
3937
+ onSaveMenuItem = _ref$onSaveMenuItem === void 0 ? null : _ref$onSaveMenuItem,
3938
+ appId = _ref.appId,
3939
+ onReloadWorkspaces = _ref.onReloadWorkspaces;
3302
3940
  var _useContext = React.useContext(DashReact.ThemeContext),
3303
3941
  themes = _useContext.themes,
3304
3942
  appThemeKey = _useContext.themeKey;
3305
- var _useState = React.useState(""),
3943
+ var _useState = React.useState(null),
3306
3944
  _useState2 = _slicedToArray(_useState, 2),
3307
- dashboardName = _useState2[0],
3308
- setDashboardName = _useState2[1];
3309
- var _useState3 = React.useState(layoutTemplates[0]),
3945
+ creationMethod = _useState2[0],
3946
+ setCreationMethod = _useState2[1];
3947
+ var _useState3 = React.useState(""),
3310
3948
  _useState4 = _slicedToArray(_useState3, 2),
3311
- selectedTemplate = _useState4[0],
3312
- setSelectedTemplate = _useState4[1];
3313
- var _useState5 = React.useState(0),
3949
+ dashboardName = _useState4[0],
3950
+ setDashboardName = _useState4[1];
3951
+ var _useState5 = React.useState(layoutTemplates[0]),
3314
3952
  _useState6 = _slicedToArray(_useState5, 2),
3315
- activeStep = _useState6[0],
3316
- setActiveStep = _useState6[1];
3317
- var _useState7 = React.useState(null),
3953
+ selectedTemplate = _useState6[0],
3954
+ setSelectedTemplate = _useState6[1];
3955
+ var _useState7 = React.useState(0),
3318
3956
  _useState8 = _slicedToArray(_useState7, 2),
3319
- selectedMenuId = _useState8[0],
3320
- setSelectedMenuId = _useState8[1];
3957
+ activeStep = _useState8[0],
3958
+ setActiveStep = _useState8[1];
3321
3959
  var _useState9 = React.useState(null),
3322
3960
  _useState0 = _slicedToArray(_useState9, 2),
3323
- selectedThemeKey = _useState0[0],
3324
- setSelectedThemeKey = _useState0[1];
3325
- var _useState1 = React.useState([]),
3961
+ selectedMenuId = _useState0[0],
3962
+ setSelectedMenuId = _useState0[1];
3963
+ var _useState1 = React.useState(null),
3326
3964
  _useState10 = _slicedToArray(_useState1, 2),
3327
- localMenuItems = _useState10[0],
3328
- setLocalMenuItems = _useState10[1];
3965
+ selectedThemeKey = _useState10[0],
3966
+ setSelectedThemeKey = _useState10[1];
3967
+ var _useState11 = React.useState([]),
3968
+ _useState12 = _slicedToArray(_useState11, 2),
3969
+ localMenuItems = _useState12[0],
3970
+ setLocalMenuItems = _useState12[1];
3329
3971
 
3330
3972
  // Inline new-folder form state
3331
- var _useState11 = React.useState(false),
3332
- _useState12 = _slicedToArray(_useState11, 2),
3333
- isCreatingFolder = _useState12[0],
3334
- setIsCreatingFolder = _useState12[1];
3335
- var _useState13 = React.useState(""),
3973
+ var _useState13 = React.useState(false),
3336
3974
  _useState14 = _slicedToArray(_useState13, 2),
3337
- newFolderName = _useState14[0],
3338
- setNewFolderName = _useState14[1];
3339
- var _useState15 = React.useState(null),
3975
+ isCreatingFolder = _useState14[0],
3976
+ setIsCreatingFolder = _useState14[1];
3977
+ var _useState15 = React.useState(""),
3340
3978
  _useState16 = _slicedToArray(_useState15, 2),
3341
- newFolderIcon = _useState16[0],
3342
- setNewFolderIcon = _useState16[1];
3979
+ newFolderName = _useState16[0],
3980
+ setNewFolderName = _useState16[1];
3981
+ var _useState17 = React.useState(null),
3982
+ _useState18 = _slicedToArray(_useState17, 2),
3983
+ newFolderIcon = _useState18[0],
3984
+ setNewFolderIcon = _useState18[1];
3343
3985
 
3344
3986
  // Reset state when modal opens
3345
3987
  React.useEffect(function () {
3346
3988
  if (open) {
3989
+ setCreationMethod(null);
3347
3990
  setDashboardName("");
3348
3991
  setActiveStep(0);
3349
3992
  setLocalMenuItems(menuItems || []);
@@ -3391,16 +4034,85 @@ var LayoutManagerModal = function LayoutManagerModal(_ref) {
3391
4034
  setSelectedTemplate(template);
3392
4035
  setActiveStep(2);
3393
4036
  }
4037
+ function handleMethodSelect(method) {
4038
+ if (method === "import") {
4039
+ handleImportFromFile();
4040
+ } else {
4041
+ setCreationMethod(method);
4042
+ }
4043
+ }
4044
+ function handleImportFromFile() {
4045
+ return _handleImportFromFile.apply(this, arguments);
4046
+ }
4047
+ function _handleImportFromFile() {
4048
+ _handleImportFromFile = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
4049
+ var result;
4050
+ return _regeneratorRuntime.wrap(function (_context) {
4051
+ while (1) switch (_context.prev = _context.next) {
4052
+ case 0:
4053
+ handleClose();
4054
+ _context.prev = 1;
4055
+ _context.next = 2;
4056
+ return window.mainApi.dashboardConfig.importDashboardConfig(appId);
4057
+ case 2:
4058
+ result = _context.sent;
4059
+ if (result && !result.canceled && result.success) {
4060
+ onReloadWorkspaces && onReloadWorkspaces();
4061
+ }
4062
+ _context.next = 4;
4063
+ break;
4064
+ case 3:
4065
+ _context.prev = 3;
4066
+ _context["catch"](1);
4067
+ case 4:
4068
+ case "end":
4069
+ return _context.stop();
4070
+ }
4071
+ }, _callee, null, [[1, 3]]);
4072
+ }));
4073
+ return _handleImportFromFile.apply(this, arguments);
4074
+ }
3394
4075
  var selectedFolder = localMenuItems.find(function (item) {
3395
4076
  return item.id === selectedMenuId;
3396
4077
  });
3397
- return /*#__PURE__*/jsxRuntime.jsxs(DashReact.Modal, {
3398
- isOpen: open,
3399
- setIsOpen: setIsOpen,
3400
- width: "w-11/12 xl:w-5/6",
3401
- height: "h-5/6",
3402
- scrollable: false,
3403
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Panel, {
4078
+
4079
+ // ─── Render body based on creationMethod ─────────────────────────
4080
+ function renderBody() {
4081
+ if (creationMethod === null) {
4082
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Panel, {
4083
+ backgroundColor: "bg-slate-800",
4084
+ padding: false,
4085
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Panel.Body, {
4086
+ scrollable: false,
4087
+ className: "h-full",
4088
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
4089
+ className: "h-full p-6 pb-0",
4090
+ children: /*#__PURE__*/jsxRuntime.jsx(CreationMethodPicker, {
4091
+ onSelect: handleMethodSelect
4092
+ })
4093
+ })
4094
+ })
4095
+ });
4096
+ }
4097
+ if (creationMethod === "registry") {
4098
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Panel, {
4099
+ backgroundColor: "bg-slate-800",
4100
+ padding: false,
4101
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Panel.Body, {
4102
+ scrollable: false,
4103
+ className: "h-full",
4104
+ children: /*#__PURE__*/jsxRuntime.jsx(DiscoverDashboardsDetail, {
4105
+ onBack: function onBack() {
4106
+ return setCreationMethod(null);
4107
+ },
4108
+ appId: appId
4109
+ })
4110
+ })
4111
+ });
4112
+ }
4113
+
4114
+ // creationMethod === "template" — existing 4-step wizard
4115
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Panel, {
3404
4116
  backgroundColor: "bg-slate-800",
3405
4117
  padding: false,
3406
4118
  children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Panel.Body, {
@@ -3658,13 +4370,45 @@ var LayoutManagerModal = function LayoutManagerModal(_ref) {
3658
4370
  })]
3659
4371
  })
3660
4372
  })
3661
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Modal.Footer, {
4373
+ });
4374
+ }
4375
+
4376
+ // ─── Render footer based on creationMethod ───────────────────────
4377
+ function renderFooter() {
4378
+ // Picker screen: just Cancel
4379
+ if (creationMethod === null) {
4380
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Modal.Footer, {
4381
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
4382
+ className: "flex flex-row space-x-2",
4383
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
4384
+ onClick: handleClose,
4385
+ title: "Cancel",
4386
+ textSize: "text-base xl:text-lg",
4387
+ padding: "py-2 px-4",
4388
+ backgroundColor: "bg-gray-700",
4389
+ textColor: "text-gray-300",
4390
+ hoverTextColor: "hover:text-gray-100",
4391
+ hoverBackgroundColor: "hover:bg-gray-600"
4392
+ })
4393
+ })
4394
+ });
4395
+ }
4396
+
4397
+ // Registry screen: no footer (DiscoverDashboardsDetail has its own back button)
4398
+ if (creationMethod === "registry") {
4399
+ return null;
4400
+ }
4401
+
4402
+ // Template wizard footer
4403
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Modal.Footer, {
3662
4404
  children: /*#__PURE__*/jsxRuntime.jsxs("div", {
3663
4405
  className: "flex flex-row space-x-2",
3664
4406
  children: [activeStep === 0 && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
3665
4407
  children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
3666
- onClick: handleClose,
3667
- title: "Cancel",
4408
+ onClick: function onClick() {
4409
+ return setCreationMethod(null);
4410
+ },
4411
+ title: "Back",
3668
4412
  textSize: "text-base xl:text-lg",
3669
4413
  padding: "py-2 px-4",
3670
4414
  backgroundColor: "bg-gray-700",
@@ -3757,7 +4501,15 @@ var LayoutManagerModal = function LayoutManagerModal(_ref) {
3757
4501
  })]
3758
4502
  })]
3759
4503
  })
3760
- })]
4504
+ });
4505
+ }
4506
+ return /*#__PURE__*/jsxRuntime.jsxs(DashReact.Modal, {
4507
+ isOpen: open,
4508
+ setIsOpen: setIsOpen,
4509
+ width: "w-11/12 xl:w-5/6",
4510
+ height: "h-5/6",
4511
+ scrollable: false,
4512
+ children: [renderBody(), renderFooter()]
3761
4513
  });
3762
4514
  };
3763
4515
 
@@ -30660,102 +31412,6 @@ var ThemeManagerModal = function ThemeManagerModal(_ref) {
30660
31412
  });
30661
31413
  };
30662
31414
 
30663
- var StarRating = function StarRating(_ref) {
30664
- var appId = _ref.appId,
30665
- packageName = _ref.packageName,
30666
- _ref$interactive = _ref.interactive,
30667
- interactive = _ref$interactive === void 0 ? true : _ref$interactive;
30668
- var _useContext = React.useContext(DashReact.ThemeContext),
30669
- currentTheme = _useContext.currentTheme;
30670
- var _useState = React.useState(0),
30671
- _useState2 = _slicedToArray(_useState, 2),
30672
- rating = _useState2[0],
30673
- setRating = _useState2[1];
30674
- var _useState3 = React.useState(0),
30675
- _useState4 = _slicedToArray(_useState3, 2),
30676
- hoverRating = _useState4[0],
30677
- setHoverRating = _useState4[1];
30678
- var _useState5 = React.useState(true),
30679
- _useState6 = _slicedToArray(_useState5, 2),
30680
- loading = _useState6[0],
30681
- setLoading = _useState6[1];
30682
- React.useEffect(function () {
30683
- var _window$mainApi;
30684
- if (!appId || !packageName) return;
30685
- var cancelled = false;
30686
- setLoading(true);
30687
- (_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) {
30688
- if (!cancelled && result !== null && result !== void 0 && result.rating) {
30689
- setRating(result.rating);
30690
- }
30691
- })["catch"](function () {})["finally"](function () {
30692
- if (!cancelled) setLoading(false);
30693
- });
30694
- return function () {
30695
- cancelled = true;
30696
- };
30697
- }, [appId, packageName]);
30698
- function handleClick(_x) {
30699
- return _handleClick.apply(this, arguments);
30700
- }
30701
- function _handleClick() {
30702
- _handleClick = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(value) {
30703
- var newRating, _window$mainApi2;
30704
- return _regeneratorRuntime.wrap(function (_context) {
30705
- while (1) switch (_context.prev = _context.next) {
30706
- case 0:
30707
- if (!(!interactive || !appId || !packageName)) {
30708
- _context.next = 1;
30709
- break;
30710
- }
30711
- return _context.abrupt("return");
30712
- case 1:
30713
- newRating = value === rating ? 0 : value;
30714
- setRating(newRating);
30715
- _context.prev = 2;
30716
- _context.next = 3;
30717
- 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);
30718
- case 3:
30719
- _context.next = 5;
30720
- break;
30721
- case 4:
30722
- _context.prev = 4;
30723
- _context["catch"](2);
30724
- case 5:
30725
- case "end":
30726
- return _context.stop();
30727
- }
30728
- }, _callee, null, [[2, 4]]);
30729
- }));
30730
- return _handleClick.apply(this, arguments);
30731
- }
30732
- if (loading) return null;
30733
- var displayRating = hoverRating || rating;
30734
- return /*#__PURE__*/jsxRuntime.jsx("div", {
30735
- className: "flex items-center gap-0.5",
30736
- onMouseLeave: function onMouseLeave() {
30737
- return setHoverRating(0);
30738
- },
30739
- children: [1, 2, 3, 4, 5].map(function (star) {
30740
- return /*#__PURE__*/jsxRuntime.jsx("button", {
30741
- type: "button",
30742
- disabled: !interactive,
30743
- onClick: function onClick() {
30744
- return handleClick(star);
30745
- },
30746
- onMouseEnter: function onMouseEnter() {
30747
- return interactive && setHoverRating(star);
30748
- },
30749
- className: "p-0.5 transition-colors ".concat(interactive ? "cursor-pointer hover:scale-110" : "cursor-default"),
30750
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
30751
- icon: star <= displayRating ? "star" : ["far", "star"],
30752
- className: "h-3.5 w-3.5 ".concat(star <= displayRating ? "text-yellow-400" : currentTheme["text-primary-medium"] || "text-gray-500")
30753
- })
30754
- }, star);
30755
- })
30756
- });
30757
- };
30758
-
30759
31415
  var DASHBOARD_TAGS = ["productivity", "monitoring", "analytics", "communication", "developer", "sales", "marketing", "finance", "project-management", "social", "news", "utilities"];
30760
31416
 
30761
31417
  /**
@@ -31845,471 +32501,6 @@ var DashboardDetail = function DashboardDetail(_ref2) {
31845
32501
  });
31846
32502
  };
31847
32503
 
31848
- var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
31849
- var dashboardPackage = _ref.dashboardPackage,
31850
- appId = _ref.appId;
31851
- var _useContext = React.useContext(DashReact.ThemeContext),
31852
- currentTheme = _useContext.currentTheme;
31853
- var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
31854
- grow: false
31855
- });
31856
- var _useState = React.useState(null),
31857
- _useState2 = _slicedToArray(_useState, 2),
31858
- preview = _useState2[0],
31859
- setPreview = _useState2[1];
31860
- var _useState3 = React.useState(false),
31861
- _useState4 = _slicedToArray(_useState3, 2),
31862
- previewLoading = _useState4[0],
31863
- setPreviewLoading = _useState4[1];
31864
- var _useState5 = React.useState(false),
31865
- _useState6 = _slicedToArray(_useState5, 2),
31866
- isInstalling = _useState6[0],
31867
- setIsInstalling = _useState6[1];
31868
- var _useState7 = React.useState(null),
31869
- _useState8 = _slicedToArray(_useState7, 2),
31870
- installResult = _useState8[0],
31871
- setInstallResult = _useState8[1];
31872
- var pkg = dashboardPackage;
31873
- if (!pkg) return null;
31874
-
31875
- // Load preview data on mount
31876
- // eslint-disable-next-line react-hooks/rules-of-hooks
31877
- React.useEffect(function () {
31878
- var _window$mainApi;
31879
- if (!pkg.name) return;
31880
- var cancelled = false;
31881
- setPreviewLoading(true);
31882
- setPreview(null);
31883
- setInstallResult(null);
31884
- (_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) {
31885
- if (!cancelled) setPreview(result);
31886
- })["catch"](function (err) {
31887
- })["finally"](function () {
31888
- if (!cancelled) setPreviewLoading(false);
31889
- });
31890
- return function () {
31891
- cancelled = true;
31892
- };
31893
- }, [pkg.name]);
31894
- function handleInstall() {
31895
- return _handleInstall.apply(this, arguments);
31896
- }
31897
- function _handleInstall() {
31898
- _handleInstall = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
31899
- var _result$workspace, result, _t;
31900
- return _regeneratorRuntime.wrap(function (_context) {
31901
- while (1) switch (_context.prev = _context.next) {
31902
- case 0:
31903
- if (!(!appId || !pkg.name)) {
31904
- _context.next = 1;
31905
- break;
31906
- }
31907
- return _context.abrupt("return");
31908
- case 1:
31909
- setIsInstalling(true);
31910
- setInstallResult(null);
31911
- _context.prev = 2;
31912
- _context.next = 3;
31913
- return window.mainApi.dashboardConfig.installDashboardFromRegistry(appId, pkg.name);
31914
- case 3:
31915
- result = _context.sent;
31916
- setInstallResult({
31917
- status: result !== null && result !== void 0 && result.success ? "success" : "error",
31918
- 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."
31919
- });
31920
- _context.next = 5;
31921
- break;
31922
- case 4:
31923
- _context.prev = 4;
31924
- _t = _context["catch"](2);
31925
- setInstallResult({
31926
- status: "error",
31927
- message: _t.message || "Failed to install dashboard."
31928
- });
31929
- case 5:
31930
- _context.prev = 5;
31931
- setIsInstalling(false);
31932
- return _context.finish(5);
31933
- case 6:
31934
- case "end":
31935
- return _context.stop();
31936
- }
31937
- }, _callee, null, [[2, 4, 5, 6]]);
31938
- }));
31939
- return _handleInstall.apply(this, arguments);
31940
- }
31941
- var compatibility = preview === null || preview === void 0 ? void 0 : preview.compatibility;
31942
- var widgetDeps = (preview === null || preview === void 0 ? void 0 : preview.widgets) || pkg.widgets || [];
31943
- var providers = (preview === null || preview === void 0 ? void 0 : preview.providers) || [];
31944
- var wiring = (preview === null || preview === void 0 ? void 0 : preview.wiring) || [];
31945
- function getCompatIcon(status) {
31946
- if (status === "installed") return {
31947
- icon: "circle-check",
31948
- color: "text-green-400"
31949
- };
31950
- if (status === "available") return {
31951
- icon: "circle-down",
31952
- color: "text-blue-400"
31953
- };
31954
- return {
31955
- icon: "circle-xmark",
31956
- color: "text-red-400"
31957
- };
31958
- }
31959
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
31960
- className: "flex flex-col flex-1 min-h-0",
31961
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
31962
- className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-6 ".concat(panelStyles.textColor || "text-gray-200"),
31963
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
31964
- className: "flex flex-row items-center gap-3",
31965
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
31966
- className: "h-5 w-5 flex-shrink-0 flex items-center justify-center",
31967
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
31968
- icon: pkg.icon || "clone",
31969
- className: "h-5 w-5"
31970
- })
31971
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
31972
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
31973
- title: pkg.displayName || pkg.name,
31974
- padding: false
31975
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
31976
- className: "flex items-center gap-2 mt-0.5",
31977
- children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
31978
- className: "text-sm opacity-60",
31979
- children: ["by ", pkg.author || "Unknown"]
31980
- }), pkg.version && /*#__PURE__*/jsxRuntime.jsxs("span", {
31981
- className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
31982
- children: ["v", pkg.version]
31983
- })]
31984
- })]
31985
- })]
31986
- }), appId && /*#__PURE__*/jsxRuntime.jsx(StarRating, {
31987
- appId: appId,
31988
- packageName: pkg.name,
31989
- interactive: false
31990
- }), /*#__PURE__*/jsxRuntime.jsx("hr", {
31991
- className: currentTheme["border-primary-medium"]
31992
- }), pkg.description && /*#__PURE__*/jsxRuntime.jsx("p", {
31993
- className: "text-sm",
31994
- children: pkg.description
31995
- }), pkg.tags && pkg.tags.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
31996
- className: "flex flex-wrap gap-1",
31997
- children: pkg.tags.map(function (tag) {
31998
- return /*#__PURE__*/jsxRuntime.jsx("span", {
31999
- className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-60"),
32000
- children: tag
32001
- }, tag);
32002
- })
32003
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
32004
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
32005
- className: "text-xs font-semibold opacity-50 mb-1 block",
32006
- children: "REQUIRED WIDGETS"
32007
- }), previewLoading ? /*#__PURE__*/jsxRuntime.jsxs("div", {
32008
- className: "flex items-center gap-2 py-2",
32009
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
32010
- className: "animate-spin rounded-full h-4 w-4 border-b-2 border-blue-500"
32011
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
32012
- className: "text-xs opacity-50",
32013
- children: "Checking compatibility..."
32014
- })]
32015
- }) : /*#__PURE__*/jsxRuntime.jsx("div", {
32016
- className: "space-y-1.5",
32017
- children: widgetDeps.map(function (w, idx) {
32018
- var _compatibility$widget;
32019
- 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";
32020
- var compat = getCompatIcon(status);
32021
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
32022
- className: "p-2 rounded ".concat(currentTheme["bg-primary-medium"], " flex items-center gap-2"),
32023
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
32024
- icon: compat.icon,
32025
- className: "h-3.5 w-3.5 ".concat(compat.color)
32026
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
32027
- className: "text-sm",
32028
- children: w.displayName || w.name || w.packageName
32029
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
32030
- className: "text-xs opacity-40 ml-auto",
32031
- children: status === "installed" ? "Installed" : status === "available" ? "Will install" : "Unavailable"
32032
- })]
32033
- }, idx);
32034
- })
32035
- })]
32036
- }), providers.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
32037
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
32038
- className: "text-xs font-semibold opacity-50 mb-1 block",
32039
- children: "REQUIRED PROVIDERS"
32040
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
32041
- className: "space-y-1",
32042
- children: providers.map(function (p, idx) {
32043
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
32044
- className: "flex items-center gap-2",
32045
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
32046
- className: "text-xs px-1.5 py-0.5 rounded bg-blue-900/30 text-blue-400",
32047
- children: p.type
32048
- }), p.required && /*#__PURE__*/jsxRuntime.jsx("span", {
32049
- className: "text-[10px] opacity-40",
32050
- children: "Required"
32051
- })]
32052
- }, idx);
32053
- })
32054
- })]
32055
- }), wiring.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
32056
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
32057
- className: "text-xs font-semibold opacity-50 mb-1 block",
32058
- children: "EVENT WIRING"
32059
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
32060
- className: "space-y-1",
32061
- children: wiring.map(function (w, idx) {
32062
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
32063
- className: "text-xs p-2 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
32064
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
32065
- className: "font-medium",
32066
- children: w.from || "Source"
32067
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
32068
- icon: "arrow-right",
32069
- className: "h-2.5 w-2.5 mx-1.5 opacity-50"
32070
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
32071
- className: "font-medium",
32072
- children: w.to || "Target"
32073
- }), w.event && /*#__PURE__*/jsxRuntime.jsxs("span", {
32074
- className: "opacity-50 ml-1.5",
32075
- children: ["(", w.event, ")"]
32076
- })]
32077
- }, idx);
32078
- })
32079
- })]
32080
- }), installResult && /*#__PURE__*/jsxRuntime.jsx("div", {
32081
- className: "p-2 rounded border ".concat(installResult.status === "success" ? "bg-green-900/20 border-green-700" : "bg-red-900/30 border-red-700"),
32082
- children: /*#__PURE__*/jsxRuntime.jsxs("div", {
32083
- className: "flex items-center gap-2",
32084
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
32085
- icon: installResult.status === "success" ? "circle-check" : "circle-xmark",
32086
- className: "h-4 w-4 ".concat(installResult.status === "success" ? "text-green-400" : "text-red-400")
32087
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
32088
- className: "text-sm ".concat(installResult.status === "error" ? "text-red-400" : ""),
32089
- children: installResult.message
32090
- })]
32091
- })
32092
- })]
32093
- }), (installResult === null || installResult === void 0 ? void 0 : installResult.status) !== "success" && /*#__PURE__*/jsxRuntime.jsx("div", {
32094
- className: "flex items-center justify-end px-6 py-3 border-t ".concat(currentTheme["border-primary-medium"]),
32095
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
32096
- title: isInstalling ? "Installing..." : "Install Dashboard",
32097
- bgColor: "bg-blue-600",
32098
- hoverBackgroundColor: isInstalling ? "" : "hover:bg-blue-700",
32099
- textSize: "text-sm",
32100
- padding: "py-1.5 px-4",
32101
- onClick: handleInstall,
32102
- disabled: isInstalling
32103
- })
32104
- })]
32105
- });
32106
- };
32107
-
32108
- var DiscoverDashboardsDetail = function DiscoverDashboardsDetail(_ref) {
32109
- var onBack = _ref.onBack,
32110
- appId = _ref.appId;
32111
- var _useContext = React.useContext(DashReact.ThemeContext),
32112
- currentTheme = _useContext.currentTheme;
32113
- var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
32114
- grow: false
32115
- });
32116
- var _useState = React.useState([]),
32117
- _useState2 = _slicedToArray(_useState, 2),
32118
- packages = _useState2[0],
32119
- setPackages = _useState2[1];
32120
- var _useState3 = React.useState(false),
32121
- _useState4 = _slicedToArray(_useState3, 2),
32122
- isLoading = _useState4[0],
32123
- setIsLoading = _useState4[1];
32124
- var _useState5 = React.useState(null),
32125
- _useState6 = _slicedToArray(_useState5, 2),
32126
- error = _useState6[0],
32127
- setError = _useState6[1];
32128
- var _useState7 = React.useState(""),
32129
- _useState8 = _slicedToArray(_useState7, 2),
32130
- searchQuery = _useState8[0],
32131
- setSearchQuery = _useState8[1];
32132
- var _useState9 = React.useState(null),
32133
- _useState0 = _slicedToArray(_useState9, 2),
32134
- selectedPackageName = _useState0[0],
32135
- setSelectedPackageName = _useState0[1];
32136
- var search = React.useCallback(/*#__PURE__*/function () {
32137
- var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(query) {
32138
- var _window$mainApi;
32139
- var result, _t;
32140
- return _regeneratorRuntime.wrap(function (_context) {
32141
- while (1) switch (_context.prev = _context.next) {
32142
- case 0:
32143
- if ((_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && (_window$mainApi = _window$mainApi.registry) !== null && _window$mainApi !== void 0 && _window$mainApi.searchDashboards) {
32144
- _context.next = 1;
32145
- break;
32146
- }
32147
- setPackages([]);
32148
- return _context.abrupt("return");
32149
- case 1:
32150
- setIsLoading(true);
32151
- setError(null);
32152
- _context.prev = 2;
32153
- _context.next = 3;
32154
- return window.mainApi.registry.searchDashboards(query || "", {});
32155
- case 3:
32156
- result = _context.sent;
32157
- setPackages((result === null || result === void 0 ? void 0 : result.packages) || []);
32158
- _context.next = 5;
32159
- break;
32160
- case 4:
32161
- _context.prev = 4;
32162
- _t = _context["catch"](2);
32163
- setError(_t.message || "Failed to search dashboard registry");
32164
- setPackages([]);
32165
- case 5:
32166
- _context.prev = 5;
32167
- setIsLoading(false);
32168
- return _context.finish(5);
32169
- case 6:
32170
- case "end":
32171
- return _context.stop();
32172
- }
32173
- }, _callee, null, [[2, 4, 5, 6]]);
32174
- }));
32175
- return function (_x) {
32176
- return _ref2.apply(this, arguments);
32177
- };
32178
- }(), []);
32179
-
32180
- // Debounce search on query changes
32181
- React.useEffect(function () {
32182
- var timer = setTimeout(function () {
32183
- search(searchQuery);
32184
- }, 300);
32185
- return function () {
32186
- return clearTimeout(timer);
32187
- };
32188
- // eslint-disable-next-line react-hooks/exhaustive-deps
32189
- }, [searchQuery]);
32190
- var retry = function retry() {
32191
- return search(searchQuery);
32192
- };
32193
- var selectedPackage = selectedPackageName ? packages.find(function (p) {
32194
- return p.name === selectedPackageName;
32195
- }) : null;
32196
-
32197
- // If a package is selected, show its detail inline
32198
- if (selectedPackage) {
32199
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
32200
- className: "flex flex-col flex-1 min-h-0",
32201
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
32202
- className: "flex-shrink-0 px-4 pt-4",
32203
- children: /*#__PURE__*/jsxRuntime.jsxs("button", {
32204
- type: "button",
32205
- onClick: function onClick() {
32206
- return setSelectedPackageName(null);
32207
- },
32208
- className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
32209
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
32210
- icon: "arrow-left",
32211
- className: "h-3 w-3"
32212
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
32213
- children: "Back"
32214
- })]
32215
- })
32216
- }), /*#__PURE__*/jsxRuntime.jsx(RegistryDashboardDetail, {
32217
- dashboardPackage: selectedPackage,
32218
- appId: appId
32219
- })]
32220
- });
32221
- }
32222
-
32223
- // Package list view
32224
- var listBody;
32225
- if (isLoading) {
32226
- listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
32227
- className: "flex items-center justify-center py-12",
32228
- children: /*#__PURE__*/jsxRuntime.jsxs("div", {
32229
- className: "text-center",
32230
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
32231
- className: "animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500 mx-auto mb-3"
32232
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
32233
- className: "text-sm opacity-50",
32234
- children: "Loading dashboards..."
32235
- })]
32236
- })
32237
- });
32238
- } else if (error) {
32239
- listBody = /*#__PURE__*/jsxRuntime.jsxs("div", {
32240
- className: "px-4 py-8 text-center",
32241
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
32242
- className: "text-sm text-red-400 mb-3",
32243
- children: error
32244
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
32245
- title: "Retry",
32246
- bgColor: "bg-gray-700",
32247
- hoverBackgroundColor: "hover:bg-gray-600",
32248
- textSize: "text-sm",
32249
- padding: "py-1 px-3",
32250
- onClick: retry
32251
- })]
32252
- });
32253
- } else if (packages.length === 0) {
32254
- listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
32255
- className: "px-4 py-8 text-center",
32256
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
32257
- className: "text-sm opacity-50",
32258
- children: searchQuery ? "No dashboards match your search." : "No dashboard packages available."
32259
- })
32260
- });
32261
- } else {
32262
- listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
32263
- className: "space-y-1",
32264
- children: packages.map(function (pkg) {
32265
- var widgetCount = (pkg.widgets || []).length;
32266
- return /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
32267
- icon: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
32268
- icon: pkg.icon || "clone",
32269
- className: "h-3.5 w-3.5"
32270
- }),
32271
- onClick: function onClick() {
32272
- return setSelectedPackageName(pkg.name);
32273
- },
32274
- badge: widgetCount > 0 ? "".concat(widgetCount) : undefined,
32275
- children: pkg.displayName || pkg.name
32276
- }, pkg.name);
32277
- })
32278
- });
32279
- }
32280
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
32281
- className: "flex flex-col flex-1 min-h-0 ".concat(panelStyles.textColor || "text-gray-200"),
32282
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
32283
- className: "flex-shrink-0 px-4 pt-4",
32284
- children: /*#__PURE__*/jsxRuntime.jsxs("button", {
32285
- type: "button",
32286
- onClick: onBack,
32287
- className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
32288
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
32289
- icon: "arrow-left",
32290
- className: "h-3 w-3"
32291
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
32292
- children: "Back"
32293
- })]
32294
- })
32295
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
32296
- className: "flex-shrink-0 px-4 py-3",
32297
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.SearchInput, {
32298
- value: searchQuery,
32299
- onChange: setSearchQuery,
32300
- placeholder: "Search dashboards...",
32301
- inputClassName: "py-1.5 text-xs"
32302
- })
32303
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
32304
- className: "flex-1 min-h-0 overflow-y-auto px-2",
32305
- children: listBody
32306
- }), !isLoading && !error && packages.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
32307
- className: "flex-shrink-0 px-4 py-2 text-[10px] opacity-40 border-t border-white/10",
32308
- children: [packages.length, " dashboard", packages.length !== 1 ? "s" : ""]
32309
- })]
32310
- });
32311
- };
32312
-
32313
32504
  function ownKeys$9(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; }
32314
32505
  function _objectSpread$9(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$9(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$9(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
32315
32506
  var DashboardsSection = function DashboardsSection(_ref) {
@@ -40513,9 +40704,21 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
40513
40704
  _useState36 = _slicedToArray(_useState35, 2),
40514
40705
  appSettingsInitialSection = _useState36[0],
40515
40706
  setAppSettingsInitialSection = _useState36[1];
40707
+ var _useState37 = React.useState(null),
40708
+ _useState38 = _slicedToArray(_useState37, 2),
40709
+ appSettingsInitialProvider = _useState38[0],
40710
+ setAppSettingsInitialProvider = _useState38[1];
40711
+ var _useState39 = React.useState(false),
40712
+ _useState40 = _slicedToArray(_useState39, 2),
40713
+ appSettingsCreateProvider = _useState40[0],
40714
+ setAppSettingsCreateProvider = _useState40[1];
40516
40715
  function openAppSettings() {
40517
40716
  var section = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "general";
40717
+ var providerName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
40718
+ var createProvider = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
40518
40719
  setAppSettingsInitialSection(section);
40720
+ setAppSettingsInitialProvider(providerName);
40721
+ setAppSettingsCreateProvider(createProvider);
40519
40722
  setIsAppSettingsOpen(true);
40520
40723
  }
40521
40724
  function handleProfileUpdated() {
@@ -41296,8 +41499,16 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
41296
41499
  }), !popout && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
41297
41500
  children: [/*#__PURE__*/jsxRuntime.jsx(AppSettingsModal, {
41298
41501
  isOpen: isAppSettingsOpen,
41299
- setIsOpen: setIsAppSettingsOpen,
41502
+ setIsOpen: function setIsOpen(open) {
41503
+ setIsAppSettingsOpen(open);
41504
+ if (!open) {
41505
+ setAppSettingsInitialProvider(null);
41506
+ setAppSettingsCreateProvider(false);
41507
+ }
41508
+ },
41300
41509
  initialSection: appSettingsInitialSection,
41510
+ initialProviderName: appSettingsInitialProvider,
41511
+ initialCreateProvider: appSettingsCreateProvider,
41301
41512
  workspaces: workspaceConfig,
41302
41513
  menuItems: menuItems,
41303
41514
  dashApi: dashApi,
@@ -41337,7 +41548,9 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
41337
41548
  setIsOpen: setIsLayoutPickerOpen,
41338
41549
  onCreateWorkspace: handleCreateFromTemplate,
41339
41550
  menuItems: menuItems,
41340
- onSaveMenuItem: handleSaveNewMenuItem
41551
+ onSaveMenuItem: handleSaveNewMenuItem,
41552
+ appId: credentials === null || credentials === void 0 ? void 0 : credentials.appId,
41553
+ onReloadWorkspaces: loadWorkspaces
41341
41554
  })]
41342
41555
  })]
41343
41556
  }), !popout && /*#__PURE__*/jsxRuntime.jsx(DashCommandPalette, {
@@ -41356,7 +41569,10 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
41356
41569
  },
41357
41570
  providers: (appContext === null || appContext === void 0 ? void 0 : appContext.providers) || {},
41358
41571
  onCreateNewProvider: function onCreateNewProvider() {
41359
- return openAppSettings("providers");
41572
+ return openAppSettings("providers", null, true);
41573
+ },
41574
+ onOpenProviderDetail: function onOpenProviderDetail(name) {
41575
+ return openAppSettings("providers", name);
41360
41576
  },
41361
41577
  themes: themes || {},
41362
41578
  currentThemeKey: themeKey,