@trops/dash-core 0.1.115 → 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');
@@ -49,8 +49,8 @@ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
49
49
  var jsxRuntime__namespace = /*#__PURE__*/_interopNamespaceDefault(jsxRuntime);
50
50
  var ReactDOM__namespace = /*#__PURE__*/_interopNamespaceDefault(ReactDOM);
51
51
 
52
- function ownKeys$A(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; }
53
- function _objectSpread$A(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$A(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$A(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
52
+ function ownKeys$B(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; }
53
+ function _objectSpread$B(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$B(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$B(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
54
54
  var event = {
55
55
  list: new Map(),
56
56
  // Map(1) { '<widget-UUID>' => { 'CustomSearchbar[10].searchQueryChanged': [] } }
@@ -112,7 +112,7 @@ var event = {
112
112
  uuid: subscriber["uuid"]
113
113
  };
114
114
  if ("action" in subscriber && subscriber.action !== undefined) {
115
- subscriber["action"](_objectSpread$A({}, objectToSend));
115
+ subscriber["action"](_objectSpread$B({}, objectToSend));
116
116
  }
117
117
  });
118
118
  }
@@ -2552,8 +2552,8 @@ var DashboardWrapper = function DashboardWrapper(_ref) {
2552
2552
  });
2553
2553
  };
2554
2554
 
2555
- function ownKeys$z(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; }
2556
- function _objectSpread$z(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$z(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$z(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2555
+ function ownKeys$A(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; }
2556
+ function _objectSpread$A(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$A(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$A(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2557
2557
  var DashboardThemeProvider = function DashboardThemeProvider(_ref) {
2558
2558
  var themeKey = _ref.themeKey,
2559
2559
  children = _ref.children;
@@ -2565,7 +2565,7 @@ var DashboardThemeProvider = function DashboardThemeProvider(_ref) {
2565
2565
  var dashboardTheme = themes[themeKey];
2566
2566
  var themeValue = dashboardTheme ? dashboardTheme[themeVariant] || null : null;
2567
2567
  if (!themeValue) return null;
2568
- return _objectSpread$z(_objectSpread$z({}, parentContext), {}, {
2568
+ return _objectSpread$A(_objectSpread$A({}, parentContext), {}, {
2569
2569
  currentTheme: themeValue,
2570
2570
  currentThemeKey: themeKey,
2571
2571
  theme: themeValue,
@@ -2583,8 +2583,8 @@ var DashboardThemeProvider = function DashboardThemeProvider(_ref) {
2583
2583
  });
2584
2584
  };
2585
2585
 
2586
- function ownKeys$y(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; }
2587
- function _objectSpread$y(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$y(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$y(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2586
+ function ownKeys$z(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; }
2587
+ function _objectSpread$z(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$z(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$z(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2588
2588
  var AppThemeScope = function AppThemeScope(_ref) {
2589
2589
  var children = _ref.children;
2590
2590
  var ctx = React.useContext(DashReact.ThemeContext);
@@ -2592,7 +2592,7 @@ var AppThemeScope = function AppThemeScope(_ref) {
2592
2592
  children: children
2593
2593
  });
2594
2594
  return /*#__PURE__*/jsxRuntime.jsx(DashReact.ThemeContext.Provider, {
2595
- value: _objectSpread$y(_objectSpread$y({}, ctx), {}, {
2595
+ value: _objectSpread$z(_objectSpread$z({}, ctx), {}, {
2596
2596
  currentTheme: ctx.appTheme,
2597
2597
  currentThemeKey: ctx.appThemeKey,
2598
2598
  theme: ctx.appTheme,
@@ -2704,8 +2704,8 @@ var LayoutContainer = function LayoutContainer(_ref) {
2704
2704
  });
2705
2705
  };
2706
2706
 
2707
- function ownKeys$x(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; }
2708
- function _objectSpread$x(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$x(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$x(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2707
+ function ownKeys$y(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; }
2708
+ function _objectSpread$y(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$y(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$y(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2709
2709
  function _createForOfIteratorHelper$a(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$a(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
2710
2710
  function _unsupportedIterableToArray$a(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$a(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$a(r, a) : void 0; } }
2711
2711
  function _arrayLikeToArray$a(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
@@ -2949,7 +2949,7 @@ function createLayoutFromTemplate(template) {
2949
2949
  try {
2950
2950
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
2951
2951
  var cell = _step.value;
2952
- grid[cell.key] = _objectSpread$x({
2952
+ grid[cell.key] = _objectSpread$y({
2953
2953
  component: null,
2954
2954
  hide: cell.hide || false
2955
2955
  }, cell.span ? {
@@ -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
 
@@ -8343,8 +9095,8 @@ var deepEqual = function deepEqual(a, b, opts) {
8343
9095
 
8344
9096
  var deepEqual$1 = /*@__PURE__*/getDefaultExportFromCjs(deepEqual);
8345
9097
 
8346
- function ownKeys$w(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; }
8347
- function _objectSpread$w(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$w(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$w(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
9098
+ function ownKeys$x(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; }
9099
+ function _objectSpread$x(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$x(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$x(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8348
9100
  var PanelEditItem = function PanelEditItem(_ref) {
8349
9101
  var _ComponentManager$get;
8350
9102
  var workspace = _ref.workspace,
@@ -8370,35 +9122,6 @@ var PanelEditItem = function PanelEditItem(_ref) {
8370
9122
  var widgetConfig = itemSelected ? ComponentManager.config(itemSelected.component, itemSelected) : null;
8371
9123
  var providerRequirements = (widgetConfig === null || widgetConfig === void 0 ? void 0 : widgetConfig.providers) || [];
8372
9124
  var selectedProviders = (itemSelected === null || itemSelected === void 0 ? void 0 : itemSelected.selectedProviders) || {};
8373
- var notificationDefs = (widgetConfig === null || widgetConfig === void 0 ? void 0 : widgetConfig.notifications) || [];
8374
-
8375
- // Notification preferences for this widget instance
8376
- var _useState7 = React.useState({}),
8377
- _useState8 = _slicedToArray(_useState7, 2),
8378
- notifPrefs = _useState8[0],
8379
- setNotifPrefs = _useState8[1];
8380
- var widgetUuid = (itemSelected === null || itemSelected === void 0 ? void 0 : itemSelected.uuid) || (itemSelected === null || itemSelected === void 0 ? void 0 : itemSelected.uuidString);
8381
- React.useEffect(function () {
8382
- var _window$mainApi;
8383
- if (notificationDefs.length > 0 && widgetUuid && (_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && (_window$mainApi = _window$mainApi.notifications) !== null && _window$mainApi !== void 0 && _window$mainApi.getPreferences) {
8384
- window.mainApi.notifications.getPreferences().then(function (result) {
8385
- var _result$instances;
8386
- setNotifPrefs(((_result$instances = result.instances) === null || _result$instances === void 0 ? void 0 : _result$instances[widgetUuid]) || {});
8387
- });
8388
- }
8389
- }, [widgetUuid, notificationDefs.length]);
8390
- function handleNotifToggle(typeKey, value) {
8391
- var _window$mainApi2;
8392
- var updated = _objectSpread$w(_objectSpread$w({}, notifPrefs), {}, _defineProperty({}, typeKey, value));
8393
- setNotifPrefs(updated);
8394
- if ((_window$mainApi2 = window.mainApi) !== null && _window$mainApi2 !== void 0 && (_window$mainApi2 = _window$mainApi2.notifications) !== null && _window$mainApi2 !== void 0 && _window$mainApi2.setPreferences && widgetUuid) {
8395
- window.mainApi.notifications.setPreferences(widgetUuid, _defineProperty({}, typeKey, value));
8396
- }
8397
- }
8398
- function getNotifEnabled(typeKey, defaultEnabled) {
8399
- if (typeof notifPrefs[typeKey] === "boolean") return notifPrefs[typeKey];
8400
- return defaultEnabled;
8401
- }
8402
9125
  React.useEffect(function () {
8403
9126
  if (deepEqual$1(item, itemSelected) === false) {
8404
9127
  setItemSelected(function () {
@@ -8433,7 +9156,7 @@ var PanelEditItem = function PanelEditItem(_ref) {
8433
9156
  var uuid = newItem.uuid || newItem.uuidString;
8434
9157
  if (uuid) {
8435
9158
  workspaceTemp.selectedProviders = workspaceTemp.selectedProviders || {};
8436
- workspaceTemp.selectedProviders[uuid] = _objectSpread$w(_objectSpread$w({}, workspaceTemp.selectedProviders[uuid] || {}), {}, _defineProperty({}, providerType, providerId));
9159
+ workspaceTemp.selectedProviders[uuid] = _objectSpread$x(_objectSpread$x({}, workspaceTemp.selectedProviders[uuid] || {}), {}, _defineProperty({}, providerType, providerId));
8437
9160
  }
8438
9161
  onUpdate(newItem, workspaceTemp);
8439
9162
  forceUpdate();
@@ -8562,7 +9285,7 @@ var PanelEditItem = function PanelEditItem(_ref) {
8562
9285
  var _ref5 = _slicedToArray(_ref4, 2),
8563
9286
  name = _ref5[0],
8564
9287
  p = _ref5[1];
8565
- return _objectSpread$w({
9288
+ return _objectSpread$x({
8566
9289
  name: name
8567
9290
  }, p);
8568
9291
  });
@@ -8599,31 +9322,6 @@ var PanelEditItem = function PanelEditItem(_ref) {
8599
9322
  })]
8600
9323
  }, providerType);
8601
9324
  })]
8602
- }), notificationDefs.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
8603
- className: "flex flex-col space-y-3",
8604
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
8605
- title: "Notifications",
8606
- padding: false
8607
- }), notificationDefs.map(function (notif) {
8608
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
8609
- className: "flex flex-row items-center justify-between py-1",
8610
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
8611
- className: "flex flex-col",
8612
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
8613
- className: "text-sm",
8614
- children: notif.displayName
8615
- }), notif.description && /*#__PURE__*/jsxRuntime.jsx("span", {
8616
- className: "text-xs opacity-50",
8617
- children: notif.description
8618
- })]
8619
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Switch, {
8620
- checked: getNotifEnabled(notif.key, notif.defaultEnabled),
8621
- onChange: function onChange(value) {
8622
- return handleNotifToggle(notif.key, value);
8623
- }
8624
- })]
8625
- }, notif.key);
8626
- })]
8627
9325
  })]
8628
9326
  });
8629
9327
  };
@@ -8632,8 +9330,8 @@ var _excluded$5 = ["rows", "cols"];
8632
9330
  function _createForOfIteratorHelper$9(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$9(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
8633
9331
  function _unsupportedIterableToArray$9(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$9(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray$9(r, a) : void 0; } }
8634
9332
  function _arrayLikeToArray$9(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
8635
- function ownKeys$v(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; }
8636
- function _objectSpread$v(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$v(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$v(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
9333
+ function ownKeys$w(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; }
9334
+ function _objectSpread$w(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$w(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$w(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8637
9335
  var defaultGrid = {
8638
9336
  rows: 1,
8639
9337
  cols: 1,
@@ -8654,7 +9352,7 @@ function GridEditor(_ref) {
8654
9352
  setGrid = _useState2[1];
8655
9353
  var addRow = function addRow() {
8656
9354
  var newRow = grid.rows;
8657
- var newGrid = _objectSpread$v(_objectSpread$v({}, grid), {}, {
9355
+ var newGrid = _objectSpread$w(_objectSpread$w({}, grid), {}, {
8658
9356
  rows: grid.rows + 1
8659
9357
  });
8660
9358
  for (var col = 0; col < grid.cols; col++) {
@@ -8669,7 +9367,7 @@ function GridEditor(_ref) {
8669
9367
  };
8670
9368
  var addColumn = function addColumn() {
8671
9369
  var newCol = grid.cols;
8672
- var newGrid = _objectSpread$v(_objectSpread$v({}, grid), {}, {
9370
+ var newGrid = _objectSpread$w(_objectSpread$w({}, grid), {}, {
8673
9371
  cols: grid.cols + 1
8674
9372
  });
8675
9373
  for (var row = 0; row < grid.rows; row++) {
@@ -8702,8 +9400,8 @@ function GridEditor(_ref) {
8702
9400
  });
8703
9401
  }
8704
9402
  if (grid[nextKey]) {
8705
- var newGrid = _objectSpread$v({}, grid);
8706
- newGrid[currentKey] = _objectSpread$v(_objectSpread$v({}, newGrid[currentKey]), {}, {
9403
+ var newGrid = _objectSpread$w({}, grid);
9404
+ newGrid[currentKey] = _objectSpread$w(_objectSpread$w({}, newGrid[currentKey]), {}, {
8707
9405
  colSpan: newGrid[currentKey].colSpan + 1
8708
9406
  });
8709
9407
  delete newGrid[nextKey];
@@ -8716,8 +9414,8 @@ function GridEditor(_ref) {
8716
9414
  var currentKey = "".concat(row, ".").concat(col);
8717
9415
  var belowKey = "".concat(row + 1, ".").concat(col);
8718
9416
  if (grid[belowKey]) {
8719
- var newGrid = _objectSpread$v({}, grid);
8720
- newGrid[currentKey] = _objectSpread$v(_objectSpread$v({}, newGrid[currentKey]), {}, {
9417
+ var newGrid = _objectSpread$w({}, grid);
9418
+ newGrid[currentKey] = _objectSpread$w(_objectSpread$w({}, newGrid[currentKey]), {}, {
8721
9419
  rowSpan: newGrid[currentKey].rowSpan + 1
8722
9420
  });
8723
9421
  delete newGrid[belowKey];
@@ -8734,7 +9432,7 @@ function GridEditor(_ref) {
8734
9432
  var splitCell = function splitCell(row, col) {
8735
9433
  var key = "".concat(row, ".").concat(col);
8736
9434
  var cell = grid[key];
8737
- var newGrid = _objectSpread$v({}, grid);
9435
+ var newGrid = _objectSpread$w({}, grid);
8738
9436
 
8739
9437
  // we have to check the colspan, and since the colspan is greater than 1
8740
9438
  // Only handle horizontal split if colSpan > 1
@@ -8750,13 +9448,13 @@ function GridEditor(_ref) {
8750
9448
  var oldKey = "".concat(row, ".").concat(c);
8751
9449
  var newKey = "".concat(row, ".").concat(c + 1);
8752
9450
  if (newGrid[oldKey]) {
8753
- newGrid[newKey] = _objectSpread$v({}, newGrid[oldKey]);
9451
+ newGrid[newKey] = _objectSpread$w({}, newGrid[oldKey]);
8754
9452
  delete newGrid[oldKey];
8755
9453
  }
8756
9454
  }
8757
9455
 
8758
9456
  // Update the original cell's colSpan
8759
- newGrid[key] = _objectSpread$v(_objectSpread$v({}, cell), {}, {
9457
+ newGrid[key] = _objectSpread$w(_objectSpread$w({}, cell), {}, {
8760
9458
  colSpan: cell.colSpan - 1
8761
9459
  });
8762
9460
 
@@ -8768,7 +9466,7 @@ function GridEditor(_ref) {
8768
9466
  };
8769
9467
  }
8770
9468
  if (cell.rowSpan > 1) {
8771
- newGrid[key] = _objectSpread$v(_objectSpread$v({}, newGrid[key]), {}, {
9469
+ newGrid[key] = _objectSpread$w(_objectSpread$w({}, newGrid[key]), {}, {
8772
9470
  rowSpan: cell.rowSpan - 1
8773
9471
  });
8774
9472
  newGrid["".concat(row + 1, ".").concat(col)] = {
@@ -8887,7 +9585,7 @@ function GridEditor(_ref) {
8887
9585
  var fromKey = "".concat(from.row, ".").concat(from.col);
8888
9586
  var toKey = "".concat(to.row, ".").concat(to.col);
8889
9587
  if (fromKey === toKey) return;
8890
- var newGrid = _objectSpread$v({}, grid);
9588
+ var newGrid = _objectSpread$w({}, grid);
8891
9589
 
8892
9590
  // Swap the cells
8893
9591
  var temp = newGrid[fromKey];
@@ -8913,7 +9611,7 @@ function GridEditor(_ref) {
8913
9611
  // console.log("Grid updated:", sequencedGrid);
8914
9612
  }
8915
9613
  function resetGridLayout() {
8916
- var newGrid = _objectSpread$v({}, defaultGrid);
9614
+ var newGrid = _objectSpread$w({}, defaultGrid);
8917
9615
  setGrid(newGrid);
8918
9616
  onUpdate(newGrid);
8919
9617
  }
@@ -9191,6 +9889,72 @@ var PanelEditItemGrid = function PanelEditItemGrid(_ref) {
9191
9889
  });
9192
9890
  };
9193
9891
 
9892
+ function ownKeys$v(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; }
9893
+ function _objectSpread$v(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$v(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$v(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
9894
+ var PanelEditItemNotifications = function PanelEditItemNotifications(_ref) {
9895
+ var item = _ref.item;
9896
+ _ref.workspace;
9897
+ _ref.onUpdate;
9898
+ var widgetConfig = item ? ComponentManager.config(item.component, item) : null;
9899
+ var notificationDefs = (widgetConfig === null || widgetConfig === void 0 ? void 0 : widgetConfig.notifications) || [];
9900
+ var _useState = React.useState({}),
9901
+ _useState2 = _slicedToArray(_useState, 2),
9902
+ notifPrefs = _useState2[0],
9903
+ setNotifPrefs = _useState2[1];
9904
+ var widgetUuid = (item === null || item === void 0 ? void 0 : item.uuid) || (item === null || item === void 0 ? void 0 : item.uuidString);
9905
+ React.useEffect(function () {
9906
+ var _window$mainApi;
9907
+ if (notificationDefs.length > 0 && widgetUuid && (_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && (_window$mainApi = _window$mainApi.notifications) !== null && _window$mainApi !== void 0 && _window$mainApi.getPreferences) {
9908
+ window.mainApi.notifications.getPreferences().then(function (result) {
9909
+ var _result$instances;
9910
+ setNotifPrefs(((_result$instances = result.instances) === null || _result$instances === void 0 ? void 0 : _result$instances[widgetUuid]) || {});
9911
+ });
9912
+ }
9913
+ }, [widgetUuid, notificationDefs.length]);
9914
+ function handleNotifToggle(typeKey, value) {
9915
+ var _window$mainApi2;
9916
+ var updated = _objectSpread$v(_objectSpread$v({}, notifPrefs), {}, _defineProperty({}, typeKey, value));
9917
+ setNotifPrefs(updated);
9918
+ if ((_window$mainApi2 = window.mainApi) !== null && _window$mainApi2 !== void 0 && (_window$mainApi2 = _window$mainApi2.notifications) !== null && _window$mainApi2 !== void 0 && _window$mainApi2.setPreferences && widgetUuid) {
9919
+ window.mainApi.notifications.setPreferences(widgetUuid, _defineProperty({}, typeKey, value));
9920
+ }
9921
+ }
9922
+ function getNotifEnabled(typeKey, defaultEnabled) {
9923
+ if (typeof notifPrefs[typeKey] === "boolean") return notifPrefs[typeKey];
9924
+ return defaultEnabled;
9925
+ }
9926
+ if (!item || notificationDefs.length === 0) return null;
9927
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
9928
+ className: "flex flex-col flex-1 min-h-0 overflow-y-auto p-6 space-y-6",
9929
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
9930
+ className: "flex flex-col space-y-3",
9931
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
9932
+ title: "Notifications",
9933
+ padding: false
9934
+ }), notificationDefs.map(function (notif) {
9935
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
9936
+ className: "flex flex-row items-center justify-between py-1",
9937
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
9938
+ className: "flex flex-col",
9939
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
9940
+ className: "text-sm",
9941
+ children: notif.displayName
9942
+ }), notif.description && /*#__PURE__*/jsxRuntime.jsx("span", {
9943
+ className: "text-xs opacity-50",
9944
+ children: notif.description
9945
+ })]
9946
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Switch, {
9947
+ checked: getNotifEnabled(notif.key, notif.defaultEnabled),
9948
+ onChange: function onChange(value) {
9949
+ return handleNotifToggle(notif.key, value);
9950
+ }
9951
+ })]
9952
+ }, notif.key);
9953
+ })]
9954
+ })
9955
+ });
9956
+ };
9957
+
9194
9958
  var PanelCode = function PanelCode(_ref) {
9195
9959
  var workspace = _ref.workspace,
9196
9960
  onUpdate = _ref.onUpdate,
@@ -9524,6 +10288,9 @@ var PanelEditItemHandlers = function PanelEditItemHandlers(_ref) {
9524
10288
  };
9525
10289
 
9526
10290
  var getSections = function getSections(item) {
10291
+ var _widgetConfig$notific;
10292
+ var widgetConfig = item ? ComponentManager.config(item.component, item) : null;
10293
+ var hasNotifications = (widgetConfig === null || widgetConfig === void 0 || (_widgetConfig$notific = widgetConfig.notifications) === null || _widgetConfig$notific === void 0 ? void 0 : _widgetConfig$notific.length) > 0;
9527
10294
  return [{
9528
10295
  key: "edit",
9529
10296
  label: "Settings",
@@ -9532,6 +10299,10 @@ var getSections = function getSections(item) {
9532
10299
  key: "grid_layout",
9533
10300
  label: "Layout",
9534
10301
  icon: "square"
10302
+ }] : []), _toConsumableArray(hasNotifications ? [{
10303
+ key: "notifications",
10304
+ label: "Notifications",
10305
+ icon: "bell"
9535
10306
  }] : []), _toConsumableArray((item === null || item === void 0 ? void 0 : item.workspace) !== "layout" ? [{
9536
10307
  key: "handlers",
9537
10308
  label: "Listeners",
@@ -9646,6 +10417,10 @@ var LayoutBuilderConfigModal = function LayoutBuilderConfigModal(_ref) {
9646
10417
  item: itemSelected,
9647
10418
  onUpdate: handleEditChange,
9648
10419
  workspace: workspaceSelected
10420
+ }), activeSection === "notifications" && /*#__PURE__*/jsxRuntime.jsx(PanelEditItemNotifications, {
10421
+ item: itemSelected,
10422
+ onUpdate: handleEditChange,
10423
+ workspace: workspaceSelected
9649
10424
  }), activeSection === "handlers" && /*#__PURE__*/jsxRuntime.jsx(PanelEditItemHandlers, {
9650
10425
  item: itemSelected,
9651
10426
  onUpdate: handleEditChange,
@@ -30637,102 +31412,6 @@ var ThemeManagerModal = function ThemeManagerModal(_ref) {
30637
31412
  });
30638
31413
  };
30639
31414
 
30640
- var StarRating = function StarRating(_ref) {
30641
- var appId = _ref.appId,
30642
- packageName = _ref.packageName,
30643
- _ref$interactive = _ref.interactive,
30644
- interactive = _ref$interactive === void 0 ? true : _ref$interactive;
30645
- var _useContext = React.useContext(DashReact.ThemeContext),
30646
- currentTheme = _useContext.currentTheme;
30647
- var _useState = React.useState(0),
30648
- _useState2 = _slicedToArray(_useState, 2),
30649
- rating = _useState2[0],
30650
- setRating = _useState2[1];
30651
- var _useState3 = React.useState(0),
30652
- _useState4 = _slicedToArray(_useState3, 2),
30653
- hoverRating = _useState4[0],
30654
- setHoverRating = _useState4[1];
30655
- var _useState5 = React.useState(true),
30656
- _useState6 = _slicedToArray(_useState5, 2),
30657
- loading = _useState6[0],
30658
- setLoading = _useState6[1];
30659
- React.useEffect(function () {
30660
- var _window$mainApi;
30661
- if (!appId || !packageName) return;
30662
- var cancelled = false;
30663
- setLoading(true);
30664
- (_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) {
30665
- if (!cancelled && result !== null && result !== void 0 && result.rating) {
30666
- setRating(result.rating);
30667
- }
30668
- })["catch"](function () {})["finally"](function () {
30669
- if (!cancelled) setLoading(false);
30670
- });
30671
- return function () {
30672
- cancelled = true;
30673
- };
30674
- }, [appId, packageName]);
30675
- function handleClick(_x) {
30676
- return _handleClick.apply(this, arguments);
30677
- }
30678
- function _handleClick() {
30679
- _handleClick = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(value) {
30680
- var newRating, _window$mainApi2;
30681
- return _regeneratorRuntime.wrap(function (_context) {
30682
- while (1) switch (_context.prev = _context.next) {
30683
- case 0:
30684
- if (!(!interactive || !appId || !packageName)) {
30685
- _context.next = 1;
30686
- break;
30687
- }
30688
- return _context.abrupt("return");
30689
- case 1:
30690
- newRating = value === rating ? 0 : value;
30691
- setRating(newRating);
30692
- _context.prev = 2;
30693
- _context.next = 3;
30694
- 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);
30695
- case 3:
30696
- _context.next = 5;
30697
- break;
30698
- case 4:
30699
- _context.prev = 4;
30700
- _context["catch"](2);
30701
- case 5:
30702
- case "end":
30703
- return _context.stop();
30704
- }
30705
- }, _callee, null, [[2, 4]]);
30706
- }));
30707
- return _handleClick.apply(this, arguments);
30708
- }
30709
- if (loading) return null;
30710
- var displayRating = hoverRating || rating;
30711
- return /*#__PURE__*/jsxRuntime.jsx("div", {
30712
- className: "flex items-center gap-0.5",
30713
- onMouseLeave: function onMouseLeave() {
30714
- return setHoverRating(0);
30715
- },
30716
- children: [1, 2, 3, 4, 5].map(function (star) {
30717
- return /*#__PURE__*/jsxRuntime.jsx("button", {
30718
- type: "button",
30719
- disabled: !interactive,
30720
- onClick: function onClick() {
30721
- return handleClick(star);
30722
- },
30723
- onMouseEnter: function onMouseEnter() {
30724
- return interactive && setHoverRating(star);
30725
- },
30726
- className: "p-0.5 transition-colors ".concat(interactive ? "cursor-pointer hover:scale-110" : "cursor-default"),
30727
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
30728
- icon: star <= displayRating ? "star" : ["far", "star"],
30729
- className: "h-3.5 w-3.5 ".concat(star <= displayRating ? "text-yellow-400" : currentTheme["text-primary-medium"] || "text-gray-500")
30730
- })
30731
- }, star);
30732
- })
30733
- });
30734
- };
30735
-
30736
31415
  var DASHBOARD_TAGS = ["productivity", "monitoring", "analytics", "communication", "developer", "sales", "marketing", "finance", "project-management", "social", "news", "utilities"];
30737
31416
 
30738
31417
  /**
@@ -31822,471 +32501,6 @@ var DashboardDetail = function DashboardDetail(_ref2) {
31822
32501
  });
31823
32502
  };
31824
32503
 
31825
- var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
31826
- var dashboardPackage = _ref.dashboardPackage,
31827
- appId = _ref.appId;
31828
- var _useContext = React.useContext(DashReact.ThemeContext),
31829
- currentTheme = _useContext.currentTheme;
31830
- var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
31831
- grow: false
31832
- });
31833
- var _useState = React.useState(null),
31834
- _useState2 = _slicedToArray(_useState, 2),
31835
- preview = _useState2[0],
31836
- setPreview = _useState2[1];
31837
- var _useState3 = React.useState(false),
31838
- _useState4 = _slicedToArray(_useState3, 2),
31839
- previewLoading = _useState4[0],
31840
- setPreviewLoading = _useState4[1];
31841
- var _useState5 = React.useState(false),
31842
- _useState6 = _slicedToArray(_useState5, 2),
31843
- isInstalling = _useState6[0],
31844
- setIsInstalling = _useState6[1];
31845
- var _useState7 = React.useState(null),
31846
- _useState8 = _slicedToArray(_useState7, 2),
31847
- installResult = _useState8[0],
31848
- setInstallResult = _useState8[1];
31849
- var pkg = dashboardPackage;
31850
- if (!pkg) return null;
31851
-
31852
- // Load preview data on mount
31853
- // eslint-disable-next-line react-hooks/rules-of-hooks
31854
- React.useEffect(function () {
31855
- var _window$mainApi;
31856
- if (!pkg.name) return;
31857
- var cancelled = false;
31858
- setPreviewLoading(true);
31859
- setPreview(null);
31860
- setInstallResult(null);
31861
- (_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) {
31862
- if (!cancelled) setPreview(result);
31863
- })["catch"](function (err) {
31864
- })["finally"](function () {
31865
- if (!cancelled) setPreviewLoading(false);
31866
- });
31867
- return function () {
31868
- cancelled = true;
31869
- };
31870
- }, [pkg.name]);
31871
- function handleInstall() {
31872
- return _handleInstall.apply(this, arguments);
31873
- }
31874
- function _handleInstall() {
31875
- _handleInstall = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
31876
- var _result$workspace, result, _t;
31877
- return _regeneratorRuntime.wrap(function (_context) {
31878
- while (1) switch (_context.prev = _context.next) {
31879
- case 0:
31880
- if (!(!appId || !pkg.name)) {
31881
- _context.next = 1;
31882
- break;
31883
- }
31884
- return _context.abrupt("return");
31885
- case 1:
31886
- setIsInstalling(true);
31887
- setInstallResult(null);
31888
- _context.prev = 2;
31889
- _context.next = 3;
31890
- return window.mainApi.dashboardConfig.installDashboardFromRegistry(appId, pkg.name);
31891
- case 3:
31892
- result = _context.sent;
31893
- setInstallResult({
31894
- status: result !== null && result !== void 0 && result.success ? "success" : "error",
31895
- 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."
31896
- });
31897
- _context.next = 5;
31898
- break;
31899
- case 4:
31900
- _context.prev = 4;
31901
- _t = _context["catch"](2);
31902
- setInstallResult({
31903
- status: "error",
31904
- message: _t.message || "Failed to install dashboard."
31905
- });
31906
- case 5:
31907
- _context.prev = 5;
31908
- setIsInstalling(false);
31909
- return _context.finish(5);
31910
- case 6:
31911
- case "end":
31912
- return _context.stop();
31913
- }
31914
- }, _callee, null, [[2, 4, 5, 6]]);
31915
- }));
31916
- return _handleInstall.apply(this, arguments);
31917
- }
31918
- var compatibility = preview === null || preview === void 0 ? void 0 : preview.compatibility;
31919
- var widgetDeps = (preview === null || preview === void 0 ? void 0 : preview.widgets) || pkg.widgets || [];
31920
- var providers = (preview === null || preview === void 0 ? void 0 : preview.providers) || [];
31921
- var wiring = (preview === null || preview === void 0 ? void 0 : preview.wiring) || [];
31922
- function getCompatIcon(status) {
31923
- if (status === "installed") return {
31924
- icon: "circle-check",
31925
- color: "text-green-400"
31926
- };
31927
- if (status === "available") return {
31928
- icon: "circle-down",
31929
- color: "text-blue-400"
31930
- };
31931
- return {
31932
- icon: "circle-xmark",
31933
- color: "text-red-400"
31934
- };
31935
- }
31936
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
31937
- className: "flex flex-col flex-1 min-h-0",
31938
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
31939
- className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-6 ".concat(panelStyles.textColor || "text-gray-200"),
31940
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
31941
- className: "flex flex-row items-center gap-3",
31942
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
31943
- className: "h-5 w-5 flex-shrink-0 flex items-center justify-center",
31944
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
31945
- icon: pkg.icon || "clone",
31946
- className: "h-5 w-5"
31947
- })
31948
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
31949
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
31950
- title: pkg.displayName || pkg.name,
31951
- padding: false
31952
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
31953
- className: "flex items-center gap-2 mt-0.5",
31954
- children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
31955
- className: "text-sm opacity-60",
31956
- children: ["by ", pkg.author || "Unknown"]
31957
- }), pkg.version && /*#__PURE__*/jsxRuntime.jsxs("span", {
31958
- className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
31959
- children: ["v", pkg.version]
31960
- })]
31961
- })]
31962
- })]
31963
- }), appId && /*#__PURE__*/jsxRuntime.jsx(StarRating, {
31964
- appId: appId,
31965
- packageName: pkg.name,
31966
- interactive: false
31967
- }), /*#__PURE__*/jsxRuntime.jsx("hr", {
31968
- className: currentTheme["border-primary-medium"]
31969
- }), pkg.description && /*#__PURE__*/jsxRuntime.jsx("p", {
31970
- className: "text-sm",
31971
- children: pkg.description
31972
- }), pkg.tags && pkg.tags.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
31973
- className: "flex flex-wrap gap-1",
31974
- children: pkg.tags.map(function (tag) {
31975
- return /*#__PURE__*/jsxRuntime.jsx("span", {
31976
- className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-60"),
31977
- children: tag
31978
- }, tag);
31979
- })
31980
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
31981
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
31982
- className: "text-xs font-semibold opacity-50 mb-1 block",
31983
- children: "REQUIRED WIDGETS"
31984
- }), previewLoading ? /*#__PURE__*/jsxRuntime.jsxs("div", {
31985
- className: "flex items-center gap-2 py-2",
31986
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
31987
- className: "animate-spin rounded-full h-4 w-4 border-b-2 border-blue-500"
31988
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
31989
- className: "text-xs opacity-50",
31990
- children: "Checking compatibility..."
31991
- })]
31992
- }) : /*#__PURE__*/jsxRuntime.jsx("div", {
31993
- className: "space-y-1.5",
31994
- children: widgetDeps.map(function (w, idx) {
31995
- var _compatibility$widget;
31996
- 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";
31997
- var compat = getCompatIcon(status);
31998
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
31999
- className: "p-2 rounded ".concat(currentTheme["bg-primary-medium"], " flex items-center gap-2"),
32000
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
32001
- icon: compat.icon,
32002
- className: "h-3.5 w-3.5 ".concat(compat.color)
32003
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
32004
- className: "text-sm",
32005
- children: w.displayName || w.name || w.packageName
32006
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
32007
- className: "text-xs opacity-40 ml-auto",
32008
- children: status === "installed" ? "Installed" : status === "available" ? "Will install" : "Unavailable"
32009
- })]
32010
- }, idx);
32011
- })
32012
- })]
32013
- }), providers.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
32014
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
32015
- className: "text-xs font-semibold opacity-50 mb-1 block",
32016
- children: "REQUIRED PROVIDERS"
32017
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
32018
- className: "space-y-1",
32019
- children: providers.map(function (p, idx) {
32020
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
32021
- className: "flex items-center gap-2",
32022
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
32023
- className: "text-xs px-1.5 py-0.5 rounded bg-blue-900/30 text-blue-400",
32024
- children: p.type
32025
- }), p.required && /*#__PURE__*/jsxRuntime.jsx("span", {
32026
- className: "text-[10px] opacity-40",
32027
- children: "Required"
32028
- })]
32029
- }, idx);
32030
- })
32031
- })]
32032
- }), wiring.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
32033
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
32034
- className: "text-xs font-semibold opacity-50 mb-1 block",
32035
- children: "EVENT WIRING"
32036
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
32037
- className: "space-y-1",
32038
- children: wiring.map(function (w, idx) {
32039
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
32040
- className: "text-xs p-2 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
32041
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
32042
- className: "font-medium",
32043
- children: w.from || "Source"
32044
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
32045
- icon: "arrow-right",
32046
- className: "h-2.5 w-2.5 mx-1.5 opacity-50"
32047
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
32048
- className: "font-medium",
32049
- children: w.to || "Target"
32050
- }), w.event && /*#__PURE__*/jsxRuntime.jsxs("span", {
32051
- className: "opacity-50 ml-1.5",
32052
- children: ["(", w.event, ")"]
32053
- })]
32054
- }, idx);
32055
- })
32056
- })]
32057
- }), installResult && /*#__PURE__*/jsxRuntime.jsx("div", {
32058
- className: "p-2 rounded border ".concat(installResult.status === "success" ? "bg-green-900/20 border-green-700" : "bg-red-900/30 border-red-700"),
32059
- children: /*#__PURE__*/jsxRuntime.jsxs("div", {
32060
- className: "flex items-center gap-2",
32061
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
32062
- icon: installResult.status === "success" ? "circle-check" : "circle-xmark",
32063
- className: "h-4 w-4 ".concat(installResult.status === "success" ? "text-green-400" : "text-red-400")
32064
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
32065
- className: "text-sm ".concat(installResult.status === "error" ? "text-red-400" : ""),
32066
- children: installResult.message
32067
- })]
32068
- })
32069
- })]
32070
- }), (installResult === null || installResult === void 0 ? void 0 : installResult.status) !== "success" && /*#__PURE__*/jsxRuntime.jsx("div", {
32071
- className: "flex items-center justify-end px-6 py-3 border-t ".concat(currentTheme["border-primary-medium"]),
32072
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
32073
- title: isInstalling ? "Installing..." : "Install Dashboard",
32074
- bgColor: "bg-blue-600",
32075
- hoverBackgroundColor: isInstalling ? "" : "hover:bg-blue-700",
32076
- textSize: "text-sm",
32077
- padding: "py-1.5 px-4",
32078
- onClick: handleInstall,
32079
- disabled: isInstalling
32080
- })
32081
- })]
32082
- });
32083
- };
32084
-
32085
- var DiscoverDashboardsDetail = function DiscoverDashboardsDetail(_ref) {
32086
- var onBack = _ref.onBack,
32087
- appId = _ref.appId;
32088
- var _useContext = React.useContext(DashReact.ThemeContext),
32089
- currentTheme = _useContext.currentTheme;
32090
- var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
32091
- grow: false
32092
- });
32093
- var _useState = React.useState([]),
32094
- _useState2 = _slicedToArray(_useState, 2),
32095
- packages = _useState2[0],
32096
- setPackages = _useState2[1];
32097
- var _useState3 = React.useState(false),
32098
- _useState4 = _slicedToArray(_useState3, 2),
32099
- isLoading = _useState4[0],
32100
- setIsLoading = _useState4[1];
32101
- var _useState5 = React.useState(null),
32102
- _useState6 = _slicedToArray(_useState5, 2),
32103
- error = _useState6[0],
32104
- setError = _useState6[1];
32105
- var _useState7 = React.useState(""),
32106
- _useState8 = _slicedToArray(_useState7, 2),
32107
- searchQuery = _useState8[0],
32108
- setSearchQuery = _useState8[1];
32109
- var _useState9 = React.useState(null),
32110
- _useState0 = _slicedToArray(_useState9, 2),
32111
- selectedPackageName = _useState0[0],
32112
- setSelectedPackageName = _useState0[1];
32113
- var search = React.useCallback(/*#__PURE__*/function () {
32114
- var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(query) {
32115
- var _window$mainApi;
32116
- var result, _t;
32117
- return _regeneratorRuntime.wrap(function (_context) {
32118
- while (1) switch (_context.prev = _context.next) {
32119
- case 0:
32120
- if ((_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && (_window$mainApi = _window$mainApi.registry) !== null && _window$mainApi !== void 0 && _window$mainApi.searchDashboards) {
32121
- _context.next = 1;
32122
- break;
32123
- }
32124
- setPackages([]);
32125
- return _context.abrupt("return");
32126
- case 1:
32127
- setIsLoading(true);
32128
- setError(null);
32129
- _context.prev = 2;
32130
- _context.next = 3;
32131
- return window.mainApi.registry.searchDashboards(query || "", {});
32132
- case 3:
32133
- result = _context.sent;
32134
- setPackages((result === null || result === void 0 ? void 0 : result.packages) || []);
32135
- _context.next = 5;
32136
- break;
32137
- case 4:
32138
- _context.prev = 4;
32139
- _t = _context["catch"](2);
32140
- setError(_t.message || "Failed to search dashboard registry");
32141
- setPackages([]);
32142
- case 5:
32143
- _context.prev = 5;
32144
- setIsLoading(false);
32145
- return _context.finish(5);
32146
- case 6:
32147
- case "end":
32148
- return _context.stop();
32149
- }
32150
- }, _callee, null, [[2, 4, 5, 6]]);
32151
- }));
32152
- return function (_x) {
32153
- return _ref2.apply(this, arguments);
32154
- };
32155
- }(), []);
32156
-
32157
- // Debounce search on query changes
32158
- React.useEffect(function () {
32159
- var timer = setTimeout(function () {
32160
- search(searchQuery);
32161
- }, 300);
32162
- return function () {
32163
- return clearTimeout(timer);
32164
- };
32165
- // eslint-disable-next-line react-hooks/exhaustive-deps
32166
- }, [searchQuery]);
32167
- var retry = function retry() {
32168
- return search(searchQuery);
32169
- };
32170
- var selectedPackage = selectedPackageName ? packages.find(function (p) {
32171
- return p.name === selectedPackageName;
32172
- }) : null;
32173
-
32174
- // If a package is selected, show its detail inline
32175
- if (selectedPackage) {
32176
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
32177
- className: "flex flex-col flex-1 min-h-0",
32178
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
32179
- className: "flex-shrink-0 px-4 pt-4",
32180
- children: /*#__PURE__*/jsxRuntime.jsxs("button", {
32181
- type: "button",
32182
- onClick: function onClick() {
32183
- return setSelectedPackageName(null);
32184
- },
32185
- className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
32186
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
32187
- icon: "arrow-left",
32188
- className: "h-3 w-3"
32189
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
32190
- children: "Back"
32191
- })]
32192
- })
32193
- }), /*#__PURE__*/jsxRuntime.jsx(RegistryDashboardDetail, {
32194
- dashboardPackage: selectedPackage,
32195
- appId: appId
32196
- })]
32197
- });
32198
- }
32199
-
32200
- // Package list view
32201
- var listBody;
32202
- if (isLoading) {
32203
- listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
32204
- className: "flex items-center justify-center py-12",
32205
- children: /*#__PURE__*/jsxRuntime.jsxs("div", {
32206
- className: "text-center",
32207
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
32208
- className: "animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500 mx-auto mb-3"
32209
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
32210
- className: "text-sm opacity-50",
32211
- children: "Loading dashboards..."
32212
- })]
32213
- })
32214
- });
32215
- } else if (error) {
32216
- listBody = /*#__PURE__*/jsxRuntime.jsxs("div", {
32217
- className: "px-4 py-8 text-center",
32218
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
32219
- className: "text-sm text-red-400 mb-3",
32220
- children: error
32221
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
32222
- title: "Retry",
32223
- bgColor: "bg-gray-700",
32224
- hoverBackgroundColor: "hover:bg-gray-600",
32225
- textSize: "text-sm",
32226
- padding: "py-1 px-3",
32227
- onClick: retry
32228
- })]
32229
- });
32230
- } else if (packages.length === 0) {
32231
- listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
32232
- className: "px-4 py-8 text-center",
32233
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
32234
- className: "text-sm opacity-50",
32235
- children: searchQuery ? "No dashboards match your search." : "No dashboard packages available."
32236
- })
32237
- });
32238
- } else {
32239
- listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
32240
- className: "space-y-1",
32241
- children: packages.map(function (pkg) {
32242
- var widgetCount = (pkg.widgets || []).length;
32243
- return /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
32244
- icon: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
32245
- icon: pkg.icon || "clone",
32246
- className: "h-3.5 w-3.5"
32247
- }),
32248
- onClick: function onClick() {
32249
- return setSelectedPackageName(pkg.name);
32250
- },
32251
- badge: widgetCount > 0 ? "".concat(widgetCount) : undefined,
32252
- children: pkg.displayName || pkg.name
32253
- }, pkg.name);
32254
- })
32255
- });
32256
- }
32257
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
32258
- className: "flex flex-col flex-1 min-h-0 ".concat(panelStyles.textColor || "text-gray-200"),
32259
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
32260
- className: "flex-shrink-0 px-4 pt-4",
32261
- children: /*#__PURE__*/jsxRuntime.jsxs("button", {
32262
- type: "button",
32263
- onClick: onBack,
32264
- className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
32265
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
32266
- icon: "arrow-left",
32267
- className: "h-3 w-3"
32268
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
32269
- children: "Back"
32270
- })]
32271
- })
32272
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
32273
- className: "flex-shrink-0 px-4 py-3",
32274
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.SearchInput, {
32275
- value: searchQuery,
32276
- onChange: setSearchQuery,
32277
- placeholder: "Search dashboards...",
32278
- inputClassName: "py-1.5 text-xs"
32279
- })
32280
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
32281
- className: "flex-1 min-h-0 overflow-y-auto px-2",
32282
- children: listBody
32283
- }), !isLoading && !error && packages.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
32284
- className: "flex-shrink-0 px-4 py-2 text-[10px] opacity-40 border-t border-white/10",
32285
- children: [packages.length, " dashboard", packages.length !== 1 ? "s" : ""]
32286
- })]
32287
- });
32288
- };
32289
-
32290
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; }
32291
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; }
32292
32506
  var DashboardsSection = function DashboardsSection(_ref) {
@@ -40490,9 +40704,21 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
40490
40704
  _useState36 = _slicedToArray(_useState35, 2),
40491
40705
  appSettingsInitialSection = _useState36[0],
40492
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];
40493
40715
  function openAppSettings() {
40494
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;
40495
40719
  setAppSettingsInitialSection(section);
40720
+ setAppSettingsInitialProvider(providerName);
40721
+ setAppSettingsCreateProvider(createProvider);
40496
40722
  setIsAppSettingsOpen(true);
40497
40723
  }
40498
40724
  function handleProfileUpdated() {
@@ -41273,8 +41499,16 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
41273
41499
  }), !popout && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
41274
41500
  children: [/*#__PURE__*/jsxRuntime.jsx(AppSettingsModal, {
41275
41501
  isOpen: isAppSettingsOpen,
41276
- setIsOpen: setIsAppSettingsOpen,
41502
+ setIsOpen: function setIsOpen(open) {
41503
+ setIsAppSettingsOpen(open);
41504
+ if (!open) {
41505
+ setAppSettingsInitialProvider(null);
41506
+ setAppSettingsCreateProvider(false);
41507
+ }
41508
+ },
41277
41509
  initialSection: appSettingsInitialSection,
41510
+ initialProviderName: appSettingsInitialProvider,
41511
+ initialCreateProvider: appSettingsCreateProvider,
41278
41512
  workspaces: workspaceConfig,
41279
41513
  menuItems: menuItems,
41280
41514
  dashApi: dashApi,
@@ -41314,7 +41548,9 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
41314
41548
  setIsOpen: setIsLayoutPickerOpen,
41315
41549
  onCreateWorkspace: handleCreateFromTemplate,
41316
41550
  menuItems: menuItems,
41317
- onSaveMenuItem: handleSaveNewMenuItem
41551
+ onSaveMenuItem: handleSaveNewMenuItem,
41552
+ appId: credentials === null || credentials === void 0 ? void 0 : credentials.appId,
41553
+ onReloadWorkspaces: loadWorkspaces
41318
41554
  })]
41319
41555
  })]
41320
41556
  }), !popout && /*#__PURE__*/jsxRuntime.jsx(DashCommandPalette, {
@@ -41333,7 +41569,10 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
41333
41569
  },
41334
41570
  providers: (appContext === null || appContext === void 0 ? void 0 : appContext.providers) || {},
41335
41571
  onCreateNewProvider: function onCreateNewProvider() {
41336
- return openAppSettings("providers");
41572
+ return openAppSettings("providers", null, true);
41573
+ },
41574
+ onOpenProviderDetail: function onOpenProviderDetail(name) {
41575
+ return openAppSettings("providers", name);
41337
41576
  },
41338
41577
  themes: themes || {},
41339
41578
  currentThemeKey: themeKey,
@@ -42850,6 +43089,7 @@ exports.PROVIDER_SAVE_ERROR = PROVIDER_SAVE_ERROR;
42850
43089
  exports.PanelCode = PanelCode;
42851
43090
  exports.PanelEditItem = PanelEditItem;
42852
43091
  exports.PanelEditItemHandlers = PanelEditItemHandlers;
43092
+ exports.PanelEditItemNotifications = PanelEditItemNotifications;
42853
43093
  exports.ProviderContext = ProviderContext;
42854
43094
  exports.ProviderErrorBoundary = ProviderErrorBoundary;
42855
43095
  exports.ProviderForm = ProviderForm;