@trops/dash-core 0.1.444 → 0.1.446

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -2,7 +2,7 @@ import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
2
2
  import _typeof from '@babel/runtime/helpers/typeof';
3
3
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
4
4
  import * as DashReact from '@trops/dash-react';
5
- import { isObject, ThemeContext, deepCopy, MainSection, getUUID, getStylesForItem, themeObjects, Heading, SearchInput, ButtonIcon, SubHeading3, InputText, Button, FontAwesomeIcon, Tag, Modal, Paragraph, Sidebar, Panel, Stepper, Tag2, Tag3, Card2, Card3, Heading3, MenuItem3, FormLabel, SelectMenu, Switch, SelectInput, CodeEditorVS, SettingsModal, SubHeading2, tailwindHeightFractions, Menu3, Panel3, ButtonIcon2, DropdownPanel, MenuItem2, DragComponent, ConfirmationModal, DropComponent, getStyleName, capitalizeFirstLetter, colorTypes, getCSSStyleForClassname, Panel2, Heading2, SubHeading, Paragraph2, Paragraph3, Button2, Button3, MenuItem, ButtonIcon3, DashPanel, colorNames, shades, themeVariants, Tabs3, DataList, Checkbox, StatCard, Card, Tabs, Accordion, Alert, Toast, ProgressBar, Toggle, Breadcrumbs, Tabs2, Accordion2, Alert2, Toast2, ProgressBar2, Toggle2, Breadcrumbs2, Accordion3, Alert3, Toast3, ProgressBar3, Toggle3, Breadcrumbs3, ThemeFromUrlPane, TextArea, CodeEditorInline, Icon2, AlgoliaSearchBox, CommandPalette, useSidebar, EmptyState, Navbar, withRouter, Menu as Menu$1 } from '@trops/dash-react';
5
+ import { isObject, ThemeContext, deepCopy, MainSection, getUUID, getStylesForItem, themeObjects, Heading, SearchInput, ButtonIcon, SubHeading3, InputText, Button, FontAwesomeIcon, Tag, Modal, Button3, Button2, Paragraph, Sidebar, Panel, Stepper, Tag2, Tag3, Card2, Card3, Heading3, MenuItem3, FormLabel, SelectMenu, Switch, SelectInput, CodeEditorVS, SettingsModal, SubHeading2, tailwindHeightFractions, Menu3, Panel3, ButtonIcon2, DropdownPanel, MenuItem2, DragComponent, ConfirmationModal, DropComponent, getStyleName, capitalizeFirstLetter, colorTypes, getCSSStyleForClassname, Panel2, Heading2, SubHeading, Paragraph2, Paragraph3, MenuItem, ButtonIcon3, DashPanel, colorNames, shades, themeVariants, Tabs3, DataList, Checkbox, StatCard, Card, Tabs, Accordion, Alert, Toast, ProgressBar, Toggle, Breadcrumbs, Tabs2, Accordion2, Alert2, Toast2, ProgressBar2, Toggle2, Breadcrumbs2, Accordion3, Alert3, Toast3, ProgressBar3, Toggle3, Breadcrumbs3, ThemeFromUrlPane, TextArea, CodeEditorInline, Icon2, AlgoliaSearchBox, CommandPalette, useSidebar, EmptyState, Navbar, withRouter, Menu as Menu$1 } from '@trops/dash-react';
6
6
  export * from '@trops/dash-react';
7
7
  export { ThemeContext } from '@trops/dash-react';
8
8
  import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
@@ -32,8 +32,8 @@ import { InstantSearch, Hits } from 'react-instantsearch-hooks-web';
32
32
  import { Link } from 'react-router-dom';
33
33
  import { marked } from 'marked';
34
34
 
35
- function ownKeys$$(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; }
36
- function _objectSpread$$(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$$(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$$(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
35
+ 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; }
36
+ 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; }
37
37
  var event = {
38
38
  list: new Map(),
39
39
  // Map(1) { '<widget-UUID>' => { 'CustomSearchbar[10].searchQueryChanged': [] } }
@@ -95,7 +95,7 @@ var event = {
95
95
  uuid: subscriber["uuid"]
96
96
  };
97
97
  if ("action" in subscriber && subscriber.action !== undefined) {
98
- subscriber["action"](_objectSpread$$({}, objectToSend));
98
+ subscriber["action"](_objectSpread$Z({}, objectToSend));
99
99
  }
100
100
  });
101
101
  }
@@ -2873,8 +2873,8 @@ var DashboardWrapper = function DashboardWrapper(_ref) {
2873
2873
  });
2874
2874
  };
2875
2875
 
2876
- function ownKeys$_(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; }
2877
- function _objectSpread$_(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$_(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$_(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
2876
+ 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; }
2877
+ 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; }
2878
2878
  function ThemeBroadcast(_ref) {
2879
2879
  var ctx = _ref.ctx;
2880
2880
  useEffect(function () {
@@ -2907,7 +2907,7 @@ var DashboardThemeProvider = function DashboardThemeProvider(_ref2) {
2907
2907
  var dashboardTheme = themes[themeKey];
2908
2908
  var themeValue = dashboardTheme ? dashboardTheme[themeVariant] || null : null;
2909
2909
  if (!themeValue) return null;
2910
- return _objectSpread$_(_objectSpread$_({}, parentContext), {}, {
2910
+ return _objectSpread$Y(_objectSpread$Y({}, parentContext), {}, {
2911
2911
  currentTheme: themeValue,
2912
2912
  currentThemeKey: themeKey,
2913
2913
  theme: themeValue,
@@ -2934,8 +2934,8 @@ var DashboardThemeProvider = function DashboardThemeProvider(_ref2) {
2934
2934
  });
2935
2935
  };
2936
2936
 
2937
- 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; }
2938
- 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; }
2937
+ 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; }
2938
+ 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; }
2939
2939
  var AppThemeScope = function AppThemeScope(_ref) {
2940
2940
  var children = _ref.children;
2941
2941
  var ctx = useContext(ThemeContext);
@@ -2943,7 +2943,7 @@ var AppThemeScope = function AppThemeScope(_ref) {
2943
2943
  children: children
2944
2944
  });
2945
2945
  return /*#__PURE__*/jsx(ThemeContext.Provider, {
2946
- value: _objectSpread$Z(_objectSpread$Z({}, ctx), {}, {
2946
+ value: _objectSpread$X(_objectSpread$X({}, ctx), {}, {
2947
2947
  currentTheme: ctx.appTheme,
2948
2948
  currentThemeKey: ctx.appThemeKey,
2949
2949
  theme: ctx.appTheme,
@@ -3055,8 +3055,8 @@ var LayoutContainer = function LayoutContainer(_ref) {
3055
3055
  });
3056
3056
  };
3057
3057
 
3058
- 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; }
3059
- 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; }
3058
+ 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; }
3059
+ 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; }
3060
3060
  function _createForOfIteratorHelper$x(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$x(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; } } }; }
3061
3061
  function _unsupportedIterableToArray$x(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$x(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$x(r, a) : void 0; } }
3062
3062
  function _arrayLikeToArray$x(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; }
@@ -3338,7 +3338,7 @@ function createLayoutFromTemplate(template) {
3338
3338
  try {
3339
3339
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
3340
3340
  var cell = _step.value;
3341
- grid[cell.key] = _objectSpread$Y({
3341
+ grid[cell.key] = _objectSpread$W({
3342
3342
  component: null,
3343
3343
  hide: cell.hide || false
3344
3344
  }, cell.span ? {
@@ -4264,11 +4264,261 @@ var RegistryAuthModal = function RegistryAuthModal(_ref) {
4264
4264
  });
4265
4265
  };
4266
4266
 
4267
+ var DashboardInstallOptionsModal = function DashboardInstallOptionsModal(_ref) {
4268
+ var _menuItems$;
4269
+ var isOpen = _ref.isOpen,
4270
+ setIsOpen = _ref.setIsOpen,
4271
+ pkg = _ref.pkg,
4272
+ _ref$menuItems = _ref.menuItems,
4273
+ menuItems = _ref$menuItems === void 0 ? [] : _ref$menuItems,
4274
+ onCreateFolder = _ref.onCreateFolder,
4275
+ onConfirm = _ref.onConfirm;
4276
+ var _useContext = useContext(ThemeContext),
4277
+ currentTheme = _useContext.currentTheme;
4278
+ var panelStyles = getStylesForItem(themeObjects.PANEL, currentTheme, {
4279
+ grow: false
4280
+ });
4281
+ var defaultName = (pkg === null || pkg === void 0 ? void 0 : pkg.displayName) || (pkg === null || pkg === void 0 ? void 0 : pkg.name) || "";
4282
+ var _useState = useState(defaultName),
4283
+ _useState2 = _slicedToArray(_useState, 2),
4284
+ name = _useState2[0],
4285
+ setName = _useState2[1];
4286
+ var _useState3 = useState(((_menuItems$ = menuItems[0]) === null || _menuItems$ === void 0 ? void 0 : _menuItems$.id) != null ? String(menuItems[0].id) : ""),
4287
+ _useState4 = _slicedToArray(_useState3, 2),
4288
+ selectedMenuId = _useState4[0],
4289
+ setSelectedMenuId = _useState4[1];
4290
+ var _useState5 = useState(false),
4291
+ _useState6 = _slicedToArray(_useState5, 2),
4292
+ newFolderMode = _useState6[0],
4293
+ setNewFolderMode = _useState6[1];
4294
+ var _useState7 = useState(""),
4295
+ _useState8 = _slicedToArray(_useState7, 2),
4296
+ newFolderName = _useState8[0],
4297
+ setNewFolderName = _useState8[1];
4298
+ var _useState9 = useState(false),
4299
+ _useState0 = _slicedToArray(_useState9, 2),
4300
+ creating = _useState0[0],
4301
+ setCreating = _useState0[1];
4302
+ var _useState1 = useState(null),
4303
+ _useState10 = _slicedToArray(_useState1, 2),
4304
+ error = _useState10[0],
4305
+ setError = _useState10[1];
4306
+
4307
+ // Reset state every time the modal opens with a new package.
4308
+ useEffect(function () {
4309
+ var _menuItems$2;
4310
+ if (!isOpen) return;
4311
+ setName(defaultName);
4312
+ setSelectedMenuId(((_menuItems$2 = menuItems[0]) === null || _menuItems$2 === void 0 ? void 0 : _menuItems$2.id) != null ? String(menuItems[0].id) : "");
4313
+ setNewFolderMode(false);
4314
+ setNewFolderName("");
4315
+ setError(null);
4316
+ // eslint-disable-next-line react-hooks/exhaustive-deps
4317
+ }, [isOpen, pkg === null || pkg === void 0 ? void 0 : pkg.name]);
4318
+ var sortedFolders = useMemo(function () {
4319
+ return _toConsumableArray(menuItems || []).filter(function (m) {
4320
+ return m && m.id != null;
4321
+ }).sort(function (a, b) {
4322
+ return String(a.name || "").localeCompare(String(b.name || ""));
4323
+ });
4324
+ }, [menuItems]);
4325
+ function handleConfirm() {
4326
+ return _handleConfirm.apply(this, arguments);
4327
+ }
4328
+ function _handleConfirm() {
4329
+ _handleConfirm = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
4330
+ var menuId, trimmed, newId, created, _t;
4331
+ return _regeneratorRuntime.wrap(function (_context) {
4332
+ while (1) switch (_context.prev = _context.next) {
4333
+ case 0:
4334
+ setError(null);
4335
+ menuId = selectedMenuId ? selectedMenuId : null;
4336
+ if (!newFolderMode) {
4337
+ _context.next = 7;
4338
+ break;
4339
+ }
4340
+ trimmed = (newFolderName || "").trim();
4341
+ if (trimmed) {
4342
+ _context.next = 1;
4343
+ break;
4344
+ }
4345
+ setError("New folder name is required.");
4346
+ return _context.abrupt("return");
4347
+ case 1:
4348
+ if (!(typeof onCreateFolder !== "function")) {
4349
+ _context.next = 2;
4350
+ break;
4351
+ }
4352
+ setError("Folder creation is unavailable.");
4353
+ return _context.abrupt("return");
4354
+ case 2:
4355
+ _context.prev = 2;
4356
+ setCreating(true);
4357
+ newId = Date.now();
4358
+ _context.next = 3;
4359
+ return onCreateFolder({
4360
+ id: newId,
4361
+ name: trimmed,
4362
+ icon: "folder"
4363
+ });
4364
+ case 3:
4365
+ created = _context.sent;
4366
+ if (!(created !== null && created !== void 0 && created.error || (created === null || created === void 0 ? void 0 : created.success) === false)) {
4367
+ _context.next = 4;
4368
+ break;
4369
+ }
4370
+ setError((created === null || created === void 0 ? void 0 : created.message) || "Could not create folder.");
4371
+ return _context.abrupt("return");
4372
+ case 4:
4373
+ menuId = newId;
4374
+ _context.next = 6;
4375
+ break;
4376
+ case 5:
4377
+ _context.prev = 5;
4378
+ _t = _context["catch"](2);
4379
+ setError((_t === null || _t === void 0 ? void 0 : _t.message) || "Could not create folder.");
4380
+ return _context.abrupt("return");
4381
+ case 6:
4382
+ _context.prev = 6;
4383
+ setCreating(false);
4384
+ return _context.finish(6);
4385
+ case 7:
4386
+ onConfirm({
4387
+ name: (name || "").trim() || defaultName,
4388
+ menuId: menuId
4389
+ });
4390
+ case 8:
4391
+ case "end":
4392
+ return _context.stop();
4393
+ }
4394
+ }, _callee, null, [[2, 5, 6, 7]]);
4395
+ }));
4396
+ return _handleConfirm.apply(this, arguments);
4397
+ }
4398
+ if (!isOpen) return null;
4399
+ return /*#__PURE__*/jsx(Modal, {
4400
+ isOpen: isOpen,
4401
+ setIsOpen: setIsOpen,
4402
+ width: "w-full max-w-md",
4403
+ height: "h-auto",
4404
+ children: /*#__PURE__*/jsxs("div", {
4405
+ className: "flex flex-col rounded-lg overflow-hidden border ".concat(panelStyles.backgroundColor || "", " ").concat(panelStyles.borderColor || "", " ").concat(panelStyles.textColor || ""),
4406
+ children: [/*#__PURE__*/jsxs("div", {
4407
+ className: "flex flex-row items-center justify-between p-4 border-b border-white/10",
4408
+ children: [/*#__PURE__*/jsxs("div", {
4409
+ className: "flex items-center gap-3",
4410
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
4411
+ icon: "download",
4412
+ className: "h-4 w-4 opacity-70"
4413
+ }), /*#__PURE__*/jsx("span", {
4414
+ className: "text-lg font-semibold",
4415
+ children: "Install dashboard"
4416
+ })]
4417
+ }), /*#__PURE__*/jsx("button", {
4418
+ type: "button",
4419
+ onClick: function onClick() {
4420
+ return setIsOpen(false);
4421
+ },
4422
+ className: "opacity-50 hover:opacity-100 transition-opacity cursor-pointer",
4423
+ "aria-label": "Close",
4424
+ children: /*#__PURE__*/jsx(FontAwesomeIcon, {
4425
+ icon: "xmark",
4426
+ className: "h-5 w-5"
4427
+ })
4428
+ })]
4429
+ }), /*#__PURE__*/jsxs("div", {
4430
+ className: "flex flex-col gap-4 p-4",
4431
+ children: [/*#__PURE__*/jsxs("div", {
4432
+ className: "flex flex-col gap-1",
4433
+ children: [/*#__PURE__*/jsx("label", {
4434
+ className: "text-sm font-medium",
4435
+ children: "Name"
4436
+ }), /*#__PURE__*/jsx(InputText, {
4437
+ value: name,
4438
+ onChange: function onChange(v) {
4439
+ return setName(v);
4440
+ },
4441
+ placeholder: defaultName
4442
+ }), /*#__PURE__*/jsx("span", {
4443
+ className: "text-[10px] opacity-50",
4444
+ children: "The local display name only. Doesn't change the published scope or package id."
4445
+ })]
4446
+ }), /*#__PURE__*/jsxs("div", {
4447
+ className: "flex flex-col gap-1",
4448
+ children: [/*#__PURE__*/jsx("label", {
4449
+ className: "text-sm font-medium",
4450
+ children: "Folder"
4451
+ }), !newFolderMode ? /*#__PURE__*/jsxs("div", {
4452
+ className: "flex flex-row gap-2 items-center",
4453
+ children: [/*#__PURE__*/jsxs("select", {
4454
+ value: selectedMenuId,
4455
+ onChange: function onChange(e) {
4456
+ return setSelectedMenuId(e.target.value);
4457
+ },
4458
+ className: "flex-1 px-3 py-2 bg-gray-900 border border-white/10 rounded text-sm text-gray-200",
4459
+ children: [sortedFolders.length === 0 && /*#__PURE__*/jsx("option", {
4460
+ value: "",
4461
+ children: "\u2014 No folders yet \u2014"
4462
+ }), sortedFolders.map(function (m) {
4463
+ return /*#__PURE__*/jsx("option", {
4464
+ value: String(m.id),
4465
+ children: m.name
4466
+ }, m.id);
4467
+ })]
4468
+ }), /*#__PURE__*/jsx("button", {
4469
+ type: "button",
4470
+ onClick: function onClick() {
4471
+ return setNewFolderMode(true);
4472
+ },
4473
+ className: "px-3 py-2 text-xs bg-indigo-600 hover:bg-indigo-500 text-white rounded transition-colors",
4474
+ children: "+ New"
4475
+ })]
4476
+ }) : /*#__PURE__*/jsxs("div", {
4477
+ className: "flex flex-row gap-2 items-center",
4478
+ children: [/*#__PURE__*/jsx(InputText, {
4479
+ value: newFolderName,
4480
+ onChange: function onChange(v) {
4481
+ return setNewFolderName(v);
4482
+ },
4483
+ placeholder: "New folder name",
4484
+ autoFocus: true
4485
+ }), /*#__PURE__*/jsx("button", {
4486
+ type: "button",
4487
+ onClick: function onClick() {
4488
+ setNewFolderMode(false);
4489
+ setNewFolderName("");
4490
+ setError(null);
4491
+ },
4492
+ className: "px-3 py-2 text-xs bg-gray-700 hover:bg-gray-600 text-gray-100 rounded transition-colors",
4493
+ children: "Cancel"
4494
+ })]
4495
+ })]
4496
+ }), error && /*#__PURE__*/jsx("div", {
4497
+ className: "text-xs text-red-300 bg-red-900/30 border border-red-700/40 rounded px-3 py-2",
4498
+ children: error
4499
+ })]
4500
+ }), /*#__PURE__*/jsxs("div", {
4501
+ className: "flex flex-row justify-end gap-2 p-4 border-t border-white/10",
4502
+ children: [/*#__PURE__*/jsx(Button3, {
4503
+ title: "Cancel",
4504
+ onClick: function onClick() {
4505
+ return setIsOpen(false);
4506
+ }
4507
+ }), /*#__PURE__*/jsx(Button2, {
4508
+ title: creating ? "Creating folder…" : "Install",
4509
+ onClick: handleConfirm,
4510
+ disabled: creating || !name.trim()
4511
+ })]
4512
+ })]
4513
+ })
4514
+ });
4515
+ };
4516
+
4267
4517
  function _createForOfIteratorHelper$w(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$w(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; } } }; }
4268
4518
  function _unsupportedIterableToArray$w(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$w(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$w(r, a) : void 0; } }
4269
4519
  function _arrayLikeToArray$w(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; }
4270
- 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; }
4271
- 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; }
4520
+ 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; }
4521
+ 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; }
4272
4522
  var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
4273
4523
  var dashboardPackage = _ref.dashboardPackage,
4274
4524
  appId = _ref.appId,
@@ -4308,6 +4558,18 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
4308
4558
  setProgressComplete = _useState12[1];
4309
4559
  var progressResultRef = useRef(null);
4310
4560
  var cleanupProgressRef = useRef(null);
4561
+
4562
+ // Pre-install options modal: choose folder + rename. Lets the user
4563
+ // override the publisher's menuId (which would otherwise collide
4564
+ // with their local folder ids) and pick a friendlier display name.
4565
+ var _useState13 = useState(false),
4566
+ _useState14 = _slicedToArray(_useState13, 2),
4567
+ showOptionsModal = _useState14[0],
4568
+ setShowOptionsModal = _useState14[1];
4569
+ var _useState15 = useState([]),
4570
+ _useState16 = _slicedToArray(_useState15, 2),
4571
+ menuItems = _useState16[0],
4572
+ setMenuItems = _useState16[1];
4311
4573
  var pkg = dashboardPackage;
4312
4574
  if (!pkg) return null;
4313
4575
 
@@ -4338,12 +4600,16 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
4338
4600
  cancelled = true;
4339
4601
  };
4340
4602
  }, [pkg.name]);
4341
- function handleInstall() {
4342
- return _handleInstall.apply(this, arguments);
4343
- } // eslint-disable-next-line react-hooks/rules-of-hooks
4344
- function _handleInstall() {
4345
- _handleInstall = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
4346
- var deps, items, _window$mainApi2, _window$mainApi2$onIn, result, _result$workspace2, _t;
4603
+
4604
+ // Click handler on the "Install" button: load the user's existing
4605
+ // folders + open the options modal. The actual install fires from
4606
+ // the modal's onConfirm so we have the user's name/menuId choice.
4607
+ function handleInstallClick() {
4608
+ return _handleInstallClick.apply(this, arguments);
4609
+ }
4610
+ function _handleInstallClick() {
4611
+ _handleInstallClick = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
4612
+ var _window$mainApi2, _window$mainApi2$list, result, list;
4347
4613
  return _regeneratorRuntime.wrap(function (_context) {
4348
4614
  while (1) switch (_context.prev = _context.next) {
4349
4615
  case 0:
@@ -4352,6 +4618,107 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
4352
4618
  break;
4353
4619
  }
4354
4620
  return _context.abrupt("return");
4621
+ case 1:
4622
+ setInstallResult(null);
4623
+ _context.prev = 2;
4624
+ _context.next = 3;
4625
+ return (_window$mainApi2 = window.mainApi) === null || _window$mainApi2 === void 0 || (_window$mainApi2 = _window$mainApi2.menuItems) === null || _window$mainApi2 === void 0 || (_window$mainApi2$list = _window$mainApi2.listMenuItems) === null || _window$mainApi2$list === void 0 ? void 0 : _window$mainApi2$list.call(_window$mainApi2, appId);
4626
+ case 3:
4627
+ result = _context.sent;
4628
+ list = ((result === null || result === void 0 ? void 0 : result.menuItems) || []).filter(function (m) {
4629
+ return m && m.id != null;
4630
+ });
4631
+ setMenuItems(list);
4632
+ _context.next = 5;
4633
+ break;
4634
+ case 4:
4635
+ _context.prev = 4;
4636
+ _context["catch"](2);
4637
+ setMenuItems([]);
4638
+ case 5:
4639
+ setShowOptionsModal(true);
4640
+ case 6:
4641
+ case "end":
4642
+ return _context.stop();
4643
+ }
4644
+ }, _callee, null, [[2, 4]]);
4645
+ }));
4646
+ return _handleInstallClick.apply(this, arguments);
4647
+ }
4648
+ function handleCreateFolder(_x) {
4649
+ return _handleCreateFolder.apply(this, arguments);
4650
+ }
4651
+ function _handleCreateFolder() {
4652
+ _handleCreateFolder = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(menuItem) {
4653
+ var _window$mainApi3, _window$mainApi3$save;
4654
+ return _regeneratorRuntime.wrap(function (_context2) {
4655
+ while (1) switch (_context2.prev = _context2.next) {
4656
+ case 0:
4657
+ if (appId) {
4658
+ _context2.next = 1;
4659
+ break;
4660
+ }
4661
+ return _context2.abrupt("return", {
4662
+ success: false,
4663
+ message: "No appId"
4664
+ });
4665
+ case 1:
4666
+ return _context2.abrupt("return", (_window$mainApi3 = window.mainApi) === null || _window$mainApi3 === void 0 || (_window$mainApi3 = _window$mainApi3.menuItems) === null || _window$mainApi3 === void 0 || (_window$mainApi3$save = _window$mainApi3.saveMenuItem) === null || _window$mainApi3$save === void 0 ? void 0 : _window$mainApi3$save.call(_window$mainApi3, appId, menuItem));
4667
+ case 2:
4668
+ case "end":
4669
+ return _context2.stop();
4670
+ }
4671
+ }, _callee2);
4672
+ }));
4673
+ return _handleCreateFolder.apply(this, arguments);
4674
+ }
4675
+ function handleOptionsConfirm(_x2) {
4676
+ return _handleOptionsConfirm.apply(this, arguments);
4677
+ }
4678
+ function _handleOptionsConfirm() {
4679
+ _handleOptionsConfirm = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(_ref2) {
4680
+ var name, menuId;
4681
+ return _regeneratorRuntime.wrap(function (_context3) {
4682
+ while (1) switch (_context3.prev = _context3.next) {
4683
+ case 0:
4684
+ name = _ref2.name, menuId = _ref2.menuId;
4685
+ setShowOptionsModal(false);
4686
+ _context3.next = 1;
4687
+ return runInstall({
4688
+ name: name,
4689
+ menuId: menuId
4690
+ });
4691
+ case 1:
4692
+ case "end":
4693
+ return _context3.stop();
4694
+ }
4695
+ }, _callee3);
4696
+ }));
4697
+ return _handleOptionsConfirm.apply(this, arguments);
4698
+ }
4699
+ function runInstall() {
4700
+ return _runInstall.apply(this, arguments);
4701
+ } // eslint-disable-next-line react-hooks/rules-of-hooks
4702
+ function _runInstall() {
4703
+ _runInstall = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
4704
+ var installOptions,
4705
+ deps,
4706
+ items,
4707
+ _window$mainApi4,
4708
+ _window$mainApi4$onIn,
4709
+ result,
4710
+ _result$workspace2,
4711
+ _args4 = arguments,
4712
+ _t2;
4713
+ return _regeneratorRuntime.wrap(function (_context4) {
4714
+ while (1) switch (_context4.prev = _context4.next) {
4715
+ case 0:
4716
+ installOptions = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {};
4717
+ if (!(!appId || !pkg.name)) {
4718
+ _context4.next = 1;
4719
+ break;
4720
+ }
4721
+ return _context4.abrupt("return");
4355
4722
  case 1:
4356
4723
  setIsInstalling(true);
4357
4724
  setInstallResult(null);
@@ -4380,11 +4747,11 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
4380
4747
 
4381
4748
  // Register progress listener
4382
4749
  if (cleanupProgressRef.current) cleanupProgressRef.current();
4383
- 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) {
4750
+ cleanupProgressRef.current = (_window$mainApi4 = window.mainApi) === null || _window$mainApi4 === void 0 || (_window$mainApi4 = _window$mainApi4.dashboardConfig) === null || _window$mainApi4 === void 0 || (_window$mainApi4$onIn = _window$mainApi4.onInstallProgress) === null || _window$mainApi4$onIn === void 0 ? void 0 : _window$mainApi4$onIn.call(_window$mainApi4, function (data) {
4384
4751
  setProgressWidgets(function (prev) {
4385
4752
  var next = _toConsumableArray(prev);
4386
4753
  if (data.index >= 0 && data.index < next.length) {
4387
- next[data.index] = _objectSpread$X(_objectSpread$X({}, next[data.index]), {}, {
4754
+ next[data.index] = _objectSpread$V(_objectSpread$V({}, next[data.index]), {}, {
4388
4755
  status: data.status,
4389
4756
  error: data.error || null
4390
4757
  });
@@ -4393,13 +4760,13 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
4393
4760
  });
4394
4761
  });
4395
4762
  }
4396
- _context.prev = 2;
4397
- _context.next = 3;
4398
- return window.mainApi.dashboardConfig.installDashboardFromRegistry(appId, pkg.name);
4763
+ _context4.prev = 2;
4764
+ _context4.next = 3;
4765
+ return window.mainApi.dashboardConfig.installDashboardFromRegistry(appId, pkg.name, installOptions);
4399
4766
  case 3:
4400
- result = _context.sent;
4767
+ result = _context4.sent;
4401
4768
  if (!(result !== null && result !== void 0 && result.authRequired)) {
4402
- _context.next = 4;
4769
+ _context4.next = 4;
4403
4770
  break;
4404
4771
  }
4405
4772
  // Auth needed — close progress modal, show inline auth prompt
@@ -4413,7 +4780,7 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
4413
4780
  cleanupProgressRef.current();
4414
4781
  cleanupProgressRef.current = null;
4415
4782
  }
4416
- return _context.abrupt("return");
4783
+ return _context4.abrupt("return");
4417
4784
  case 4:
4418
4785
  // Store result for use when modal closes
4419
4786
  progressResultRef.current = result;
@@ -4429,33 +4796,33 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
4429
4796
  onInstallComplete(result);
4430
4797
  }
4431
4798
  }
4432
- _context.next = 6;
4799
+ _context4.next = 6;
4433
4800
  break;
4434
4801
  case 5:
4435
- _context.prev = 5;
4436
- _t = _context["catch"](2);
4802
+ _context4.prev = 5;
4803
+ _t2 = _context4["catch"](2);
4437
4804
  setProgressComplete(true);
4438
4805
  if (items.length === 0) {
4439
4806
  setInstallResult({
4440
4807
  status: "error",
4441
- message: _t.message || "Failed to install dashboard."
4808
+ message: _t2.message || "Failed to install dashboard."
4442
4809
  });
4443
4810
  }
4444
4811
  case 6:
4445
- _context.prev = 6;
4812
+ _context4.prev = 6;
4446
4813
  setIsInstalling(false);
4447
4814
  if (cleanupProgressRef.current) {
4448
4815
  cleanupProgressRef.current();
4449
4816
  cleanupProgressRef.current = null;
4450
4817
  }
4451
- return _context.finish(6);
4818
+ return _context4.finish(6);
4452
4819
  case 7:
4453
4820
  case "end":
4454
- return _context.stop();
4821
+ return _context4.stop();
4455
4822
  }
4456
- }, _callee, null, [[2, 5, 6, 7]]);
4823
+ }, _callee4, null, [[2, 5, 6, 7]]);
4457
4824
  }));
4458
- return _handleInstall.apply(this, arguments);
4825
+ return _runInstall.apply(this, arguments);
4459
4826
  }
4460
4827
  var handleProgressDone = useCallback(function () {
4461
4828
  setShowProgressModal(false);
@@ -4480,7 +4847,7 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
4480
4847
  var raw = preview === null || preview === void 0 ? void 0 : preview.compatibility;
4481
4848
  if (!raw) return raw;
4482
4849
  var cMap = ComponentManager.componentMap();
4483
- var augWidgets = _objectSpread$X({}, raw.widgets);
4850
+ var augWidgets = _objectSpread$V({}, raw.widgets);
4484
4851
  var fixedCount = 0;
4485
4852
  var _loop = function _loop() {
4486
4853
  var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
@@ -4723,9 +5090,16 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
4723
5090
  hoverBackgroundColor: isInstalling ? "" : "hover:bg-blue-700",
4724
5091
  textSize: "text-sm",
4725
5092
  padding: "py-1.5 px-4",
4726
- onClick: handleInstall,
5093
+ onClick: handleInstallClick,
4727
5094
  disabled: isInstalling
4728
5095
  })
5096
+ }), /*#__PURE__*/jsx(DashboardInstallOptionsModal, {
5097
+ isOpen: showOptionsModal,
5098
+ setIsOpen: setShowOptionsModal,
5099
+ pkg: pkg,
5100
+ menuItems: menuItems,
5101
+ onCreateFolder: handleCreateFolder,
5102
+ onConfirm: handleOptionsConfirm
4729
5103
  }), /*#__PURE__*/jsx(InstallProgressModal, {
4730
5104
  isOpen: showProgressModal,
4731
5105
  setIsOpen: setShowProgressModal,
@@ -4739,7 +5113,10 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
4739
5113
  },
4740
5114
  onAuthenticated: function onAuthenticated() {
4741
5115
  setInstallResult(null);
4742
- handleInstall();
5116
+ // Re-open the options modal so the user can confirm again
5117
+ // post-auth (cheaper than caching their first selection
5118
+ // through the auth round-trip).
5119
+ handleInstallClick();
4743
5120
  },
4744
5121
  onCancel: function onCancel() {
4745
5122
  return setInstallResult(null);
@@ -5063,8 +5440,6 @@ var DiscoverDashboardsDetail = function DiscoverDashboardsDetail(_ref) {
5063
5440
  });
5064
5441
  };
5065
5442
 
5066
- 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; }
5067
- 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; }
5068
5443
  var LayoutManagerModal = function LayoutManagerModal(_ref) {
5069
5444
  var open = _ref.open,
5070
5445
  setIsOpen = _ref.setIsOpen,
@@ -5112,31 +5487,25 @@ var LayoutManagerModal = function LayoutManagerModal(_ref) {
5112
5487
  localMenuItems = _useState12[0],
5113
5488
  setLocalMenuItems = _useState12[1];
5114
5489
 
5115
- // Post-install workspace for registry stepper customization
5490
+ // Pre-import file selection (file preview, not yet saved)
5116
5491
  var _useState13 = useState(null),
5117
5492
  _useState14 = _slicedToArray(_useState13, 2),
5118
- importedWorkspace = _useState14[0],
5119
- setImportedWorkspace = _useState14[1];
5120
-
5121
- // Pre-import file selection (file preview, not yet saved)
5122
- var _useState15 = useState(null),
5123
- _useState16 = _slicedToArray(_useState15, 2),
5124
- selectedFile = _useState16[0],
5125
- setSelectedFile = _useState16[1];
5493
+ selectedFile = _useState14[0],
5494
+ setSelectedFile = _useState14[1];
5126
5495
 
5127
5496
  // Inline new-folder form state
5128
- var _useState17 = useState(false),
5497
+ var _useState15 = useState(false),
5498
+ _useState16 = _slicedToArray(_useState15, 2),
5499
+ isCreatingFolder = _useState16[0],
5500
+ setIsCreatingFolder = _useState16[1];
5501
+ var _useState17 = useState(""),
5129
5502
  _useState18 = _slicedToArray(_useState17, 2),
5130
- isCreatingFolder = _useState18[0],
5131
- setIsCreatingFolder = _useState18[1];
5132
- var _useState19 = useState(""),
5503
+ newFolderName = _useState18[0],
5504
+ setNewFolderName = _useState18[1];
5505
+ var _useState19 = useState(null),
5133
5506
  _useState20 = _slicedToArray(_useState19, 2),
5134
- newFolderName = _useState20[0],
5135
- setNewFolderName = _useState20[1];
5136
- var _useState21 = useState(null),
5137
- _useState22 = _slicedToArray(_useState21, 2),
5138
- newFolderIcon = _useState22[0],
5139
- setNewFolderIcon = _useState22[1];
5507
+ newFolderIcon = _useState20[0],
5508
+ setNewFolderIcon = _useState20[1];
5140
5509
 
5141
5510
  // Reset state when modal opens
5142
5511
  useEffect(function () {
@@ -5156,7 +5525,6 @@ var LayoutManagerModal = function LayoutManagerModal(_ref) {
5156
5525
  return (a.name || "").localeCompare(b.name || "");
5157
5526
  })[0]) === null || _Object$entries$sort$ === void 0 ? void 0 : _Object$entries$sort$[0]) || null : null;
5158
5527
  setSelectedThemeKey(appThemeKey || fallback);
5159
- setImportedWorkspace(null);
5160
5528
  setSelectedFile(null);
5161
5529
  setIsCreatingFolder(false);
5162
5530
  setNewFolderName("");
@@ -5243,22 +5611,34 @@ var LayoutManagerModal = function LayoutManagerModal(_ref) {
5243
5611
  return _handleImportFromFile.apply(this, arguments);
5244
5612
  }
5245
5613
  function handleRegistryInstallComplete(result) {
5246
- var _result$workspace, _result$workspace2, _result$workspace3;
5247
- setImportedWorkspace(result.workspace);
5248
- setDashboardName(((_result$workspace = result.workspace) === null || _result$workspace === void 0 ? void 0 : _result$workspace.name) || "");
5249
- setSelectedMenuId(((_result$workspace2 = result.workspace) === null || _result$workspace2 === void 0 ? void 0 : _result$workspace2.menuId) || (menuItems.length > 0 ? menuItems[0].id : 1));
5250
- setSelectedThemeKey(((_result$workspace3 = result.workspace) === null || _result$workspace3 === void 0 ? void 0 : _result$workspace3.themeKey) || null);
5251
- setActiveStep(0);
5252
- }
5253
- function handleImportRegistryConfirm() {
5254
- return _handleImportRegistryConfirm.apply(this, arguments);
5255
- }
5256
- function _handleImportRegistryConfirm() {
5257
- _handleImportRegistryConfirm = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
5258
- var menuId, newItem, result, updatedWorkspace;
5614
+ // The pre-install DashboardInstallOptionsModal already collected
5615
+ // the user's name + folder choice and the install IPC applied
5616
+ // them, so the workspace on disk is final. Skip the legacy
5617
+ // post-install Name/Organize/Theme stepper (it would just ask
5618
+ // for the same fields again) close out and open the new
5619
+ // dashboard.
5620
+ if (onReloadWorkspaces) onReloadWorkspaces();
5621
+ loadThemes();
5622
+ if (onOpenWorkspace && result !== null && result !== void 0 && result.workspace) {
5623
+ onOpenWorkspace(result.workspace);
5624
+ }
5625
+ handleClose();
5626
+ }
5627
+ function handleImportConfirm() {
5628
+ return _handleImportConfirm.apply(this, arguments);
5629
+ }
5630
+ function _handleImportConfirm() {
5631
+ _handleImportConfirm = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
5632
+ var menuId, newItem, result;
5259
5633
  return _regeneratorRuntime.wrap(function (_context2) {
5260
5634
  while (1) switch (_context2.prev = _context2.next) {
5261
5635
  case 0:
5636
+ if (selectedFile) {
5637
+ _context2.next = 1;
5638
+ break;
5639
+ }
5640
+ return _context2.abrupt("return");
5641
+ case 1:
5262
5642
  menuId = selectedMenuId;
5263
5643
  if (isCreatingFolder && newFolderName.trim() && newFolderIcon) {
5264
5644
  newItem = {
@@ -5271,21 +5651,15 @@ var LayoutManagerModal = function LayoutManagerModal(_ref) {
5271
5651
  onSaveMenuItem(newItem);
5272
5652
  }
5273
5653
  }
5274
-
5275
- // Import flow: file not yet saved, call importDashboardConfig with overrides
5276
- if (!(creationMethod === "import" && selectedFile)) {
5277
- _context2.next = 5;
5278
- break;
5279
- }
5280
- _context2.prev = 1;
5281
- _context2.next = 2;
5654
+ _context2.prev = 2;
5655
+ _context2.next = 3;
5282
5656
  return window.mainApi.dashboardConfig.importDashboardConfig(appId, {
5283
5657
  filePath: selectedFile.filePath,
5284
5658
  name: dashboardName.trim(),
5285
5659
  menuId: menuId,
5286
5660
  themeKey: selectedThemeKey
5287
5661
  });
5288
- case 2:
5662
+ case 3:
5289
5663
  result = _context2.sent;
5290
5664
  if (result && result.success) {
5291
5665
  onReloadWorkspaces && onReloadWorkspaces();
@@ -5295,47 +5669,18 @@ var LayoutManagerModal = function LayoutManagerModal(_ref) {
5295
5669
  }
5296
5670
  handleClose();
5297
5671
  }
5298
- _context2.next = 4;
5672
+ _context2.next = 5;
5299
5673
  break;
5300
- case 3:
5301
- _context2.prev = 3;
5302
- _context2["catch"](1);
5303
5674
  case 4:
5304
- return _context2.abrupt("return");
5675
+ _context2.prev = 4;
5676
+ _context2["catch"](2);
5305
5677
  case 5:
5306
- if (importedWorkspace) {
5307
- _context2.next = 6;
5308
- break;
5309
- }
5310
- return _context2.abrupt("return");
5311
- case 6:
5312
- updatedWorkspace = _objectSpread$W(_objectSpread$W({}, importedWorkspace), {}, {
5313
- name: dashboardName.trim(),
5314
- menuId: menuId,
5315
- themeKey: selectedThemeKey
5316
- });
5317
- _context2.prev = 7;
5318
- _context2.next = 8;
5319
- return window.mainApi.workspace.saveWorkspaceForApplication(appId, updatedWorkspace);
5320
- case 8:
5321
- onReloadWorkspaces && onReloadWorkspaces();
5322
- loadThemes();
5323
- if (onOpenWorkspace) {
5324
- onOpenWorkspace(updatedWorkspace);
5325
- }
5326
- handleClose();
5327
- _context2.next = 10;
5328
- break;
5329
- case 9:
5330
- _context2.prev = 9;
5331
- _context2["catch"](7);
5332
- case 10:
5333
5678
  case "end":
5334
5679
  return _context2.stop();
5335
5680
  }
5336
- }, _callee2, null, [[1, 3], [7, 9]]);
5681
+ }, _callee2, null, [[2, 4]]);
5337
5682
  }));
5338
- return _handleImportRegistryConfirm.apply(this, arguments);
5683
+ return _handleImportConfirm.apply(this, arguments);
5339
5684
  }
5340
5685
  var selectedFolder = localMenuItems.find(function (item) {
5341
5686
  return item.id === selectedMenuId;
@@ -5623,8 +5968,10 @@ var LayoutManagerModal = function LayoutManagerModal(_ref) {
5623
5968
  });
5624
5969
  }
5625
5970
 
5626
- // Registry browser: show until install completes
5627
- if (creationMethod === "registry" && !importedWorkspace) {
5971
+ // Registry browser: install completes inside DiscoverDashboardsDetail
5972
+ // (via the DashboardInstallOptionsModal) and the onInstallComplete
5973
+ // handler closes this modal directly — no post-install stepper.
5974
+ if (creationMethod === "registry") {
5628
5975
  return /*#__PURE__*/jsx(Panel, {
5629
5976
  backgroundColor: "bg-slate-800",
5630
5977
  padding: false,
@@ -5677,37 +6024,6 @@ var LayoutManagerModal = function LayoutManagerModal(_ref) {
5677
6024
  });
5678
6025
  }
5679
6026
 
5680
- // Registry stepper: 3 steps (Name, Folder, Theme)
5681
- if (creationMethod === "registry" && importedWorkspace) {
5682
- return /*#__PURE__*/jsx(Panel, {
5683
- backgroundColor: "bg-slate-800",
5684
- padding: false,
5685
- children: /*#__PURE__*/jsx(Panel.Body, {
5686
- scrollable: false,
5687
- className: "h-full",
5688
- children: /*#__PURE__*/jsxs(Stepper, {
5689
- activeStep: activeStep,
5690
- onStepChange: setActiveStep,
5691
- showNavigation: false,
5692
- className: "h-full p-6 pb-0",
5693
- children: [/*#__PURE__*/jsx(Stepper.Step, {
5694
- label: "Name",
5695
- description: "Name your dashboard",
5696
- children: renderNameStep()
5697
- }), /*#__PURE__*/jsx(Stepper.Step, {
5698
- label: "Organize",
5699
- description: "Choose a folder",
5700
- children: renderFolderStep()
5701
- }), /*#__PURE__*/jsx(Stepper.Step, {
5702
- label: "Choose Theme",
5703
- description: "Dashboard theme",
5704
- children: renderThemeStep()
5705
- })]
5706
- })
5707
- })
5708
- });
5709
- }
5710
-
5711
6027
  // creationMethod === "template" — existing 4-step wizard
5712
6028
  return /*#__PURE__*/jsx(Panel, {
5713
6029
  backgroundColor: "bg-slate-800",
@@ -5768,7 +6084,7 @@ var LayoutManagerModal = function LayoutManagerModal(_ref) {
5768
6084
  }
5769
6085
 
5770
6086
  // Registry browser: Cancel only (DiscoverDashboardsDetail has its own inline back button)
5771
- if (creationMethod === "registry" && !importedWorkspace) {
6087
+ if (creationMethod === "registry") {
5772
6088
  return /*#__PURE__*/jsx(Modal.Footer, {
5773
6089
  children: /*#__PURE__*/jsx("div", {
5774
6090
  className: "flex flex-row space-x-2",
@@ -5876,86 +6192,7 @@ var LayoutManagerModal = function LayoutManagerModal(_ref) {
5876
6192
  hoverTextColor: "hover:text-gray-100",
5877
6193
  hoverBackgroundColor: "hover:bg-gray-600"
5878
6194
  }), /*#__PURE__*/jsx(Button, {
5879
- onClick: handleImportRegistryConfirm,
5880
- title: "Save",
5881
- textSize: "text-base xl:text-lg",
5882
- padding: "py-2 px-4",
5883
- backgroundColor: "bg-blue-600",
5884
- textColor: "text-white",
5885
- hoverTextColor: "hover:text-white",
5886
- hoverBackgroundColor: "hover:bg-blue-500"
5887
- })]
5888
- })]
5889
- })
5890
- });
5891
- }
5892
-
5893
- // Registry stepper footer: 3 steps (Name, Organize, Theme)
5894
- if (creationMethod === "registry" && importedWorkspace) {
5895
- return /*#__PURE__*/jsx(Modal.Footer, {
5896
- children: /*#__PURE__*/jsxs("div", {
5897
- className: "flex flex-row space-x-2",
5898
- children: [activeStep === 0 && /*#__PURE__*/jsxs(Fragment, {
5899
- children: [/*#__PURE__*/jsx(Button, {
5900
- onClick: handleClose,
5901
- title: "Cancel",
5902
- textSize: "text-base xl:text-lg",
5903
- padding: "py-2 px-4",
5904
- backgroundColor: "bg-gray-700",
5905
- textColor: "text-gray-300",
5906
- hoverTextColor: "hover:text-gray-100",
5907
- hoverBackgroundColor: "hover:bg-gray-600"
5908
- }), /*#__PURE__*/jsx(Button, {
5909
- onClick: function onClick() {
5910
- return setActiveStep(1);
5911
- },
5912
- title: "Next",
5913
- textSize: "text-base xl:text-lg",
5914
- padding: "py-2 px-4",
5915
- backgroundColor: "bg-blue-600",
5916
- textColor: "text-white",
5917
- hoverTextColor: "hover:text-white",
5918
- hoverBackgroundColor: "hover:bg-blue-500",
5919
- disabled: !dashboardName.trim()
5920
- })]
5921
- }), activeStep === 1 && /*#__PURE__*/jsxs(Fragment, {
5922
- children: [/*#__PURE__*/jsx(Button, {
5923
- onClick: function onClick() {
5924
- return setActiveStep(0);
5925
- },
5926
- title: "Back",
5927
- textSize: "text-base xl:text-lg",
5928
- padding: "py-2 px-4",
5929
- backgroundColor: "bg-gray-700",
5930
- textColor: "text-gray-300",
5931
- hoverTextColor: "hover:text-gray-100",
5932
- hoverBackgroundColor: "hover:bg-gray-600"
5933
- }), /*#__PURE__*/jsx(Button, {
5934
- onClick: function onClick() {
5935
- return setActiveStep(2);
5936
- },
5937
- title: "Next",
5938
- textSize: "text-base xl:text-lg",
5939
- padding: "py-2 px-4",
5940
- backgroundColor: "bg-blue-600",
5941
- textColor: "text-white",
5942
- hoverTextColor: "hover:text-white",
5943
- hoverBackgroundColor: "hover:bg-blue-500"
5944
- })]
5945
- }), activeStep === 2 && /*#__PURE__*/jsxs(Fragment, {
5946
- children: [/*#__PURE__*/jsx(Button, {
5947
- onClick: function onClick() {
5948
- return setActiveStep(1);
5949
- },
5950
- title: "Back",
5951
- textSize: "text-base xl:text-lg",
5952
- padding: "py-2 px-4",
5953
- backgroundColor: "bg-gray-700",
5954
- textColor: "text-gray-300",
5955
- hoverTextColor: "hover:text-gray-100",
5956
- hoverBackgroundColor: "hover:bg-gray-600"
5957
- }), /*#__PURE__*/jsx(Button, {
5958
- onClick: handleImportRegistryConfirm,
6195
+ onClick: handleImportConfirm,
5959
6196
  title: "Save",
5960
6197
  textSize: "text-base xl:text-lg",
5961
6198
  padding: "py-2 px-4",
@@ -7067,8 +7304,6 @@ function applyFilters(items, filters, mode) {
7067
7304
  function _createForOfIteratorHelper$u(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$u(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; } } }; }
7068
7305
  function _unsupportedIterableToArray$u(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$u(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$u(r, a) : void 0; } }
7069
7306
  function _arrayLikeToArray$u(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; }
7070
- 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; }
7071
- 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; }
7072
7307
  var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
7073
7308
  var _state$selectedDashbo, _state$selectedDashbo2;
7074
7309
  var state = _ref.state,
@@ -7188,7 +7423,7 @@ var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
7188
7423
 
7189
7424
  // --- Create logic (DASH-191: moved above useEffect so ref captures actual function) ---
7190
7425
  var handleCreate = useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
7191
- var _state$customization, name, menuId, theme, result, _window$mainApi, installResult, updatedWorkspace, _window$mainApi2, _window$mainApi3, template, installedList, installedNames, _iterator, _step, widget, scopedId, resolvedUrl, layoutObj, widgetOrder, cells, widgetItems, nextId, _loop, i, fullLayout, workspace, _t, _t2, _t3;
7426
+ var _state$customization, name, menuId, theme, result, _window$mainApi, installResult, _window$mainApi2, _window$mainApi3, template, installedList, installedNames, _iterator, _step, widget, scopedId, resolvedUrl, layoutObj, widgetOrder, cells, widgetItems, nextId, _loop, i, fullLayout, workspace, _t, _t2, _t3;
7192
7427
  return _regeneratorRuntime.wrap(function (_context2) {
7193
7428
  while (1) switch (_context2.prev = _context2.next) {
7194
7429
  case 0:
@@ -7198,7 +7433,7 @@ var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
7198
7433
  _context2.prev = 1;
7199
7434
  _state$customization = state.customization, name = _state$customization.name, menuId = _state$customization.menuId, theme = _state$customization.theme;
7200
7435
  if (!(isPrebuilt && state.selectedDashboard)) {
7201
- _context2.next = 9;
7436
+ _context2.next = 8;
7202
7437
  break;
7203
7438
  }
7204
7439
  if (!onInstallDashboard) {
@@ -7215,15 +7450,19 @@ var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
7215
7450
  });
7216
7451
  case 2:
7217
7452
  result = _context2.sent;
7218
- _context2.next = 8;
7453
+ _context2.next = 7;
7219
7454
  break;
7220
7455
  case 3:
7221
7456
  if (!((_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && (_window$mainApi = _window$mainApi.dashboardConfig) !== null && _window$mainApi !== void 0 && _window$mainApi.installDashboardFromRegistry)) {
7222
- _context2.next = 8;
7457
+ _context2.next = 7;
7223
7458
  break;
7224
7459
  }
7225
7460
  _context2.next = 4;
7226
- return window.mainApi.dashboardConfig.installDashboardFromRegistry(appId, state.selectedDashboard.name || state.selectedDashboard.key);
7461
+ return window.mainApi.dashboardConfig.installDashboardFromRegistry(appId, state.selectedDashboard.name || state.selectedDashboard.key, {
7462
+ name: name.trim(),
7463
+ menuId: menuId || 1,
7464
+ themeKey: theme
7465
+ });
7227
7466
  case 4:
7228
7467
  installResult = _context2.sent;
7229
7468
  if (!(installResult !== null && installResult !== void 0 && installResult.authRequired)) {
@@ -7235,103 +7474,95 @@ var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
7235
7474
  return _context2.abrupt("return");
7236
7475
  case 5:
7237
7476
  if (!(installResult !== null && installResult !== void 0 && installResult.workspace)) {
7238
- _context2.next = 7;
7477
+ _context2.next = 6;
7239
7478
  break;
7240
7479
  }
7241
- updatedWorkspace = _objectSpread$V(_objectSpread$V({}, installResult.workspace), {}, {
7242
- name: name.trim(),
7243
- menuId: menuId || 1,
7244
- themeKey: theme
7245
- });
7246
- _context2.next = 6;
7247
- return window.mainApi.workspace.saveWorkspaceForApplication(appId, updatedWorkspace);
7248
- case 6:
7249
7480
  result = {
7250
7481
  success: true,
7251
- workspace: updatedWorkspace
7482
+ workspace: installResult.workspace
7252
7483
  };
7253
- _context2.next = 8;
7484
+ _context2.next = 7;
7254
7485
  break;
7255
- case 7:
7486
+ case 6:
7256
7487
  if (!(installResult !== null && installResult !== void 0 && installResult.error)) {
7257
- _context2.next = 8;
7488
+ _context2.next = 7;
7258
7489
  break;
7259
7490
  }
7260
7491
  throw new Error(installResult.error);
7261
- case 8:
7262
- _context2.next = 27;
7492
+ case 7:
7493
+ _context2.next = 26;
7263
7494
  break;
7264
- case 9:
7495
+ case 8:
7265
7496
  // Build-your-own path: create layout from template + place widgets
7266
7497
  template = layoutTemplates.find(function (t) {
7267
7498
  return t.id === state.layout.templateKey;
7268
7499
  });
7269
7500
  if (template) {
7270
- _context2.next = 10;
7501
+ _context2.next = 9;
7271
7502
  break;
7272
7503
  }
7273
7504
  throw new Error("No layout template selected.");
7274
- case 10:
7505
+ case 9:
7275
7506
  if (!((_window$mainApi2 = window.mainApi) !== null && _window$mainApi2 !== void 0 && _window$mainApi2.widgets)) {
7276
- _context2.next = 20;
7507
+ _context2.next = 19;
7277
7508
  break;
7278
7509
  }
7279
- _context2.next = 11;
7510
+ _context2.next = 10;
7280
7511
  return window.mainApi.widgets.list();
7281
- case 11:
7512
+ case 10:
7282
7513
  _t = _context2.sent;
7283
7514
  if (_t) {
7284
- _context2.next = 12;
7515
+ _context2.next = 11;
7285
7516
  break;
7286
7517
  }
7287
7518
  _t = [];
7288
- case 12:
7519
+ case 11:
7289
7520
  installedList = _t;
7290
7521
  installedNames = new Set(installedList.map(function (w) {
7291
7522
  return w.name;
7292
7523
  }));
7293
7524
  _iterator = _createForOfIteratorHelper$u(state.selectedWidgets);
7294
- _context2.prev = 13;
7525
+ _context2.prev = 12;
7295
7526
  _iterator.s();
7296
- case 14:
7527
+ case 13:
7297
7528
  if ((_step = _iterator.n()).done) {
7298
- _context2.next = 17;
7529
+ _context2.next = 16;
7299
7530
  break;
7300
7531
  }
7301
7532
  widget = _step.value;
7302
7533
  if (widget.isRegistry) {
7303
- _context2.next = 15;
7534
+ _context2.next = 14;
7304
7535
  break;
7305
7536
  }
7306
- return _context2.abrupt("continue", 16);
7307
- case 15:
7537
+ return _context2.abrupt("continue", 15);
7538
+ case 14:
7308
7539
  scopedId = widget.packageScope ? "@".concat(widget.packageScope.replace(/^@/, ""), "/").concat(widget.packageName) : widget.packageName;
7309
7540
  if (!(!installedNames.has(scopedId) && !installedNames.has(widget.packageName))) {
7310
- _context2.next = 16;
7541
+ _context2.next = 15;
7311
7542
  break;
7312
7543
  }
7313
7544
  resolvedUrl = (widget.downloadUrl || "").replace(/\{version\}/g, widget.packageVersion || "").replace(/\{name\}/g, widget.packageName || "");
7314
7545
  if (!resolvedUrl) {
7315
- _context2.next = 16;
7546
+ _context2.next = 15;
7316
7547
  break;
7317
7548
  }
7318
- _context2.next = 16;
7549
+ _context2.next = 15;
7319
7550
  return window.mainApi.widgets.install(scopedId, resolvedUrl);
7551
+ case 15:
7552
+ _context2.next = 13;
7553
+ break;
7320
7554
  case 16:
7321
- _context2.next = 14;
7555
+ _context2.next = 18;
7322
7556
  break;
7323
7557
  case 17:
7324
- _context2.next = 19;
7325
- break;
7558
+ _context2.prev = 17;
7559
+ _t2 = _context2["catch"](12);
7560
+ _iterator.e(_t2);
7326
7561
  case 18:
7327
7562
  _context2.prev = 18;
7328
- _t2 = _context2["catch"](13);
7329
- _iterator.e(_t2);
7330
- case 19:
7331
- _context2.prev = 19;
7332
7563
  _iterator.f();
7333
- return _context2.finish(19);
7334
- case 20:
7564
+ return _context2.finish(18);
7565
+ case 19:
7335
7566
  layoutObj = createLayoutFromTemplate(template, menuId || 1); // Place widgets into grid cells as proper layout items
7336
7567
  widgetOrder = state.layout.widgetOrder || [];
7337
7568
  cells = template.cells.filter(function (c) {
@@ -7368,31 +7599,31 @@ var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
7368
7599
  }, _loop);
7369
7600
  });
7370
7601
  i = 0;
7371
- case 21:
7602
+ case 20:
7372
7603
  if (!(i < widgetOrder.length && i < cells.length)) {
7373
- _context2.next = 23;
7604
+ _context2.next = 22;
7374
7605
  break;
7375
7606
  }
7376
- return _context2.delegateYield(_loop(i), "t0", 22);
7377
- case 22:
7607
+ return _context2.delegateYield(_loop(i), "t0", 21);
7608
+ case 21:
7378
7609
  i++;
7379
- _context2.next = 21;
7610
+ _context2.next = 20;
7380
7611
  break;
7381
- case 23:
7612
+ case 22:
7382
7613
  fullLayout = [layoutObj].concat(widgetItems);
7383
7614
  if (!onCreateWorkspace) {
7384
- _context2.next = 25;
7615
+ _context2.next = 24;
7385
7616
  break;
7386
7617
  }
7387
- _context2.next = 24;
7618
+ _context2.next = 23;
7388
7619
  return onCreateWorkspace(fullLayout, theme, name.trim());
7389
- case 24:
7620
+ case 23:
7390
7621
  result = _context2.sent;
7391
- _context2.next = 27;
7622
+ _context2.next = 26;
7392
7623
  break;
7393
- case 25:
7624
+ case 24:
7394
7625
  if (!((_window$mainApi3 = window.mainApi) !== null && _window$mainApi3 !== void 0 && (_window$mainApi3 = _window$mainApi3.workspace) !== null && _window$mainApi3 !== void 0 && _window$mainApi3.saveWorkspaceForApplication)) {
7395
- _context2.next = 27;
7626
+ _context2.next = 26;
7396
7627
  break;
7397
7628
  }
7398
7629
  workspace = {
@@ -7401,43 +7632,48 @@ var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
7401
7632
  themeKey: theme,
7402
7633
  layout: fullLayout
7403
7634
  };
7404
- _context2.next = 26;
7635
+ _context2.next = 25;
7405
7636
  return window.mainApi.workspace.saveWorkspaceForApplication(appId, workspace);
7406
- case 26:
7637
+ case 25:
7407
7638
  result = {
7408
7639
  success: true,
7409
7640
  workspace: workspace
7410
7641
  };
7411
- case 27:
7642
+ case 26:
7412
7643
  if (result) {
7413
7644
  setCreatedDashboard(result.workspace || result);
7414
7645
  }
7415
- _context2.next = 29;
7646
+ _context2.next = 28;
7416
7647
  break;
7417
- case 28:
7418
- _context2.prev = 28;
7648
+ case 27:
7649
+ _context2.prev = 27;
7419
7650
  _t3 = _context2["catch"](1);
7420
7651
  setError(_t3.message || "Failed to create dashboard.");
7421
- case 29:
7422
- _context2.prev = 29;
7652
+ case 28:
7653
+ _context2.prev = 28;
7423
7654
  setCreating(false);
7424
- return _context2.finish(29);
7425
- case 30:
7655
+ return _context2.finish(28);
7656
+ case 29:
7426
7657
  case "end":
7427
7658
  return _context2.stop();
7428
7659
  }
7429
- }, _callee, null, [[1, 28, 29, 30], [13, 18, 19, 20]]);
7660
+ }, _callee, null, [[1, 27, 28, 29], [12, 17, 18, 19]]);
7430
7661
  })), [state, isPrebuilt, onInstallDashboard, onCreateWorkspace, appId]);
7431
7662
 
7432
- // Expose handleCreate and creating state to parent via ref (DASH-183)
7663
+ // Expose handleCreate, creating, and createdDashboard state to parent
7664
+ // via ref (DASH-183). The parent uses `createdDashboard` to swap the
7665
+ // footer "Create Dashboard" button out once the success state is
7666
+ // rendered — otherwise the user could accidentally re-fire the
7667
+ // install.
7433
7668
  useEffect(function () {
7434
7669
  if (createHandlerRef) {
7435
7670
  createHandlerRef.current = {
7436
7671
  handleCreate: handleCreate,
7437
- creating: creating
7672
+ creating: creating,
7673
+ createdDashboard: createdDashboard
7438
7674
  };
7439
7675
  }
7440
- }, [createHandlerRef, handleCreate, creating]);
7676
+ }, [createHandlerRef, handleCreate, creating, createdDashboard]);
7441
7677
  var handleNameChange = useCallback(function (val) {
7442
7678
  dispatch({
7443
7679
  type: "SET_CUSTOMIZATION",
@@ -8202,7 +8438,7 @@ var STEP_LABELS = [{
8202
8438
  * Resets wizard state cleanly on close.
8203
8439
  */
8204
8440
  var DashboardWizardModal = function DashboardWizardModal(_ref) {
8205
- var _createHandlerRef$cur, _createHandlerRef$cur2;
8441
+ var _createHandlerRef$cur, _createHandlerRef$cur2, _createHandlerRef$cur3;
8206
8442
  var open = _ref.open,
8207
8443
  setIsOpen = _ref.setIsOpen,
8208
8444
  _ref$menuItems = _ref.menuItems,
@@ -8249,6 +8485,7 @@ var DashboardWizardModal = function DashboardWizardModal(_ref) {
8249
8485
  }, [canProceed, nextStep]);
8250
8486
  var isLastStep = state.step === 1;
8251
8487
  var isCreating = (_createHandlerRef$cur = (_createHandlerRef$cur2 = createHandlerRef.current) === null || _createHandlerRef$cur2 === void 0 ? void 0 : _createHandlerRef$cur2.creating) !== null && _createHandlerRef$cur !== void 0 ? _createHandlerRef$cur : false;
8488
+ var isCreated = !!((_createHandlerRef$cur3 = createHandlerRef.current) !== null && _createHandlerRef$cur3 !== void 0 && _createHandlerRef$cur3.createdDashboard);
8252
8489
  var canCreate = canProceed && !isCreating;
8253
8490
  return /*#__PURE__*/jsx(Modal, {
8254
8491
  isOpen: open,
@@ -8318,7 +8555,7 @@ var DashboardWizardModal = function DashboardWizardModal(_ref) {
8318
8555
  })
8319
8556
  })
8320
8557
  })]
8321
- }), /*#__PURE__*/jsxs("div", {
8558
+ }), !isCreated && /*#__PURE__*/jsxs("div", {
8322
8559
  className: "flex flex-row justify-between items-center pt-4 mt-4 border-t border-gray-700/50",
8323
8560
  children: [/*#__PURE__*/jsx(Button, {
8324
8561
  onClick: state.step === 0 ? handleClose : prevStep,
@@ -8334,8 +8571,8 @@ var DashboardWizardModal = function DashboardWizardModal(_ref) {
8334
8571
  children: ["Step ", state.step + 1, " of ", STEP_LABELS.length]
8335
8572
  }), isLastStep ? /*#__PURE__*/jsx(Button, {
8336
8573
  onClick: function onClick() {
8337
- var _createHandlerRef$cur3, _createHandlerRef$cur4;
8338
- return (_createHandlerRef$cur3 = createHandlerRef.current) === null || _createHandlerRef$cur3 === void 0 || (_createHandlerRef$cur4 = _createHandlerRef$cur3.handleCreate) === null || _createHandlerRef$cur4 === void 0 ? void 0 : _createHandlerRef$cur4.call(_createHandlerRef$cur3);
8574
+ var _createHandlerRef$cur4, _createHandlerRef$cur5;
8575
+ return (_createHandlerRef$cur4 = createHandlerRef.current) === null || _createHandlerRef$cur4 === void 0 || (_createHandlerRef$cur5 = _createHandlerRef$cur4.handleCreate) === null || _createHandlerRef$cur5 === void 0 ? void 0 : _createHandlerRef$cur5.call(_createHandlerRef$cur4);
8339
8576
  },
8340
8577
  title: isCreating ? "Creating..." : "Create Dashboard",
8341
8578
  textSize: "text-sm",