@trops/dash-core 0.1.245 → 0.1.249

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
@@ -3574,6 +3574,102 @@ var StarRating = function StarRating(_ref) {
3574
3574
  });
3575
3575
  };
3576
3576
 
3577
+ var InstallProgressModal = function InstallProgressModal(_ref) {
3578
+ var isOpen = _ref.isOpen,
3579
+ setIsOpen = _ref.setIsOpen,
3580
+ _ref$widgets = _ref.widgets,
3581
+ widgets = _ref$widgets === void 0 ? [] : _ref$widgets,
3582
+ _ref$isComplete = _ref.isComplete,
3583
+ isComplete = _ref$isComplete === void 0 ? false : _ref$isComplete,
3584
+ onDone = _ref.onDone;
3585
+ var _useContext = React.useContext(DashReact.ThemeContext),
3586
+ currentTheme = _useContext.currentTheme;
3587
+ var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
3588
+ grow: false
3589
+ });
3590
+
3591
+ // Prevent dismissal while installation is in progress
3592
+ var guardedSetIsOpen = function guardedSetIsOpen(val) {
3593
+ if (isComplete) setIsOpen(val);
3594
+ };
3595
+ var doneCount = widgets.filter(function (w) {
3596
+ return w.status === "installed" || w.status === "already-installed" || w.status === "failed";
3597
+ }).length;
3598
+ function statusIcon(status) {
3599
+ switch (status) {
3600
+ case "downloading":
3601
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
3602
+ className: "animate-spin rounded-full h-4 w-4 border-b-2 border-blue-400 flex-shrink-0"
3603
+ });
3604
+ case "installed":
3605
+ case "already-installed":
3606
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
3607
+ icon: "circle-check",
3608
+ className: "h-4 w-4 text-green-400 flex-shrink-0"
3609
+ });
3610
+ case "failed":
3611
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
3612
+ icon: "circle-xmark",
3613
+ className: "h-4 w-4 text-red-400 flex-shrink-0"
3614
+ });
3615
+ default:
3616
+ // pending
3617
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
3618
+ icon: "clock",
3619
+ className: "h-4 w-4 opacity-30 flex-shrink-0"
3620
+ });
3621
+ }
3622
+ }
3623
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Modal, {
3624
+ isOpen: isOpen,
3625
+ setIsOpen: guardedSetIsOpen,
3626
+ width: "w-[440px]",
3627
+ height: "auto",
3628
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
3629
+ className: "flex flex-col rounded-lg overflow-hidden ".concat(panelStyles.backgroundColor || "bg-gray-900", " ").concat(panelStyles.textColor || "text-gray-200"),
3630
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
3631
+ className: "px-5 pt-5 pb-3",
3632
+ children: /*#__PURE__*/jsxRuntime.jsx("h3", {
3633
+ className: "text-sm font-semibold",
3634
+ children: isComplete ? "Installation Complete" : "Installing widget ".concat(doneCount + 1, " of ").concat(widgets.length, "...")
3635
+ })
3636
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
3637
+ className: "px-5 pb-3 space-y-1.5 max-h-64 overflow-y-auto",
3638
+ children: widgets.map(function (w, idx) {
3639
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
3640
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
3641
+ className: "flex items-center gap-2.5 p-2 rounded ".concat(currentTheme["bg-primary-medium"] || "bg-white/5"),
3642
+ children: [statusIcon(w.status), /*#__PURE__*/jsxRuntime.jsx("span", {
3643
+ className: "text-sm flex-1 truncate",
3644
+ children: w.displayName
3645
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
3646
+ className: "text-[10px] opacity-40",
3647
+ children: w.status === "already-installed" ? "Already installed" : w.status === "downloading" ? "Downloading..." : w.status === "installed" ? "Installed" : w.status === "failed" ? "Failed" : "Pending"
3648
+ })]
3649
+ }), w.status === "failed" && w.error && /*#__PURE__*/jsxRuntime.jsx("p", {
3650
+ className: "text-[10px] text-red-400/80 mt-0.5 ml-7 truncate",
3651
+ children: w.error
3652
+ })]
3653
+ }, idx);
3654
+ })
3655
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
3656
+ className: "flex items-center justify-end px-5 py-3 border-t ".concat(currentTheme["border-primary-medium"] || "border-white/10"),
3657
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
3658
+ title: "Done",
3659
+ bgColor: isComplete ? "bg-blue-600" : "bg-gray-700",
3660
+ hoverBackgroundColor: isComplete ? "hover:bg-blue-700" : "",
3661
+ textSize: "text-sm",
3662
+ padding: "py-1.5 px-4",
3663
+ onClick: function onClick() {
3664
+ if (isComplete && onDone) onDone();
3665
+ },
3666
+ disabled: !isComplete
3667
+ })
3668
+ })]
3669
+ })
3670
+ });
3671
+ };
3672
+
3577
3673
  function _createForOfIteratorHelper$g(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$g(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; } } }; }
3578
3674
  function _unsupportedIterableToArray$g(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$g(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$g(r, a) : void 0; } }
3579
3675
  function _arrayLikeToArray$g(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; }
@@ -3616,15 +3712,30 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
3616
3712
  _useState12 = _slicedToArray(_useState11, 2),
3617
3713
  authError = _useState12[0],
3618
3714
  setAuthError = _useState12[1];
3715
+ var _useState13 = React.useState(false),
3716
+ _useState14 = _slicedToArray(_useState13, 2),
3717
+ showProgressModal = _useState14[0],
3718
+ setShowProgressModal = _useState14[1];
3719
+ var _useState15 = React.useState([]),
3720
+ _useState16 = _slicedToArray(_useState15, 2),
3721
+ progressWidgets = _useState16[0],
3722
+ setProgressWidgets = _useState16[1];
3723
+ var _useState17 = React.useState(false),
3724
+ _useState18 = _slicedToArray(_useState17, 2),
3725
+ progressComplete = _useState18[0],
3726
+ setProgressComplete = _useState18[1];
3727
+ var progressResultRef = React.useRef(null);
3619
3728
  var pollIntervalRef = React.useRef(null);
3729
+ var cleanupProgressRef = React.useRef(null);
3620
3730
  var pkg = dashboardPackage;
3621
3731
  if (!pkg) return null;
3622
3732
 
3623
- // Clean up polling on unmount
3733
+ // Clean up polling and progress listener on unmount
3624
3734
  // eslint-disable-next-line react-hooks/rules-of-hooks
3625
3735
  React.useEffect(function () {
3626
3736
  return function () {
3627
3737
  if (pollIntervalRef.current) clearInterval(pollIntervalRef.current);
3738
+ if (cleanupProgressRef.current) cleanupProgressRef.current();
3628
3739
  };
3629
3740
  }, []);
3630
3741
 
@@ -3653,10 +3764,10 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
3653
3764
  }, [pkg.name]);
3654
3765
  function handleInstall() {
3655
3766
  return _handleInstall.apply(this, arguments);
3656
- }
3767
+ } // eslint-disable-next-line react-hooks/rules-of-hooks
3657
3768
  function _handleInstall() {
3658
3769
  _handleInstall = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
3659
- var _result$workspace, result, _t;
3770
+ var deps, _window$mainApi2, _window$mainApi2$onIn, result, _result$workspace2, _t;
3660
3771
  return _regeneratorRuntime.wrap(function (_context) {
3661
3772
  while (1) switch (_context.prev = _context.next) {
3662
3773
  case 0:
@@ -3670,6 +3781,35 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
3670
3781
  setInstallResult(null);
3671
3782
  setAuthFlow(null);
3672
3783
  setAuthError(null);
3784
+
3785
+ // Initialize progress modal from widget deps
3786
+ deps = widgetDeps.length > 0 ? widgetDeps : [];
3787
+ if (deps.length > 0) {
3788
+ setProgressWidgets(deps.map(function (w) {
3789
+ return {
3790
+ packageName: w["package"] || w.name,
3791
+ displayName: w.displayName || w.name || w["package"],
3792
+ status: "pending"
3793
+ };
3794
+ }));
3795
+ setProgressComplete(false);
3796
+ setShowProgressModal(true);
3797
+
3798
+ // Register progress listener
3799
+ if (cleanupProgressRef.current) cleanupProgressRef.current();
3800
+ cleanupProgressRef.current = (_window$mainApi2 = window.mainApi) === null || _window$mainApi2 === void 0 || (_window$mainApi2 = _window$mainApi2.dashboardConfig) === null || _window$mainApi2 === void 0 || (_window$mainApi2$onIn = _window$mainApi2.onInstallProgress) === null || _window$mainApi2$onIn === void 0 ? void 0 : _window$mainApi2$onIn.call(_window$mainApi2, function (data) {
3801
+ setProgressWidgets(function (prev) {
3802
+ var next = _toConsumableArray(prev);
3803
+ if (data.index >= 0 && data.index < next.length) {
3804
+ next[data.index] = _objectSpread$D(_objectSpread$D({}, next[data.index]), {}, {
3805
+ status: data.status,
3806
+ error: data.error || null
3807
+ });
3808
+ }
3809
+ return next;
3810
+ });
3811
+ });
3812
+ }
3673
3813
  _context.prev = 2;
3674
3814
  _context.next = 3;
3675
3815
  return window.mainApi.dashboardConfig.installDashboardFromRegistry(appId, pkg.name);
@@ -3679,33 +3819,52 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
3679
3819
  _context.next = 4;
3680
3820
  break;
3681
3821
  }
3682
- // Auth needed — show inline auth prompt (DASH-135)
3822
+ // Auth needed — close progress modal, show inline auth prompt
3823
+ setShowProgressModal(false);
3683
3824
  setIsInstalling(false);
3684
3825
  setInstallResult({
3685
3826
  status: "auth",
3686
3827
  message: result.error || "Sign in to install this dashboard."
3687
3828
  });
3829
+ if (cleanupProgressRef.current) {
3830
+ cleanupProgressRef.current();
3831
+ cleanupProgressRef.current = null;
3832
+ }
3688
3833
  return _context.abrupt("return");
3689
3834
  case 4:
3690
- setInstallResult({
3691
- status: result !== null && result !== void 0 && result.success ? "success" : "error",
3692
- 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."
3693
- });
3694
- if (result !== null && result !== void 0 && result.success && onInstallComplete) {
3695
- onInstallComplete(result);
3835
+ // Store result for use when modal closes
3836
+ progressResultRef.current = result;
3837
+ setProgressComplete(true);
3838
+
3839
+ // If no progress modal was shown, apply result directly
3840
+ if (deps.length === 0) {
3841
+ setInstallResult({
3842
+ status: result !== null && result !== void 0 && result.success ? "success" : "error",
3843
+ message: result !== null && result !== void 0 && result.success ? "Dashboard \"".concat(((_result$workspace2 = result.workspace) === null || _result$workspace2 === void 0 ? void 0 : _result$workspace2.name) || pkg.name, "\" installed successfully.") : (result === null || result === void 0 ? void 0 : result.error) || "Installation failed."
3844
+ });
3845
+ if (result !== null && result !== void 0 && result.success && onInstallComplete) {
3846
+ onInstallComplete(result);
3847
+ }
3696
3848
  }
3697
3849
  _context.next = 6;
3698
3850
  break;
3699
3851
  case 5:
3700
3852
  _context.prev = 5;
3701
3853
  _t = _context["catch"](2);
3702
- setInstallResult({
3703
- status: "error",
3704
- message: _t.message || "Failed to install dashboard."
3705
- });
3854
+ setProgressComplete(true);
3855
+ if (deps.length === 0) {
3856
+ setInstallResult({
3857
+ status: "error",
3858
+ message: _t.message || "Failed to install dashboard."
3859
+ });
3860
+ }
3706
3861
  case 6:
3707
3862
  _context.prev = 6;
3708
3863
  setIsInstalling(false);
3864
+ if (cleanupProgressRef.current) {
3865
+ cleanupProgressRef.current();
3866
+ cleanupProgressRef.current = null;
3867
+ }
3709
3868
  return _context.finish(6);
3710
3869
  case 7:
3711
3870
  case "end":
@@ -3715,6 +3874,20 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
3715
3874
  }));
3716
3875
  return _handleInstall.apply(this, arguments);
3717
3876
  }
3877
+ var handleProgressDone = React.useCallback(function () {
3878
+ setShowProgressModal(false);
3879
+ var result = progressResultRef.current;
3880
+ if (result) {
3881
+ var _result$workspace;
3882
+ setInstallResult({
3883
+ status: result.success ? "success" : "error",
3884
+ message: result.success ? "Dashboard \"".concat(((_result$workspace = result.workspace) === null || _result$workspace === void 0 ? void 0 : _result$workspace.name) || pkg.name, "\" installed successfully.") : result.error || "Installation failed."
3885
+ });
3886
+ if (result.success && onInstallComplete) {
3887
+ onInstallComplete(result);
3888
+ }
3889
+ }
3890
+ }, [pkg.name, onInstallComplete]);
3718
3891
  function handleSignIn() {
3719
3892
  return _handleSignIn.apply(this, arguments);
3720
3893
  }
@@ -4096,6 +4269,12 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
4096
4269
  onClick: handleInstall,
4097
4270
  disabled: isInstalling
4098
4271
  })
4272
+ }), /*#__PURE__*/jsxRuntime.jsx(InstallProgressModal, {
4273
+ isOpen: showProgressModal,
4274
+ setIsOpen: setShowProgressModal,
4275
+ widgets: progressWidgets,
4276
+ isComplete: progressComplete,
4277
+ onDone: handleProgressDone
4099
4278
  })]
4100
4279
  });
4101
4280
  };
@@ -22953,6 +23132,397 @@ var ExternalWidget = function ExternalWidget(_ref) {
22953
23132
  });
22954
23133
  };
22955
23134
 
23135
+ var RegistryPackageDetail = function RegistryPackageDetail(_ref) {
23136
+ var widget = _ref.widget,
23137
+ onInstall = _ref.onInstall,
23138
+ _ref$isInstalling = _ref.isInstalling,
23139
+ isInstalling = _ref$isInstalling === void 0 ? false : _ref$isInstalling,
23140
+ _ref$installError = _ref.installError,
23141
+ installError = _ref$installError === void 0 ? null : _ref$installError,
23142
+ _ref$isInstalled = _ref.isInstalled,
23143
+ isInstalled = _ref$isInstalled === void 0 ? false : _ref$isInstalled;
23144
+ var _useContext = React.useContext(DashReact.ThemeContext),
23145
+ currentTheme = _useContext.currentTheme;
23146
+ var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
23147
+ grow: false
23148
+ });
23149
+ if (!widget) return null;
23150
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
23151
+ className: "flex flex-col flex-1 min-h-0",
23152
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
23153
+ className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-6 ".concat(panelStyles.textColor || "text-gray-200"),
23154
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
23155
+ className: "flex flex-row items-center gap-3",
23156
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
23157
+ className: "h-5 w-5 flex-shrink-0 flex items-center justify-center",
23158
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
23159
+ icon: widget.icon || "cube",
23160
+ className: "h-5 w-5"
23161
+ })
23162
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
23163
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
23164
+ className: "flex items-center gap-2",
23165
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
23166
+ title: widget.packageDisplayName,
23167
+ padding: false
23168
+ }), isInstalled && /*#__PURE__*/jsxRuntime.jsx("span", {
23169
+ className: "text-[10px] px-1.5 py-0.5 rounded bg-emerald-500/20 text-emerald-400 flex-shrink-0",
23170
+ children: "Installed"
23171
+ })]
23172
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
23173
+ className: "flex items-center gap-2 mt-0.5",
23174
+ children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
23175
+ className: "text-sm opacity-60",
23176
+ children: ["by ", widget.packageAuthor || "Unknown"]
23177
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
23178
+ className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
23179
+ children: ["v", widget.packageVersion]
23180
+ })]
23181
+ })]
23182
+ })]
23183
+ }), /*#__PURE__*/jsxRuntime.jsx("hr", {
23184
+ className: currentTheme["border-primary-medium"]
23185
+ }), widget.packageDescription && /*#__PURE__*/jsxRuntime.jsx("p", {
23186
+ className: "text-sm",
23187
+ children: widget.packageDescription
23188
+ }), widget.packageTags && widget.packageTags.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
23189
+ className: "flex flex-wrap gap-1",
23190
+ children: widget.packageTags.map(function (tag) {
23191
+ return /*#__PURE__*/jsxRuntime.jsx("span", {
23192
+ className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-60"),
23193
+ children: tag
23194
+ }, tag);
23195
+ })
23196
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
23197
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
23198
+ className: "text-xs font-semibold opacity-50 mb-1 block",
23199
+ children: "INCLUDED WIDGETS"
23200
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
23201
+ className: "space-y-1.5",
23202
+ children: (widget.packageWidgets || []).map(function (w, idx) {
23203
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
23204
+ className: "p-2 rounded ".concat(currentTheme["bg-primary-medium"]),
23205
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
23206
+ className: "text-sm font-medium",
23207
+ children: w.displayName || w.name
23208
+ }), w.description && /*#__PURE__*/jsxRuntime.jsx("div", {
23209
+ className: "text-xs opacity-50 mt-0.5",
23210
+ children: w.description
23211
+ }), getUserConfigurableProviders(w.providers).length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
23212
+ className: "space-y-1 mt-1",
23213
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
23214
+ className: "flex gap-1 flex-wrap",
23215
+ children: getUserConfigurableProviders(w.providers).map(function (p, pidx) {
23216
+ return /*#__PURE__*/jsxRuntime.jsxs("span", {
23217
+ className: "text-xs px-1.5 py-0.5 rounded bg-blue-900/30 text-blue-400",
23218
+ children: [p.type, p.required ? " *" : ""]
23219
+ }, pidx);
23220
+ })
23221
+ }), getUserConfigurableProviders(w.providers).some(function (p) {
23222
+ var _p$requiredTools;
23223
+ return ((_p$requiredTools = p.requiredTools) === null || _p$requiredTools === void 0 ? void 0 : _p$requiredTools.length) > 0;
23224
+ }) && /*#__PURE__*/jsxRuntime.jsx("div", {
23225
+ className: "flex flex-wrap gap-1 ml-1",
23226
+ children: getUserConfigurableProviders(w.providers).filter(function (p) {
23227
+ var _p$requiredTools2;
23228
+ return ((_p$requiredTools2 = p.requiredTools) === null || _p$requiredTools2 === void 0 ? void 0 : _p$requiredTools2.length) > 0;
23229
+ }).flatMap(function (p) {
23230
+ return p.requiredTools.map(function (tool) {
23231
+ return /*#__PURE__*/jsxRuntime.jsx("span", {
23232
+ className: "text-[10px] font-mono px-1.5 py-0.5 rounded bg-white/5 opacity-60",
23233
+ children: tool
23234
+ }, "".concat(p.type, "-").concat(tool));
23235
+ });
23236
+ })
23237
+ })]
23238
+ })]
23239
+ }, idx);
23240
+ })
23241
+ })]
23242
+ }), widget.appOrigin && /*#__PURE__*/jsxRuntime.jsxs("div", {
23243
+ className: "flex items-center gap-1.5 text-xs opacity-50",
23244
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
23245
+ icon: "laptop",
23246
+ className: "h-3 w-3"
23247
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
23248
+ children: ["Built for ", widget.appOrigin]
23249
+ })]
23250
+ }), widget.missingApis && widget.missingApis.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
23251
+ className: "p-2 rounded bg-yellow-900/30 border border-yellow-700",
23252
+ children: /*#__PURE__*/jsxRuntime.jsxs("p", {
23253
+ className: "text-xs text-yellow-400",
23254
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
23255
+ icon: "triangle-exclamation",
23256
+ className: "mr-1"
23257
+ }), "Incompatible \u2014 requires ", widget.missingApis.join(", "), " API", widget.missingApis.length !== 1 ? "s" : ""]
23258
+ })
23259
+ }), widget.repository && /*#__PURE__*/jsxRuntime.jsxs("div", {
23260
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
23261
+ className: "text-xs font-semibold opacity-50 mb-1 block",
23262
+ children: "REPOSITORY"
23263
+ }), /*#__PURE__*/jsxRuntime.jsx("button", {
23264
+ type: "button",
23265
+ onClick: function onClick() {
23266
+ var _window$mainApi;
23267
+ return (_window$mainApi = window.mainApi) === null || _window$mainApi === void 0 || (_window$mainApi = _window$mainApi.shell) === null || _window$mainApi === void 0 ? void 0 : _window$mainApi.openExternal(widget.repository);
23268
+ },
23269
+ className: "text-sm text-blue-400 hover:text-blue-300 hover:underline transition-colors break-all text-left",
23270
+ children: widget.repository
23271
+ })]
23272
+ }), installError && /*#__PURE__*/jsxRuntime.jsx("div", {
23273
+ className: "p-2 rounded bg-red-900/30 border border-red-700",
23274
+ children: /*#__PURE__*/jsxRuntime.jsx("p", {
23275
+ className: "text-xs text-red-400",
23276
+ children: installError
23277
+ })
23278
+ })]
23279
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
23280
+ className: "flex items-center justify-end px-6 py-3 border-t ".concat(currentTheme["border-primary-medium"]),
23281
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
23282
+ title: isInstalled ? "Installed" : isInstalling ? "Installing..." : "Install Package",
23283
+ bgColor: isInstalled ? "bg-emerald-600/50" : "bg-blue-600",
23284
+ hoverBackgroundColor: isInstalled || isInstalling ? "" : "hover:bg-blue-700",
23285
+ textSize: "text-sm",
23286
+ padding: "py-1.5 px-4",
23287
+ onClick: onInstall,
23288
+ disabled: isInstalling || isInstalled
23289
+ })
23290
+ })]
23291
+ });
23292
+ };
23293
+
23294
+ function getWidgetSearchQuery(componentKey) {
23295
+ var parts = componentKey.split(".");
23296
+ if (parts.length >= 3) {
23297
+ return {
23298
+ packageName: parts[1],
23299
+ widgetName: parts[2],
23300
+ scope: parts[0]
23301
+ };
23302
+ }
23303
+ return {
23304
+ packageName: null,
23305
+ widgetName: componentKey,
23306
+ scope: null
23307
+ };
23308
+ }
23309
+
23310
+ /**
23311
+ * Convert a raw registry package object into the flat widget shape
23312
+ * expected by RegistryPackageDetail.
23313
+ */
23314
+ function packageToFlatWidget(pkg) {
23315
+ return {
23316
+ key: "".concat(pkg.name, "/0"),
23317
+ name: pkg.displayName || pkg.name,
23318
+ icon: pkg.icon || null,
23319
+ isRegistry: true,
23320
+ packageName: pkg.name,
23321
+ packageScope: pkg.scope || null,
23322
+ packageDisplayName: pkg.displayName || pkg.name,
23323
+ packageVersion: pkg.version,
23324
+ packageAuthor: pkg.author || "",
23325
+ packageDescription: pkg.description || "",
23326
+ packageTags: pkg.tags || [],
23327
+ packageCategory: pkg.category || "",
23328
+ downloadUrl: pkg.downloadUrl || "",
23329
+ repository: pkg.repository || "",
23330
+ publishedAt: pkg.publishedAt || "",
23331
+ packageWidgets: pkg.widgets || [],
23332
+ appOrigin: pkg.appOrigin || null,
23333
+ packageProviders: pkg.providers || [],
23334
+ missingApis: []
23335
+ };
23336
+ }
23337
+
23338
+ /**
23339
+ * WidgetNotFound — rendered in place of an unresolvable widget.
23340
+ *
23341
+ * Shows the existing "Widget Not Found" error display and adds a
23342
+ * "Find in Registry" button that does an exact registry lookup and
23343
+ * opens an install modal.
23344
+ */
23345
+ var WidgetNotFound = function WidgetNotFound(_ref) {
23346
+ var component = _ref.component;
23347
+ var _useState = React.useState(false),
23348
+ _useState2 = _slicedToArray(_useState, 2),
23349
+ showModal = _useState2[0],
23350
+ setShowModal = _useState2[1];
23351
+ var _useState3 = React.useState(null),
23352
+ _useState4 = _slicedToArray(_useState3, 2),
23353
+ registryWidget = _useState4[0],
23354
+ setRegistryWidget = _useState4[1];
23355
+ var _useState5 = React.useState(false),
23356
+ _useState6 = _slicedToArray(_useState5, 2),
23357
+ isLoading = _useState6[0],
23358
+ setIsLoading = _useState6[1];
23359
+ var _useState7 = React.useState(false),
23360
+ _useState8 = _slicedToArray(_useState7, 2),
23361
+ notFound = _useState8[0],
23362
+ setNotFound = _useState8[1];
23363
+ var _useState9 = React.useState(false),
23364
+ _useState0 = _slicedToArray(_useState9, 2),
23365
+ isInstalling = _useState0[0],
23366
+ setIsInstalling = _useState0[1];
23367
+ var _useState1 = React.useState(null),
23368
+ _useState10 = _slicedToArray(_useState1, 2),
23369
+ installError = _useState10[0],
23370
+ setInstallError = _useState10[1];
23371
+ var lookupWidget = React.useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
23372
+ var _getWidgetSearchQuery, packageName, widgetName, pkg, result;
23373
+ return _regeneratorRuntime.wrap(function (_context) {
23374
+ while (1) switch (_context.prev = _context.next) {
23375
+ case 0:
23376
+ setShowModal(true);
23377
+ setIsLoading(true);
23378
+ setNotFound(false);
23379
+ setRegistryWidget(null);
23380
+ setInstallError(null);
23381
+ _getWidgetSearchQuery = getWidgetSearchQuery(component), packageName = _getWidgetSearchQuery.packageName, widgetName = _getWidgetSearchQuery.widgetName;
23382
+ _context.prev = 1;
23383
+ pkg = null; // Scoped ID — exact package lookup
23384
+ if (!packageName) {
23385
+ _context.next = 3;
23386
+ break;
23387
+ }
23388
+ _context.next = 2;
23389
+ return window.mainApi.registry.getPackage(packageName);
23390
+ case 2:
23391
+ pkg = _context.sent;
23392
+ case 3:
23393
+ if (pkg) {
23394
+ _context.next = 5;
23395
+ break;
23396
+ }
23397
+ _context.next = 4;
23398
+ return window.mainApi.registry.search(widgetName);
23399
+ case 4:
23400
+ result = _context.sent;
23401
+ pkg = (result.packages || []).find(function (p) {
23402
+ return (p.widgets || []).some(function (w) {
23403
+ return w.name === widgetName;
23404
+ });
23405
+ });
23406
+ case 5:
23407
+ if (pkg) {
23408
+ setRegistryWidget(packageToFlatWidget(pkg));
23409
+ } else {
23410
+ setNotFound(true);
23411
+ }
23412
+ _context.next = 7;
23413
+ break;
23414
+ case 6:
23415
+ _context.prev = 6;
23416
+ _context["catch"](1);
23417
+ setNotFound(true);
23418
+ case 7:
23419
+ setIsLoading(false);
23420
+ case 8:
23421
+ case "end":
23422
+ return _context.stop();
23423
+ }
23424
+ }, _callee, null, [[1, 6]]);
23425
+ })), [component]);
23426
+ var handleInstall = React.useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
23427
+ var packageName, packageScope, downloadUrl, packageVersion, scopedId, resolvedUrl, _t2;
23428
+ return _regeneratorRuntime.wrap(function (_context2) {
23429
+ while (1) switch (_context2.prev = _context2.next) {
23430
+ case 0:
23431
+ if (registryWidget) {
23432
+ _context2.next = 1;
23433
+ break;
23434
+ }
23435
+ return _context2.abrupt("return");
23436
+ case 1:
23437
+ setIsInstalling(true);
23438
+ setInstallError(null);
23439
+ _context2.prev = 2;
23440
+ packageName = registryWidget.packageName, packageScope = registryWidget.packageScope, downloadUrl = registryWidget.downloadUrl, packageVersion = registryWidget.packageVersion;
23441
+ scopedId = packageScope ? "@".concat(packageScope.replace(/^@/, ""), "/").concat(packageName) : packageName;
23442
+ resolvedUrl = downloadUrl.replace(/\{version\}/g, packageVersion).replace(/\{name\}/g, packageName);
23443
+ _context2.next = 3;
23444
+ return window.mainApi.widgets.install(scopedId, resolvedUrl);
23445
+ case 3:
23446
+ setShowModal(false);
23447
+ _context2.next = 5;
23448
+ break;
23449
+ case 4:
23450
+ _context2.prev = 4;
23451
+ _t2 = _context2["catch"](2);
23452
+ setInstallError(_t2.message || "Failed to install package");
23453
+ case 5:
23454
+ setIsInstalling(false);
23455
+ case 6:
23456
+ case "end":
23457
+ return _context2.stop();
23458
+ }
23459
+ }, _callee2, null, [[2, 4]]);
23460
+ })), [registryWidget]);
23461
+ return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
23462
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
23463
+ className: "flex flex-col h-full justify-center items-center w-full z-10 gap-2 p-4 text-center",
23464
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
23465
+ icon: "triangle-exclamation",
23466
+ className: "h-6 w-6 text-amber-500"
23467
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
23468
+ className: "text-sm font-semibold text-gray-300",
23469
+ children: "Widget Not Found"
23470
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
23471
+ className: "text-xs text-gray-500 font-mono",
23472
+ children: component
23473
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
23474
+ className: "text-xs text-gray-600 mt-1",
23475
+ children: "This widget may have been uninstalled or renamed."
23476
+ }), /*#__PURE__*/jsxRuntime.jsxs("button", {
23477
+ type: "button",
23478
+ className: "flex items-center gap-1.5 text-xs text-blue-400 hover:text-blue-300 transition-colors mt-2",
23479
+ onClick: lookupWidget,
23480
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
23481
+ icon: "magnifying-glass",
23482
+ className: "h-3 w-3"
23483
+ }), "Find in Registry"]
23484
+ })]
23485
+ }), showModal && /*#__PURE__*/jsxRuntime.jsxs(DashReact.Modal, {
23486
+ title: "Registry Package",
23487
+ width: "w-1/3",
23488
+ height: "h-auto",
23489
+ onClose: function onClose() {
23490
+ return setShowModal(false);
23491
+ },
23492
+ children: [isLoading && /*#__PURE__*/jsxRuntime.jsx("div", {
23493
+ className: "flex items-center justify-center p-12",
23494
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
23495
+ icon: "spinner",
23496
+ className: "h-5 w-5 text-gray-400 animate-spin"
23497
+ })
23498
+ }), !isLoading && registryWidget && /*#__PURE__*/jsxRuntime.jsx(RegistryPackageDetail, {
23499
+ widget: registryWidget,
23500
+ onInstall: handleInstall,
23501
+ isInstalling: isInstalling,
23502
+ installError: installError
23503
+ }), !isLoading && notFound && /*#__PURE__*/jsxRuntime.jsxs("div", {
23504
+ className: "flex flex-col items-center justify-center gap-3 p-12 text-center",
23505
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
23506
+ icon: "triangle-exclamation",
23507
+ className: "h-6 w-6 text-amber-500"
23508
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
23509
+ className: "text-sm text-gray-400",
23510
+ children: "This widget is not available in the registry."
23511
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
23512
+ title: "Close",
23513
+ bgColor: "bg-gray-600",
23514
+ hoverBackgroundColor: "hover:bg-gray-700",
23515
+ textSize: "text-sm",
23516
+ padding: "py-1.5 px-4",
23517
+ onClick: function onClick() {
23518
+ return setShowModal(false);
23519
+ }
23520
+ })]
23521
+ })]
23522
+ })]
23523
+ });
23524
+ };
23525
+
22956
23526
  var GRID_CELL_WIDGET_TYPE = "grid-cell-widget";
22957
23527
  var SIDEBAR_WIDGET_TYPE = "sidebar-widget";
22958
23528
 
@@ -24977,21 +25547,8 @@ function renderComponent(component, id) {
24977
25547
  // WidgetFactory.render() always returns a React element (truthy),
24978
25548
  // so the old ternary fallback could never fire.
24979
25549
  if (!isWidgetResolvable(component)) {
24980
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
24981
- className: "flex flex-col h-full justify-center items-center w-full z-10 gap-2 p-4 text-center",
24982
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
24983
- icon: "triangle-exclamation",
24984
- className: "h-6 w-6 text-amber-500"
24985
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
24986
- className: "text-sm font-semibold text-gray-300",
24987
- children: "Widget Not Found"
24988
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
24989
- className: "text-xs text-gray-500 font-mono",
24990
- children: component
24991
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
24992
- className: "text-xs text-gray-600 mt-1",
24993
- children: "This widget may have been uninstalled or renamed."
24994
- })]
25550
+ return /*#__PURE__*/jsxRuntime.jsx(WidgetNotFound, {
25551
+ component: component
24995
25552
  });
24996
25553
  }
24997
25554
  if ("height" in params) {
@@ -38308,7 +38865,10 @@ var DashboardsSection = function DashboardsSection(_ref) {
38308
38865
  setInstallMode(null);
38309
38866
  setViewMode("grouped");
38310
38867
  },
38311
- appId: appId
38868
+ appId: appId,
38869
+ onInstallComplete: function onInstallComplete() {
38870
+ onReloadWorkspaces && onReloadWorkspaces();
38871
+ }
38312
38872
  });
38313
38873
  } else if (selectedWorkspace) {
38314
38874
  detailContent = /*#__PURE__*/jsxRuntime.jsx(DashboardDetail, {
@@ -43746,165 +44306,6 @@ var InstallWidgetPicker = function InstallWidgetPicker(_ref2) {
43746
44306
  });
43747
44307
  };
43748
44308
 
43749
- var RegistryPackageDetail = function RegistryPackageDetail(_ref) {
43750
- var widget = _ref.widget,
43751
- onInstall = _ref.onInstall,
43752
- _ref$isInstalling = _ref.isInstalling,
43753
- isInstalling = _ref$isInstalling === void 0 ? false : _ref$isInstalling,
43754
- _ref$installError = _ref.installError,
43755
- installError = _ref$installError === void 0 ? null : _ref$installError,
43756
- _ref$isInstalled = _ref.isInstalled,
43757
- isInstalled = _ref$isInstalled === void 0 ? false : _ref$isInstalled;
43758
- var _useContext = React.useContext(DashReact.ThemeContext),
43759
- currentTheme = _useContext.currentTheme;
43760
- var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
43761
- grow: false
43762
- });
43763
- if (!widget) return null;
43764
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
43765
- className: "flex flex-col flex-1 min-h-0",
43766
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
43767
- className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-6 ".concat(panelStyles.textColor || "text-gray-200"),
43768
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
43769
- className: "flex flex-row items-center gap-3",
43770
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
43771
- className: "h-5 w-5 flex-shrink-0 flex items-center justify-center",
43772
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
43773
- icon: widget.icon || "cube",
43774
- className: "h-5 w-5"
43775
- })
43776
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
43777
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
43778
- className: "flex items-center gap-2",
43779
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
43780
- title: widget.packageDisplayName,
43781
- padding: false
43782
- }), isInstalled && /*#__PURE__*/jsxRuntime.jsx("span", {
43783
- className: "text-[10px] px-1.5 py-0.5 rounded bg-emerald-500/20 text-emerald-400 flex-shrink-0",
43784
- children: "Installed"
43785
- })]
43786
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
43787
- className: "flex items-center gap-2 mt-0.5",
43788
- children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
43789
- className: "text-sm opacity-60",
43790
- children: ["by ", widget.packageAuthor || "Unknown"]
43791
- }), /*#__PURE__*/jsxRuntime.jsxs("span", {
43792
- className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
43793
- children: ["v", widget.packageVersion]
43794
- })]
43795
- })]
43796
- })]
43797
- }), /*#__PURE__*/jsxRuntime.jsx("hr", {
43798
- className: currentTheme["border-primary-medium"]
43799
- }), widget.packageDescription && /*#__PURE__*/jsxRuntime.jsx("p", {
43800
- className: "text-sm",
43801
- children: widget.packageDescription
43802
- }), widget.packageTags && widget.packageTags.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
43803
- className: "flex flex-wrap gap-1",
43804
- children: widget.packageTags.map(function (tag) {
43805
- return /*#__PURE__*/jsxRuntime.jsx("span", {
43806
- className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-60"),
43807
- children: tag
43808
- }, tag);
43809
- })
43810
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
43811
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
43812
- className: "text-xs font-semibold opacity-50 mb-1 block",
43813
- children: "INCLUDED WIDGETS"
43814
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
43815
- className: "space-y-1.5",
43816
- children: (widget.packageWidgets || []).map(function (w, idx) {
43817
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
43818
- className: "p-2 rounded ".concat(currentTheme["bg-primary-medium"]),
43819
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
43820
- className: "text-sm font-medium",
43821
- children: w.displayName || w.name
43822
- }), w.description && /*#__PURE__*/jsxRuntime.jsx("div", {
43823
- className: "text-xs opacity-50 mt-0.5",
43824
- children: w.description
43825
- }), getUserConfigurableProviders(w.providers).length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
43826
- className: "space-y-1 mt-1",
43827
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
43828
- className: "flex gap-1 flex-wrap",
43829
- children: getUserConfigurableProviders(w.providers).map(function (p, pidx) {
43830
- return /*#__PURE__*/jsxRuntime.jsxs("span", {
43831
- className: "text-xs px-1.5 py-0.5 rounded bg-blue-900/30 text-blue-400",
43832
- children: [p.type, p.required ? " *" : ""]
43833
- }, pidx);
43834
- })
43835
- }), getUserConfigurableProviders(w.providers).some(function (p) {
43836
- var _p$requiredTools;
43837
- return ((_p$requiredTools = p.requiredTools) === null || _p$requiredTools === void 0 ? void 0 : _p$requiredTools.length) > 0;
43838
- }) && /*#__PURE__*/jsxRuntime.jsx("div", {
43839
- className: "flex flex-wrap gap-1 ml-1",
43840
- children: getUserConfigurableProviders(w.providers).filter(function (p) {
43841
- var _p$requiredTools2;
43842
- return ((_p$requiredTools2 = p.requiredTools) === null || _p$requiredTools2 === void 0 ? void 0 : _p$requiredTools2.length) > 0;
43843
- }).flatMap(function (p) {
43844
- return p.requiredTools.map(function (tool) {
43845
- return /*#__PURE__*/jsxRuntime.jsx("span", {
43846
- className: "text-[10px] font-mono px-1.5 py-0.5 rounded bg-white/5 opacity-60",
43847
- children: tool
43848
- }, "".concat(p.type, "-").concat(tool));
43849
- });
43850
- })
43851
- })]
43852
- })]
43853
- }, idx);
43854
- })
43855
- })]
43856
- }), widget.appOrigin && /*#__PURE__*/jsxRuntime.jsxs("div", {
43857
- className: "flex items-center gap-1.5 text-xs opacity-50",
43858
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
43859
- icon: "laptop",
43860
- className: "h-3 w-3"
43861
- }), /*#__PURE__*/jsxRuntime.jsxs("span", {
43862
- children: ["Built for ", widget.appOrigin]
43863
- })]
43864
- }), widget.missingApis && widget.missingApis.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
43865
- className: "p-2 rounded bg-yellow-900/30 border border-yellow-700",
43866
- children: /*#__PURE__*/jsxRuntime.jsxs("p", {
43867
- className: "text-xs text-yellow-400",
43868
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
43869
- icon: "triangle-exclamation",
43870
- className: "mr-1"
43871
- }), "Incompatible \u2014 requires ", widget.missingApis.join(", "), " API", widget.missingApis.length !== 1 ? "s" : ""]
43872
- })
43873
- }), widget.repository && /*#__PURE__*/jsxRuntime.jsxs("div", {
43874
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
43875
- className: "text-xs font-semibold opacity-50 mb-1 block",
43876
- children: "REPOSITORY"
43877
- }), /*#__PURE__*/jsxRuntime.jsx("button", {
43878
- type: "button",
43879
- onClick: function onClick() {
43880
- var _window$mainApi;
43881
- return (_window$mainApi = window.mainApi) === null || _window$mainApi === void 0 || (_window$mainApi = _window$mainApi.shell) === null || _window$mainApi === void 0 ? void 0 : _window$mainApi.openExternal(widget.repository);
43882
- },
43883
- className: "text-sm text-blue-400 hover:text-blue-300 hover:underline transition-colors break-all text-left",
43884
- children: widget.repository
43885
- })]
43886
- }), installError && /*#__PURE__*/jsxRuntime.jsx("div", {
43887
- className: "p-2 rounded bg-red-900/30 border border-red-700",
43888
- children: /*#__PURE__*/jsxRuntime.jsx("p", {
43889
- className: "text-xs text-red-400",
43890
- children: installError
43891
- })
43892
- })]
43893
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
43894
- className: "flex items-center justify-end px-6 py-3 border-t ".concat(currentTheme["border-primary-medium"]),
43895
- children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
43896
- title: isInstalled ? "Installed" : isInstalling ? "Installing..." : "Install Package",
43897
- bgColor: isInstalled ? "bg-emerald-600/50" : "bg-blue-600",
43898
- hoverBackgroundColor: isInstalled || isInstalling ? "" : "hover:bg-blue-700",
43899
- textSize: "text-sm",
43900
- padding: "py-1.5 px-4",
43901
- onClick: onInstall,
43902
- disabled: isInstalling || isInstalled
43903
- })
43904
- })]
43905
- });
43906
- };
43907
-
43908
44309
  function _createForOfIteratorHelper$2(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$2(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; } } }; }
43909
44310
  function _unsupportedIterableToArray$2(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$2(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$2(r, a) : void 0; } }
43910
44311
  function _arrayLikeToArray$2(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; }
@@ -50809,6 +51210,7 @@ exports.WidgetApi = WidgetApi;
50809
51210
  exports.WidgetConfigPanel = WidgetConfigPanel;
50810
51211
  exports.WidgetContext = WidgetContext;
50811
51212
  exports.WidgetFactory = WidgetFactory;
51213
+ exports.WidgetNotFound = WidgetNotFound;
50812
51214
  exports.WidgetPopoutStage = WidgetPopoutStage;
50813
51215
  exports.WidgetProviderWrapper = WidgetProviderWrapper;
50814
51216
  exports.WidgetSidebar = WidgetSidebar;