@trops/dash-core 0.1.462 → 0.1.463

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
@@ -7500,11 +7500,12 @@ var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
7500
7500
  };
7501
7501
  }, []);
7502
7502
 
7503
- // Sub-step state (DASH-188): 0 = Name, 1 = Folder, 2 = Theme
7504
- var _useState21 = useState(0),
7505
- _useState22 = _slicedToArray(_useState21, 2),
7506
- subStep = _useState22[0],
7507
- setSubStep = _useState22[1];
7503
+ // Cycle 2: the inner pages were promoted to top-level wizard steps
7504
+ // (state.step 1=Name, 2=Folder, 3=Theme, 4=Review). The internal
7505
+ // mini-stepper from DASH-188 is gone — the modal footer's
7506
+ // Next/Back drives advancement now, and the wizard's per-step
7507
+ // canProceed gates each transition.
7508
+
7508
7509
  var isPrebuilt = state.path === "prebuilt";
7509
7510
 
7510
7511
  // Initialize customization defaults when stepping into this step
@@ -7809,7 +7810,6 @@ var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
7809
7810
  setIsCreatingFolder(false);
7810
7811
  setNewFolderName("");
7811
7812
  setNewFolderIcon(null);
7812
- setSubStep(2); // Auto-advance to Theme
7813
7813
  }, [dispatch]);
7814
7814
  var handleThemeSelect = useCallback(function (key) {
7815
7815
  dispatch({
@@ -7975,16 +7975,6 @@ var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
7975
7975
  return item.id === state.customization.menuId;
7976
7976
  });
7977
7977
  var selectedTheme = themes && state.customization.theme ? themes[state.customization.theme] : null;
7978
- var SUB_STEPS = [{
7979
- label: "Name",
7980
- icon: "input-text"
7981
- }, {
7982
- label: "Folder",
7983
- icon: "folder"
7984
- }, {
7985
- label: "Theme",
7986
- icon: "palette"
7987
- }];
7988
7978
  return /*#__PURE__*/jsxs("div", {
7989
7979
  className: "flex flex-col gap-4",
7990
7980
  children: [/*#__PURE__*/jsx("h3", {
@@ -8038,28 +8028,18 @@ var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
8038
8028
  children: isPrebuilt ? ((_state$selectedDashbo = state.selectedDashboard) === null || _state$selectedDashbo === void 0 ? void 0 : _state$selectedDashbo.displayName) || ((_state$selectedDashbo2 = state.selectedDashboard) === null || _state$selectedDashbo2 === void 0 ? void 0 : _state$selectedDashbo2.name) || "Pre-built dashboard" : "".concat(state.selectedWidgets.length, " widget").concat(state.selectedWidgets.length !== 1 ? "s" : "")
8039
8029
  })]
8040
8030
  })]
8041
- }), /*#__PURE__*/jsx("div", {
8042
- className: "flex items-center gap-2 mb-2",
8043
- children: SUB_STEPS.map(function (s, i) {
8044
- return /*#__PURE__*/jsxs(React__default.Fragment, {
8045
- children: [i > 0 && /*#__PURE__*/jsx("div", {
8046
- className: "flex-1 h-px ".concat(i <= subStep ? "bg-blue-500" : "bg-gray-700")
8047
- }), /*#__PURE__*/jsxs("button", {
8048
- type: "button",
8049
- className: "flex items-center gap-1.5 px-3 py-1.5 rounded-full text-xs font-medium transition-colors ".concat(i === subStep ? "bg-blue-600 text-white" : i < subStep ? "bg-blue-900/50 text-blue-300 cursor-pointer" : "bg-gray-800 text-gray-500"),
8050
- onClick: function onClick() {
8051
- return setSubStep(i);
8052
- },
8053
- children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
8054
- icon: s.icon,
8055
- fixedWidth: true
8056
- }), s.label]
8057
- })]
8058
- }, s.label);
8059
- })
8031
+ }), error && /*#__PURE__*/jsxs("div", {
8032
+ className: "rounded-lg border border-red-500 bg-red-900 p-3 flex items-start gap-2",
8033
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
8034
+ icon: "circle-exclamation",
8035
+ className: "text-red-400 mt-0.5 flex-shrink-0"
8036
+ }), /*#__PURE__*/jsx("span", {
8037
+ className: "text-sm text-red-200",
8038
+ children: error
8039
+ })]
8060
8040
  }), /*#__PURE__*/jsxs("div", {
8061
8041
  className: "flex flex-col gap-6",
8062
- children: [subStep === 0 && /*#__PURE__*/jsxs("div", {
8042
+ children: [state.step === 1 && /*#__PURE__*/jsxs("div", {
8063
8043
  className: "flex flex-col gap-3",
8064
8044
  children: [/*#__PURE__*/jsxs("label", {
8065
8045
  className: "flex items-center gap-2 text-sm font-semibold text-gray-300",
@@ -8072,24 +8052,8 @@ var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
8072
8052
  onChange: handleNameChange,
8073
8053
  placeholder: "My Dashboard",
8074
8054
  autoFocus: true
8075
- }), /*#__PURE__*/jsx("div", {
8076
- className: "flex justify-end mt-2",
8077
- children: /*#__PURE__*/jsx(Button, {
8078
- onClick: function onClick() {
8079
- return setSubStep(1);
8080
- },
8081
- title: "Next",
8082
- textSize: "text-sm",
8083
- padding: "py-1.5 px-4",
8084
- backgroundColor: state.customization.name.trim() ? "bg-blue-600" : "bg-gray-700",
8085
- textColor: state.customization.name.trim() ? "text-white" : "text-gray-500",
8086
- hoverTextColor: state.customization.name.trim() ? "hover:text-white" : "hover:text-gray-500",
8087
- hoverBackgroundColor: state.customization.name.trim() ? "hover:bg-blue-500" : "hover:bg-gray-700",
8088
- disabled: !state.customization.name.trim(),
8089
- icon: "arrow-right"
8090
- })
8091
8055
  })]
8092
- }), subStep === 1 && /*#__PURE__*/jsxs("div", {
8056
+ }), state.step === 2 && /*#__PURE__*/jsxs("div", {
8093
8057
  className: "flex flex-col gap-3",
8094
8058
  children: [/*#__PURE__*/jsxs("label", {
8095
8059
  className: "flex items-center gap-2 text-sm font-semibold text-gray-300",
@@ -8181,23 +8145,8 @@ var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
8181
8145
  })
8182
8146
  }, item.id);
8183
8147
  })]
8184
- }), /*#__PURE__*/jsx("div", {
8185
- className: "flex justify-end mt-2",
8186
- children: /*#__PURE__*/jsx(Button, {
8187
- onClick: function onClick() {
8188
- return setSubStep(2);
8189
- },
8190
- title: "Next",
8191
- textSize: "text-sm",
8192
- padding: "py-1.5 px-4",
8193
- backgroundColor: "bg-blue-600",
8194
- textColor: "text-white",
8195
- hoverTextColor: "hover:text-white",
8196
- hoverBackgroundColor: "hover:bg-blue-500",
8197
- icon: "arrow-right"
8198
- })
8199
8148
  })]
8200
- }), subStep === 2 && /*#__PURE__*/jsxs("div", {
8149
+ }), state.step === 3 && /*#__PURE__*/jsxs("div", {
8201
8150
  className: "flex flex-col gap-3",
8202
8151
  children: [/*#__PURE__*/jsxs("label", {
8203
8152
  className: "flex items-center gap-2 text-sm font-semibold text-gray-300",
@@ -8288,6 +8237,21 @@ var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
8288
8237
  })]
8289
8238
  })]
8290
8239
  })]
8240
+ }), state.step === 4 && /*#__PURE__*/jsxs("div", {
8241
+ className: "flex flex-col gap-3",
8242
+ children: [/*#__PURE__*/jsxs("label", {
8243
+ className: "flex items-center gap-2 text-sm font-semibold text-gray-300",
8244
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
8245
+ icon: "circle-check",
8246
+ fixedWidth: true
8247
+ }), "Review"]
8248
+ }), /*#__PURE__*/jsxs("p", {
8249
+ className: "text-sm text-gray-400",
8250
+ children: ["Confirm the dashboard details above. Click", " ", /*#__PURE__*/jsx("strong", {
8251
+ className: "text-gray-200",
8252
+ children: "Create Dashboard"
8253
+ }), " when you're ready \u2014 the modal footer holds the action."]
8254
+ })]
8291
8255
  }), authNeeded && /*#__PURE__*/jsxs("div", {
8292
8256
  className: "flex flex-col gap-3",
8293
8257
  children: [/*#__PURE__*/jsx("div", {
@@ -8351,7 +8315,7 @@ var WizardCustomizeStep = function WizardCustomizeStep(_ref) {
8351
8315
 
8352
8316
  function ownKeys$U(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; }
8353
8317
  function _objectSpread$U(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$U(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$U(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8354
- var TOTAL_STEPS = 2; // Steps 0-1: Discover, Customize
8318
+ var TOTAL_STEPS = 5; // Steps 0-4: Discover, Name, Folder, Theme, Review
8355
8319
 
8356
8320
  var initialState = {
8357
8321
  step: 0,
@@ -8482,16 +8446,26 @@ function widgetCountToTemplate(count) {
8482
8446
  return "three-by-three";
8483
8447
  }
8484
8448
  function getCanProceed(state) {
8449
+ // Step semantics (Cycle 2 restructure):
8450
+ // 0 = Discover (browse + select)
8451
+ // 1 = Name
8452
+ // 2 = Folder
8453
+ // 3 = Theme
8454
+ // 4 = Review (final — Create button replaces Next)
8485
8455
  switch (state.step) {
8486
8456
  case 0:
8487
8457
  return state.selectedDashboard !== null || state.selectedWidgets.length > 0;
8488
8458
  case 1:
8489
- // Create can fire only when the user has both a name and a theme.
8490
- // The wizard auto-defaults theme to the user's active app theme,
8491
- // so this gate is mostly belt-and-suspenders — but it locks the
8492
- // contract so a future refactor that drops the auto-default
8493
- // can't quietly let the Create button enable on name alone.
8494
- return state.customization.name.trim().length > 0 && !!state.customization.theme;
8459
+ return state.customization.name.trim().length > 0;
8460
+ case 2:
8461
+ return state.customization.menuId !== null;
8462
+ case 3:
8463
+ return !!state.customization.theme;
8464
+ case 4:
8465
+ // Review is the final step — there's no "next" beyond it. The
8466
+ // modal's footer swaps Next for Create on this step; the actual
8467
+ // gate for *firing* Create is composed there (`canCreate`).
8468
+ return true;
8495
8469
  default:
8496
8470
  return false;
8497
8471
  }
@@ -8548,11 +8522,17 @@ var useWizardState = function useWizardState() {
8548
8522
  };
8549
8523
 
8550
8524
  var STEP_LABELS = [{
8551
- label: "Discover",
8552
- description: "Search & select"
8525
+ label: "Name",
8526
+ description: "Pick a name"
8527
+ }, {
8528
+ label: "Folder",
8529
+ description: "Where it lives"
8530
+ }, {
8531
+ label: "Theme",
8532
+ description: "How it looks"
8553
8533
  }, {
8554
- label: "Customize",
8555
- description: "Name, folder & theme"
8534
+ label: "Review",
8535
+ description: "Confirm & create"
8556
8536
  }];
8557
8537
 
8558
8538
  /**
@@ -8608,10 +8588,17 @@ var DashboardWizardModal = function DashboardWizardModal(_ref) {
8608
8588
  if (!canProceed) return;
8609
8589
  nextStep();
8610
8590
  }, [canProceed, nextStep]);
8611
- var isLastStep = state.step === 1;
8591
+ var isDiscover = state.step === 0;
8592
+ var isLastStep = state.step === 4;
8612
8593
  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;
8613
8594
  var isCreated = !!((_createHandlerRef$cur3 = createHandlerRef.current) !== null && _createHandlerRef$cur3 !== void 0 && _createHandlerRef$cur3.createdDashboard);
8614
- var canCreate = canProceed && !isCreating;
8595
+ // Create only fires when every prior step has been validated. The
8596
+ // Review step (canProceed=true by design) doesn't tell us whether
8597
+ // Name/Folder/Theme were filled, so we re-check the underlying
8598
+ // customization here — belt-and-suspenders for clicks that race
8599
+ // the stepper.
8600
+ var customizationComplete = state.customization.name.trim().length > 0 && state.customization.menuId !== null && !!state.customization.theme;
8601
+ var canCreate = customizationComplete && !isCreating;
8615
8602
  return /*#__PURE__*/jsx(Modal, {
8616
8603
  isOpen: open,
8617
8604
  setIsOpen: setIsOpen,
@@ -8643,43 +8630,43 @@ var DashboardWizardModal = function DashboardWizardModal(_ref) {
8643
8630
  })]
8644
8631
  }), /*#__PURE__*/jsxs("div", {
8645
8632
  className: "flex flex-col flex-1 min-h-0 px-6 py-4",
8646
- children: [/*#__PURE__*/jsxs(Stepper, {
8647
- activeStep: state.step,
8648
- onStepChange: handleStepChange,
8633
+ children: [isDiscover ? /*#__PURE__*/jsx("div", {
8634
+ className: "flex-1 min-h-0 overflow-y-auto",
8635
+ children: /*#__PURE__*/jsx(WizardDiscoverStep, {
8636
+ state: state,
8637
+ dispatch: dispatch
8638
+ })
8639
+ }) : /*#__PURE__*/jsx(Stepper, {
8640
+ activeStep: state.step - 1,
8641
+ onStepChange: function onStepChange(s) {
8642
+ return handleStepChange(s + 1);
8643
+ },
8649
8644
  showNavigation: false,
8650
8645
  className: "flex-1 min-h-0",
8651
- children: [/*#__PURE__*/jsx(Stepper.Step, {
8652
- label: STEP_LABELS[0].label,
8653
- description: STEP_LABELS[0].description,
8654
- children: /*#__PURE__*/jsx("div", {
8655
- className: "flex-1 min-h-0 overflow-y-auto",
8656
- children: /*#__PURE__*/jsx(WizardDiscoverStep, {
8657
- state: state,
8658
- dispatch: dispatch
8659
- })
8660
- })
8661
- }), /*#__PURE__*/jsx(Stepper.Step, {
8662
- label: STEP_LABELS[1].label,
8663
- description: STEP_LABELS[1].description,
8664
- children: /*#__PURE__*/jsx("div", {
8665
- className: "flex-1 min-h-0 overflow-y-auto",
8666
- children: /*#__PURE__*/jsx(WizardCustomizeStep, {
8667
- state: state,
8668
- dispatch: dispatch,
8669
- menuItems: menuItems,
8670
- onSaveMenuItem: onSaveMenuItem,
8671
- onCreateWorkspace: onCreateWorkspace,
8672
- onInstallDashboard: onInstallDashboard,
8673
- onOpenDashboard: function onOpenDashboard(ws) {
8674
- handleClose();
8675
- if (_onOpenDashboard) _onOpenDashboard(ws);
8676
- if (onReloadWorkspaces) onReloadWorkspaces();
8677
- },
8678
- appId: appId,
8679
- createHandlerRef: createHandlerRef
8646
+ children: STEP_LABELS.map(function (label) {
8647
+ return /*#__PURE__*/jsx(Stepper.Step, {
8648
+ label: label.label,
8649
+ description: label.description,
8650
+ children: /*#__PURE__*/jsx("div", {
8651
+ className: "flex-1 min-h-0 overflow-y-auto",
8652
+ children: /*#__PURE__*/jsx(WizardCustomizeStep, {
8653
+ state: state,
8654
+ dispatch: dispatch,
8655
+ menuItems: menuItems,
8656
+ onSaveMenuItem: onSaveMenuItem,
8657
+ onCreateWorkspace: onCreateWorkspace,
8658
+ onInstallDashboard: onInstallDashboard,
8659
+ onOpenDashboard: function onOpenDashboard(ws) {
8660
+ handleClose();
8661
+ if (_onOpenDashboard) _onOpenDashboard(ws);
8662
+ if (onReloadWorkspaces) onReloadWorkspaces();
8663
+ },
8664
+ appId: appId,
8665
+ createHandlerRef: createHandlerRef
8666
+ })
8680
8667
  })
8681
- })
8682
- })]
8668
+ }, label.label);
8669
+ })
8683
8670
  }), !isCreated && /*#__PURE__*/jsxs("div", {
8684
8671
  className: "flex flex-row justify-between items-center pt-4 mt-4 border-t border-gray-700/50",
8685
8672
  children: [/*#__PURE__*/jsx(Button, {
@@ -8691,9 +8678,9 @@ var DashboardWizardModal = function DashboardWizardModal(_ref) {
8691
8678
  textColor: "text-gray-300",
8692
8679
  hoverTextColor: "hover:text-white",
8693
8680
  hoverBackgroundColor: "hover:bg-gray-600"
8694
- }), /*#__PURE__*/jsxs("span", {
8681
+ }), /*#__PURE__*/jsx("span", {
8695
8682
  className: "text-xs text-gray-500",
8696
- children: ["Step ", state.step + 1, " of ", STEP_LABELS.length]
8683
+ children: isDiscover ? "Browse" : "Step ".concat(state.step, " of ").concat(STEP_LABELS.length)
8697
8684
  }), isLastStep ? /*#__PURE__*/jsx(Button, {
8698
8685
  onClick: function onClick() {
8699
8686
  var _createHandlerRef$cur4, _createHandlerRef$cur5;