@trops/dash-core 0.1.94 → 0.1.97

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
@@ -3182,26 +3182,27 @@ var IconPicker = function IconPicker(_ref) {
3182
3182
  })]
3183
3183
  });
3184
3184
  };
3185
- var FolderDetail = function FolderDetail(_ref2) {
3186
- var _ref2$menuItem = _ref2.menuItem,
3187
- menuItem = _ref2$menuItem === void 0 ? null : _ref2$menuItem,
3188
- _ref2$workspaces = _ref2.workspaces,
3189
- workspaces = _ref2$workspaces === void 0 ? [] : _ref2$workspaces,
3190
- _ref2$isEditing = _ref2.isEditing,
3191
- isEditing = _ref2$isEditing === void 0 ? false : _ref2$isEditing,
3192
- _ref2$isCreating = _ref2.isCreating,
3193
- isCreating = _ref2$isCreating === void 0 ? false : _ref2$isCreating,
3194
- _ref2$formName = _ref2.formName,
3195
- formName = _ref2$formName === void 0 ? "" : _ref2$formName,
3196
- setFormName = _ref2.setFormName,
3197
- _ref2$formIcon = _ref2.formIcon,
3198
- formIcon = _ref2$formIcon === void 0 ? "folder" : _ref2$formIcon,
3199
- setFormIcon = _ref2.setFormIcon,
3200
- onSaveEdit = _ref2.onSaveEdit,
3201
- onCancelEdit = _ref2.onCancelEdit,
3202
- onStartEdit = _ref2.onStartEdit,
3203
- onCreate = _ref2.onCreate,
3204
- onDelete = _ref2.onDelete;
3185
+
3186
+ var FolderDetail = function FolderDetail(_ref) {
3187
+ var _ref$menuItem = _ref.menuItem,
3188
+ menuItem = _ref$menuItem === void 0 ? null : _ref$menuItem,
3189
+ _ref$workspaces = _ref.workspaces,
3190
+ workspaces = _ref$workspaces === void 0 ? [] : _ref$workspaces,
3191
+ _ref$isEditing = _ref.isEditing,
3192
+ isEditing = _ref$isEditing === void 0 ? false : _ref$isEditing,
3193
+ _ref$isCreating = _ref.isCreating,
3194
+ isCreating = _ref$isCreating === void 0 ? false : _ref$isCreating,
3195
+ _ref$formName = _ref.formName,
3196
+ formName = _ref$formName === void 0 ? "" : _ref$formName,
3197
+ setFormName = _ref.setFormName,
3198
+ _ref$formIcon = _ref.formIcon,
3199
+ formIcon = _ref$formIcon === void 0 ? "folder" : _ref$formIcon,
3200
+ setFormIcon = _ref.setFormIcon,
3201
+ onSaveEdit = _ref.onSaveEdit,
3202
+ onCancelEdit = _ref.onCancelEdit,
3203
+ onStartEdit = _ref.onStartEdit,
3204
+ onCreate = _ref.onCreate,
3205
+ onDelete = _ref.onDelete;
3205
3206
  var isFormMode = isEditing || isCreating;
3206
3207
 
3207
3208
  // Get dashboards in this folder
@@ -26480,7 +26481,21 @@ var StarRating = function StarRating(_ref) {
26480
26481
  });
26481
26482
  };
26482
26483
 
26484
+ var DASHBOARD_TAGS = ["productivity", "monitoring", "analytics", "communication", "developer", "sales", "marketing", "finance", "project-management", "social", "news", "utilities"];
26485
+
26486
+ /**
26487
+ * PublishDashboardModal — multi-step stepper for preparing a dashboard
26488
+ * for registry publishing.
26489
+ *
26490
+ * Steps:
26491
+ * 0. Account — Auth check, sign-in prompt, profile display
26492
+ * 1. Details — Author name (pre-filled from profile) + description (textarea)
26493
+ * 2. Tags — Predefined tag selection with toggle-pill styling
26494
+ * 3. Icon — Full icon picker with search
26495
+ * 4. Publish — Review summary, publish action, result display
26496
+ */
26483
26497
  var PublishDashboardModal = function PublishDashboardModal(_ref) {
26498
+ var _result$registrySubmi, _result$registrySubmi2;
26484
26499
  var isOpen = _ref.isOpen,
26485
26500
  setIsOpen = _ref.setIsOpen,
26486
26501
  appId = _ref.appId,
@@ -26491,146 +26506,657 @@ var PublishDashboardModal = function PublishDashboardModal(_ref) {
26491
26506
  var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
26492
26507
  grow: false
26493
26508
  });
26494
- var _useState = React.useState(""),
26509
+ // Stepper state
26510
+ var _useState = React.useState(0),
26495
26511
  _useState2 = _slicedToArray(_useState, 2),
26496
- description = _useState2[0],
26497
- setDescription = _useState2[1];
26498
- var _useState3 = React.useState(""),
26512
+ step = _useState2[0],
26513
+ setStep = _useState2[1];
26514
+
26515
+ // Step 0: Account / Auth
26516
+ var _useState3 = React.useState("loading"),
26499
26517
  _useState4 = _slicedToArray(_useState3, 2),
26500
- tags = _useState4[0],
26501
- setTags = _useState4[1];
26502
- var _useState5 = React.useState(""),
26518
+ authStatus = _useState4[0],
26519
+ setAuthStatus = _useState4[1]; // "loading" | "authenticated" | "unauthenticated"
26520
+ var _useState5 = React.useState(null),
26503
26521
  _useState6 = _slicedToArray(_useState5, 2),
26504
- icon = _useState6[0],
26505
- setIcon = _useState6[1];
26506
- var _useState7 = React.useState(false),
26522
+ profile = _useState6[0],
26523
+ setProfile = _useState6[1];
26524
+ var _useState7 = React.useState(null),
26507
26525
  _useState8 = _slicedToArray(_useState7, 2),
26508
- isPublishing = _useState8[0],
26509
- setIsPublishing = _useState8[1];
26510
- var _useState9 = React.useState(null),
26526
+ authFlow = _useState8[0],
26527
+ setAuthFlow = _useState8[1];
26528
+ var _useState9 = React.useState(false),
26511
26529
  _useState0 = _slicedToArray(_useState9, 2),
26512
- result = _useState0[0],
26513
- setResult = _useState0[1];
26530
+ isPolling = _useState0[0],
26531
+ setIsPolling = _useState0[1];
26532
+
26533
+ // Step 1: Details
26534
+ var _useState1 = React.useState(""),
26535
+ _useState10 = _slicedToArray(_useState1, 2),
26536
+ authorName = _useState10[0],
26537
+ setAuthorName = _useState10[1];
26538
+ var _useState11 = React.useState(""),
26539
+ _useState12 = _slicedToArray(_useState11, 2),
26540
+ description = _useState12[0],
26541
+ setDescription = _useState12[1];
26542
+
26543
+ // Step 2: Tags
26544
+ var _useState13 = React.useState([]),
26545
+ _useState14 = _slicedToArray(_useState13, 2),
26546
+ selectedTags = _useState14[0],
26547
+ setSelectedTags = _useState14[1];
26548
+
26549
+ // Step 3: Icon
26550
+ var _useState15 = React.useState("grip"),
26551
+ _useState16 = _slicedToArray(_useState15, 2),
26552
+ icon = _useState16[0],
26553
+ setIcon = _useState16[1];
26554
+
26555
+ // Step 4: Publish
26556
+ var _useState17 = React.useState(false),
26557
+ _useState18 = _slicedToArray(_useState17, 2),
26558
+ isPublishing = _useState18[0],
26559
+ setIsPublishing = _useState18[1];
26560
+ var _useState19 = React.useState(null),
26561
+ _useState20 = _slicedToArray(_useState19, 2),
26562
+ result = _useState20[0],
26563
+ setResult = _useState20[1];
26564
+
26565
+ // Check auth status on mount
26566
+ React.useEffect(function () {
26567
+ if (!isOpen) return;
26568
+ var cancelled = false;
26569
+ function checkAuth() {
26570
+ return _checkAuth.apply(this, arguments);
26571
+ }
26572
+ function _checkAuth() {
26573
+ _checkAuth = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
26574
+ var status, userProfile;
26575
+ return _regeneratorRuntime.wrap(function (_context) {
26576
+ while (1) switch (_context.prev = _context.next) {
26577
+ case 0:
26578
+ _context.prev = 0;
26579
+ _context.next = 1;
26580
+ return window.mainApi.registryAuth.getStatus();
26581
+ case 1:
26582
+ status = _context.sent;
26583
+ if (!cancelled) {
26584
+ _context.next = 2;
26585
+ break;
26586
+ }
26587
+ return _context.abrupt("return");
26588
+ case 2:
26589
+ if (!status.authenticated) {
26590
+ _context.next = 5;
26591
+ break;
26592
+ }
26593
+ _context.next = 3;
26594
+ return window.mainApi.registryAuth.getProfile();
26595
+ case 3:
26596
+ userProfile = _context.sent;
26597
+ if (!cancelled) {
26598
+ _context.next = 4;
26599
+ break;
26600
+ }
26601
+ return _context.abrupt("return");
26602
+ case 4:
26603
+ setProfile(userProfile);
26604
+ setAuthStatus("authenticated");
26605
+ if (userProfile !== null && userProfile !== void 0 && userProfile.displayName && !authorName) {
26606
+ setAuthorName(userProfile.displayName);
26607
+ }
26608
+ _context.next = 6;
26609
+ break;
26610
+ case 5:
26611
+ setAuthStatus("unauthenticated");
26612
+ case 6:
26613
+ _context.next = 8;
26614
+ break;
26615
+ case 7:
26616
+ _context.prev = 7;
26617
+ _context["catch"](0);
26618
+ if (!cancelled) setAuthStatus("unauthenticated");
26619
+ case 8:
26620
+ case "end":
26621
+ return _context.stop();
26622
+ }
26623
+ }, _callee, null, [[0, 7]]);
26624
+ }));
26625
+ return _checkAuth.apply(this, arguments);
26626
+ }
26627
+ checkAuth();
26628
+ return function () {
26629
+ cancelled = true;
26630
+ };
26631
+ }, [isOpen]);
26632
+ function resetState() {
26633
+ setStep(0);
26634
+ setAuthStatus("loading");
26635
+ setProfile(null);
26636
+ setAuthFlow(null);
26637
+ setIsPolling(false);
26638
+ setAuthorName("");
26639
+ setDescription("");
26640
+ setSelectedTags([]);
26641
+ setIcon("grip");
26642
+ setIsPublishing(false);
26643
+ setResult(null);
26644
+ }
26514
26645
  function handleClose() {
26515
26646
  setIsOpen(false);
26516
- // Reset state after a brief delay to avoid flash
26517
- setTimeout(function () {
26518
- setDescription("");
26519
- setTags("");
26520
- setIcon("");
26521
- setIsPublishing(false);
26522
- setResult(null);
26523
- }, 200);
26647
+ setTimeout(resetState, 200);
26648
+ }
26649
+ function handleStepChange(nextStep) {
26650
+ if (step === 0 && nextStep > 0 && authStatus !== "authenticated") return;
26651
+ if (step === 1 && nextStep > 1 && !authorName.trim()) return;
26652
+ if (step === 2 && nextStep > 2 && selectedTags.length === 0) return;
26653
+ setStep(nextStep);
26654
+ }
26655
+ function toggleTag(tag) {
26656
+ setSelectedTags(function (prev) {
26657
+ return prev.includes(tag) ? prev.filter(function (t) {
26658
+ return t !== tag;
26659
+ }) : [].concat(_toConsumableArray(prev), [tag]);
26660
+ });
26524
26661
  }
26525
26662
  function handlePublish() {
26526
26663
  return _handlePublish.apply(this, arguments);
26527
26664
  }
26528
26665
  function _handlePublish() {
26529
- _handlePublish = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
26530
- var options, res, _t;
26531
- return _regeneratorRuntime.wrap(function (_context) {
26532
- while (1) switch (_context.prev = _context.next) {
26666
+ _handlePublish = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
26667
+ var options, res, _t2;
26668
+ return _regeneratorRuntime.wrap(function (_context2) {
26669
+ while (1) switch (_context2.prev = _context2.next) {
26533
26670
  case 0:
26534
26671
  if (!(!appId || !workspaceId)) {
26535
- _context.next = 1;
26672
+ _context2.next = 1;
26536
26673
  break;
26537
26674
  }
26538
- return _context.abrupt("return");
26675
+ return _context2.abrupt("return");
26539
26676
  case 1:
26540
26677
  setIsPublishing(true);
26541
26678
  setResult(null);
26542
- _context.prev = 2;
26679
+ _context2.prev = 2;
26543
26680
  options = {
26681
+ authorName: authorName.trim(),
26544
26682
  description: description.trim() || undefined,
26545
- tags: tags.split(",").map(function (t) {
26546
- return t.trim();
26547
- }).filter(Boolean),
26548
- icon: icon.trim() || undefined
26683
+ tags: selectedTags,
26684
+ icon: icon || undefined
26549
26685
  };
26550
- _context.next = 3;
26686
+ _context2.next = 3;
26551
26687
  return window.mainApi.dashboardConfig.prepareDashboardForPublish(appId, workspaceId, options);
26552
26688
  case 3:
26553
- res = _context.sent;
26689
+ res = _context2.sent;
26554
26690
  setResult(res);
26555
- _context.next = 5;
26691
+ _context2.next = 5;
26556
26692
  break;
26557
26693
  case 4:
26558
- _context.prev = 4;
26559
- _t = _context["catch"](2);
26694
+ _context2.prev = 4;
26695
+ _t2 = _context2["catch"](2);
26560
26696
  setResult({
26561
26697
  success: false,
26562
- error: _t.message || "Failed to prepare dashboard for publish."
26698
+ error: _t2.message || "Failed to prepare dashboard for publish."
26563
26699
  });
26564
26700
  case 5:
26565
- _context.prev = 5;
26701
+ _context2.prev = 5;
26566
26702
  setIsPublishing(false);
26567
- return _context.finish(5);
26703
+ return _context2.finish(5);
26568
26704
  case 6:
26569
26705
  case "end":
26570
- return _context.stop();
26706
+ return _context2.stop();
26571
26707
  }
26572
- }, _callee, null, [[2, 4, 5, 6]]);
26708
+ }, _callee2, null, [[2, 4, 5, 6]]);
26573
26709
  }));
26574
26710
  return _handlePublish.apply(this, arguments);
26575
26711
  }
26576
- return /*#__PURE__*/jsxRuntime.jsx(DashReact.ConfirmationModal, {
26712
+ function handleSignIn() {
26713
+ return _handleSignIn.apply(this, arguments);
26714
+ }
26715
+ function _handleSignIn() {
26716
+ _handleSignIn = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
26717
+ var flow, interval, poll;
26718
+ return _regeneratorRuntime.wrap(function (_context4) {
26719
+ while (1) switch (_context4.prev = _context4.next) {
26720
+ case 0:
26721
+ _context4.prev = 0;
26722
+ _context4.next = 1;
26723
+ return window.mainApi.registryAuth.initiateLogin();
26724
+ case 1:
26725
+ flow = _context4.sent;
26726
+ setAuthFlow(flow);
26727
+
26728
+ // Open verification URL in browser
26729
+ if (flow.verificationUrlComplete) {
26730
+ window.mainApi.shell.openExternal(flow.verificationUrlComplete);
26731
+ }
26732
+
26733
+ // Start polling
26734
+ setIsPolling(true);
26735
+ interval = (flow.interval || 5) * 1000;
26736
+ poll = setInterval(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
26737
+ var pollResult, userProfile;
26738
+ return _regeneratorRuntime.wrap(function (_context3) {
26739
+ while (1) switch (_context3.prev = _context3.next) {
26740
+ case 0:
26741
+ _context3.prev = 0;
26742
+ _context3.next = 1;
26743
+ return window.mainApi.registryAuth.pollToken(flow.deviceCode);
26744
+ case 1:
26745
+ pollResult = _context3.sent;
26746
+ if (!(pollResult.status === "authorized")) {
26747
+ _context3.next = 3;
26748
+ break;
26749
+ }
26750
+ clearInterval(poll);
26751
+ setIsPolling(false);
26752
+ setAuthFlow(null);
26753
+ // Fetch profile and update auth state
26754
+ _context3.next = 2;
26755
+ return window.mainApi.registryAuth.getProfile();
26756
+ case 2:
26757
+ userProfile = _context3.sent;
26758
+ setProfile(userProfile);
26759
+ setAuthStatus("authenticated");
26760
+ if (userProfile !== null && userProfile !== void 0 && userProfile.displayName && !authorName) {
26761
+ setAuthorName(userProfile.displayName);
26762
+ }
26763
+ _context3.next = 4;
26764
+ break;
26765
+ case 3:
26766
+ if (pollResult.status === "expired") {
26767
+ clearInterval(poll);
26768
+ setIsPolling(false);
26769
+ setAuthFlow(null);
26770
+ }
26771
+ case 4:
26772
+ _context3.next = 6;
26773
+ break;
26774
+ case 5:
26775
+ _context3.prev = 5;
26776
+ _context3["catch"](0);
26777
+ clearInterval(poll);
26778
+ setIsPolling(false);
26779
+ case 6:
26780
+ case "end":
26781
+ return _context3.stop();
26782
+ }
26783
+ }, _callee3, null, [[0, 5]]);
26784
+ })), interval);
26785
+ _context4.next = 3;
26786
+ break;
26787
+ case 2:
26788
+ _context4.prev = 2;
26789
+ _context4["catch"](0);
26790
+ case 3:
26791
+ case "end":
26792
+ return _context4.stop();
26793
+ }
26794
+ }, _callee4, null, [[0, 2]]);
26795
+ }));
26796
+ return _handleSignIn.apply(this, arguments);
26797
+ }
26798
+ function handleSignOut() {
26799
+ return _handleSignOut.apply(this, arguments);
26800
+ }
26801
+ function _handleSignOut() {
26802
+ _handleSignOut = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5() {
26803
+ return _regeneratorRuntime.wrap(function (_context5) {
26804
+ while (1) switch (_context5.prev = _context5.next) {
26805
+ case 0:
26806
+ _context5.prev = 0;
26807
+ _context5.next = 1;
26808
+ return window.mainApi.registryAuth.logout();
26809
+ case 1:
26810
+ setAuthStatus("unauthenticated");
26811
+ setProfile(null);
26812
+ _context5.next = 3;
26813
+ break;
26814
+ case 2:
26815
+ _context5.prev = 2;
26816
+ _context5["catch"](0);
26817
+ case 3:
26818
+ case "end":
26819
+ return _context5.stop();
26820
+ }
26821
+ }, _callee5, null, [[0, 2]]);
26822
+ }));
26823
+ return _handleSignOut.apply(this, arguments);
26824
+ }
26825
+ var isLastStep = step === 4;
26826
+ var canAdvance = step === 0 ? authStatus === "authenticated" : step === 1 ? !!authorName.trim() : step === 2 ? selectedTags.length > 0 : true;
26827
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Modal, {
26577
26828
  isOpen: isOpen,
26578
26829
  setIsOpen: handleClose,
26579
- title: "Publish \"".concat(workspaceName || "Dashboard", "\""),
26580
- confirmLabel: isPublishing ? "Preparing..." : "Prepare for Publish",
26581
- onConfirm: result ? handleClose : handlePublish,
26582
- onCancel: handleClose,
26583
- disabled: isPublishing,
26584
- children: /*#__PURE__*/jsxRuntime.jsx("div", {
26585
- className: "space-y-4 ".concat(panelStyles.textColor || "text-gray-200"),
26586
- children: !result ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
26587
- children: [/*#__PURE__*/jsxRuntime.jsx("p", {
26588
- className: "text-sm opacity-70",
26589
- children: "This will create a publish-ready ZIP file that can be submitted to the dashboard registry."
26590
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26591
- className: "space-y-3",
26592
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
26593
- label: "Description",
26594
- value: description,
26595
- onChange: setDescription,
26596
- placeholder: "A brief description of this dashboard..."
26597
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
26598
- label: "Tags (comma-separated)",
26599
- value: tags,
26600
- onChange: setTags,
26601
- placeholder: "productivity, slack, monitoring"
26602
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
26603
- label: "Icon (FontAwesome name)",
26604
- value: icon,
26605
- onChange: setIcon,
26606
- placeholder: "chart-line"
26607
- })]
26830
+ width: "w-full max-w-2xl",
26831
+ height: "h-[70vh]",
26832
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26833
+ className: "flex flex-col h-full rounded-lg overflow-clip border ".concat(panelStyles.backgroundColor || "", " ").concat(panelStyles.borderColor || "", " ").concat(panelStyles.textColor || ""),
26834
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
26835
+ className: "flex-shrink-0 flex flex-row items-center justify-between p-4 border-b border-white/10",
26836
+ children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
26837
+ className: "text-lg font-semibold",
26838
+ children: ["Publish \"", workspaceName || "Dashboard", "\""]
26839
+ }), /*#__PURE__*/jsxRuntime.jsx("button", {
26840
+ type: "button",
26841
+ onClick: handleClose,
26842
+ className: "opacity-50 hover:opacity-100 transition-opacity cursor-pointer",
26843
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26844
+ icon: "xmark",
26845
+ className: "h-5 w-5"
26846
+ })
26608
26847
  })]
26609
- }) : result.success ? /*#__PURE__*/jsxRuntime.jsxs("div", {
26610
- className: "space-y-3",
26611
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
26612
- className: "flex items-center gap-2",
26613
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26614
- icon: "circle-check",
26615
- className: "h-4 w-4 text-green-400"
26616
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
26617
- className: "text-sm",
26618
- children: "Dashboard prepared for publishing."
26619
- })]
26620
- }), result.filePath && /*#__PURE__*/jsxRuntime.jsxs("div", {
26621
- className: "text-xs opacity-50 break-all",
26622
- children: ["Saved to: ", result.filePath]
26848
+ }), /*#__PURE__*/jsxRuntime.jsxs(DashReact.Stepper, {
26849
+ activeStep: step,
26850
+ onStepChange: handleStepChange,
26851
+ showNavigation: false,
26852
+ className: "flex-1 min-h-0 flex flex-col px-6 pt-2",
26853
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
26854
+ label: "Account",
26855
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26856
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
26857
+ children: [authStatus === "loading" && /*#__PURE__*/jsxRuntime.jsx("div", {
26858
+ className: "flex items-center justify-center py-12",
26859
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26860
+ className: "flex items-center gap-3 text-sm opacity-60",
26861
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26862
+ icon: "spinner",
26863
+ className: "h-4 w-4 animate-spin"
26864
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26865
+ children: "Checking account status..."
26866
+ })]
26867
+ })
26868
+ }), authStatus === "authenticated" && profile && /*#__PURE__*/jsxRuntime.jsxs("div", {
26869
+ className: "space-y-4",
26870
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
26871
+ className: "text-sm opacity-70",
26872
+ children: "You're signed in and ready to publish."
26873
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26874
+ className: "bg-white/5 border border-white/10 rounded-lg p-4 flex items-center gap-4",
26875
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
26876
+ className: "flex items-center justify-center h-10 w-10 rounded-full bg-green-500/20 border border-green-500/30",
26877
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26878
+ icon: "circle-check",
26879
+ className: "h-5 w-5 text-green-400"
26880
+ })
26881
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26882
+ className: "flex-1 min-w-0",
26883
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
26884
+ className: "text-sm font-medium truncate",
26885
+ children: profile.displayName || profile.username
26886
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26887
+ className: "text-xs opacity-50 truncate",
26888
+ children: ["@", profile.username]
26889
+ })]
26890
+ })]
26891
+ }), /*#__PURE__*/jsxRuntime.jsx("button", {
26892
+ type: "button",
26893
+ onClick: handleSignOut,
26894
+ className: "text-xs opacity-40 hover:opacity-70 transition-opacity cursor-pointer",
26895
+ children: "Sign out"
26896
+ })]
26897
+ }), authStatus === "unauthenticated" && /*#__PURE__*/jsxRuntime.jsxs("div", {
26898
+ className: "space-y-4",
26899
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
26900
+ className: "text-sm opacity-70",
26901
+ children: "Sign in to the Dash Registry to publish your dashboard."
26902
+ }), !authFlow && !isPolling && /*#__PURE__*/jsxRuntime.jsx("button", {
26903
+ type: "button",
26904
+ onClick: handleSignIn,
26905
+ className: "px-4 py-2 rounded-lg text-sm bg-blue-500/20 border border-blue-500/30 text-blue-300 hover:bg-blue-500/30 transition-colors cursor-pointer",
26906
+ children: "Sign in to Registry"
26907
+ }), authFlow && isPolling && /*#__PURE__*/jsxRuntime.jsxs("div", {
26908
+ className: "bg-blue-500/10 border border-blue-500/20 rounded-lg p-4 space-y-3",
26909
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
26910
+ className: "text-xs text-blue-300/90",
26911
+ children: "Enter this code in your browser:"
26912
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
26913
+ className: "text-center",
26914
+ children: /*#__PURE__*/jsxRuntime.jsx("span", {
26915
+ className: "text-2xl font-mono font-bold tracking-widest text-white",
26916
+ children: authFlow.userCode
26917
+ })
26918
+ }), /*#__PURE__*/jsxRuntime.jsx("p", {
26919
+ className: "text-xs text-blue-300/70 text-center",
26920
+ children: "Waiting for authorization..."
26921
+ })]
26922
+ })]
26923
+ })]
26924
+ })
26925
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
26926
+ label: "Details",
26927
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26928
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
26929
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
26930
+ className: "text-sm opacity-70",
26931
+ children: "Provide details about your dashboard for the registry listing."
26932
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.InputText, {
26933
+ label: "Author Name *",
26934
+ value: authorName,
26935
+ onChange: setAuthorName,
26936
+ placeholder: "Your name"
26937
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.TextArea, {
26938
+ label: "Description",
26939
+ value: description,
26940
+ onChange: setDescription,
26941
+ placeholder: "A brief description of this dashboard...",
26942
+ rows: 3
26943
+ })]
26944
+ })
26945
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
26946
+ label: "Tags",
26947
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
26948
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
26949
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
26950
+ className: "text-sm opacity-70",
26951
+ children: "Select at least one tag to categorize your dashboard."
26952
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
26953
+ className: "grid grid-cols-3 gap-2",
26954
+ children: DASHBOARD_TAGS.map(function (tag) {
26955
+ var isSelected = selectedTags.includes(tag);
26956
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
26957
+ type: "button",
26958
+ onClick: function onClick() {
26959
+ return toggleTag(tag);
26960
+ },
26961
+ className: "px-3 py-1.5 rounded-full text-sm border transition-colors cursor-pointer ".concat(isSelected ? "bg-white/15 border-white/30 text-white" : "bg-transparent border-white/10 text-white/60 hover:border-white/20 hover:text-white/80"),
26962
+ children: tag
26963
+ }, tag);
26964
+ })
26965
+ })]
26966
+ })
26967
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
26968
+ label: "Icon",
26969
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
26970
+ className: "flex-1 min-h-0 flex flex-col pb-4",
26971
+ children: /*#__PURE__*/jsxRuntime.jsx(IconPicker, {
26972
+ selectedIcon: icon,
26973
+ onSelectIcon: setIcon
26974
+ })
26975
+ })
26976
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
26977
+ label: "Publish",
26978
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
26979
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-4",
26980
+ children: !result ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
26981
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
26982
+ className: "text-sm opacity-70",
26983
+ children: "Review your dashboard details before publishing."
26984
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
26985
+ className: "bg-white/5 border border-white/10 rounded-lg p-4 space-y-2 text-sm",
26986
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
26987
+ className: "flex gap-2",
26988
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26989
+ className: "opacity-50 w-20 flex-shrink-0",
26990
+ children: "Author"
26991
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
26992
+ children: authorName
26993
+ })]
26994
+ }), description.trim() && /*#__PURE__*/jsxRuntime.jsxs("div", {
26995
+ className: "flex gap-2",
26996
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
26997
+ className: "opacity-50 w-20 flex-shrink-0",
26998
+ children: "Description"
26999
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27000
+ children: description
27001
+ })]
27002
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27003
+ className: "flex gap-2",
27004
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27005
+ className: "opacity-50 w-20 flex-shrink-0",
27006
+ children: "Tags"
27007
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27008
+ children: selectedTags.length > 0 ? selectedTags.join(", ") : "None"
27009
+ })]
27010
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27011
+ className: "flex gap-2 items-center",
27012
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
27013
+ className: "opacity-50 w-20 flex-shrink-0",
27014
+ children: "Icon"
27015
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27016
+ icon: icon || "grip",
27017
+ className: "h-4 w-4"
27018
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27019
+ className: "opacity-70",
27020
+ children: icon || "grip"
27021
+ })]
27022
+ })]
27023
+ })]
27024
+ }) : result.success ? /*#__PURE__*/jsxRuntime.jsxs("div", {
27025
+ className: "space-y-3",
27026
+ children: [(_result$registrySubmi = result.registrySubmission) !== null && _result$registrySubmi !== void 0 && _result$registrySubmi.success ? /*#__PURE__*/jsxRuntime.jsxs("div", {
27027
+ className: "space-y-3",
27028
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27029
+ className: "flex items-center gap-2",
27030
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27031
+ icon: "circle-check",
27032
+ className: "h-4 w-4 text-green-400"
27033
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27034
+ className: "text-sm",
27035
+ children: "Published to Dash Registry"
27036
+ })]
27037
+ }), result.registrySubmission.registryUrl && /*#__PURE__*/jsxRuntime.jsxs("div", {
27038
+ className: "bg-white/5 border border-white/10 rounded-lg p-3",
27039
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27040
+ className: "text-xs opacity-50 mb-1",
27041
+ children: "Shareable Link"
27042
+ }), /*#__PURE__*/jsxRuntime.jsx("button", {
27043
+ type: "button",
27044
+ onClick: function onClick() {
27045
+ return window.mainApi.shell.openExternal(result.registrySubmission.registryUrl);
27046
+ },
27047
+ className: "text-sm text-blue-400 hover:underline cursor-pointer break-all text-left",
27048
+ children: result.registrySubmission.registryUrl
27049
+ })]
27050
+ }), result.registrySubmission.version && /*#__PURE__*/jsxRuntime.jsxs("div", {
27051
+ className: "text-xs opacity-50",
27052
+ children: ["Version: v", result.registrySubmission.version]
27053
+ })]
27054
+ }) : /*#__PURE__*/jsxRuntime.jsxs("div", {
27055
+ className: "space-y-3",
27056
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27057
+ className: "flex items-center gap-2",
27058
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27059
+ icon: "circle-check",
27060
+ className: "h-4 w-4 text-green-400"
27061
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27062
+ className: "text-sm",
27063
+ children: "Dashboard prepared for publishing."
27064
+ })]
27065
+ }), ((_result$registrySubmi2 = result.registrySubmission) === null || _result$registrySubmi2 === void 0 ? void 0 : _result$registrySubmi2.error) && /*#__PURE__*/jsxRuntime.jsx("div", {
27066
+ className: "bg-amber-500/10 border border-amber-500/20 rounded-lg p-3",
27067
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
27068
+ className: "flex items-start gap-2",
27069
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27070
+ icon: "triangle-exclamation",
27071
+ className: "h-3.5 w-3.5 text-amber-400 mt-0.5 flex-shrink-0"
27072
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
27073
+ className: "text-xs text-amber-300/90",
27074
+ children: ["Registry upload failed:", " ", result.registrySubmission.error, ". Your dashboard was saved locally."]
27075
+ })]
27076
+ })
27077
+ })]
27078
+ }), result.filePath && /*#__PURE__*/jsxRuntime.jsxs("div", {
27079
+ className: "text-xs opacity-50 break-all",
27080
+ children: ["Saved to: ", result.filePath]
27081
+ }), result.warnings && result.warnings.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
27082
+ className: "bg-amber-500/10 border border-amber-500/20 rounded-lg p-3 space-y-2",
27083
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
27084
+ className: "flex items-start gap-2",
27085
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27086
+ icon: "triangle-exclamation",
27087
+ className: "h-3.5 w-3.5 text-amber-400 mt-0.5 flex-shrink-0"
27088
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27089
+ className: "text-xs text-amber-300/90",
27090
+ children: "The following widgets are not currently on the registry. This may be intentional if they are private. Dashboards referencing these widgets can only be installed by users who already have them."
27091
+ })]
27092
+ }), /*#__PURE__*/jsxRuntime.jsx("ul", {
27093
+ className: "text-xs opacity-60 pl-5 list-disc space-y-0.5",
27094
+ children: result.warnings.map(function (w) {
27095
+ return /*#__PURE__*/jsxRuntime.jsx("li", {
27096
+ children: w
27097
+ }, w);
27098
+ })
27099
+ })]
27100
+ }), result.registryCheckFailed && /*#__PURE__*/jsxRuntime.jsx("div", {
27101
+ className: "bg-amber-500/10 border border-amber-500/20 rounded-lg p-3",
27102
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
27103
+ className: "flex items-start gap-2",
27104
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27105
+ icon: "triangle-exclamation",
27106
+ className: "h-3.5 w-3.5 text-amber-400 mt-0.5 flex-shrink-0"
27107
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27108
+ className: "text-xs text-amber-300/90",
27109
+ children: "Unable to reach the registry to verify widget availability. Your dashboard was still prepared successfully."
27110
+ })]
27111
+ })
27112
+ })]
27113
+ }) : /*#__PURE__*/jsxRuntime.jsxs("div", {
27114
+ className: "flex items-center gap-2",
27115
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
27116
+ icon: "circle-xmark",
27117
+ className: "h-4 w-4 text-red-400"
27118
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
27119
+ className: "text-sm text-red-400",
27120
+ children: result.error || "Publish preparation failed."
27121
+ })]
27122
+ })
27123
+ })
26623
27124
  })]
26624
- }) : /*#__PURE__*/jsxRuntime.jsxs("div", {
26625
- className: "flex items-center gap-2",
26626
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
26627
- icon: "circle-xmark",
26628
- className: "h-4 w-4 text-red-400"
26629
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
26630
- className: "text-sm text-red-400",
26631
- children: result.error || "Publish preparation failed."
27125
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
27126
+ className: "flex-shrink-0 flex flex-row items-center px-6 py-4 border-t border-white/10",
27127
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
27128
+ className: "flex flex-row gap-2",
27129
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
27130
+ title: step === 0 ? "Cancel" : "Back",
27131
+ onClick: step === 0 ? handleClose : function () {
27132
+ return setStep(step - 1);
27133
+ },
27134
+ disabled: isPublishing
27135
+ })
27136
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
27137
+ className: "flex-1 text-center",
27138
+ children: /*#__PURE__*/jsxRuntime.jsxs("span", {
27139
+ className: "text-xs opacity-40",
27140
+ children: ["Step ", step + 1, " of 5"]
27141
+ })
27142
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
27143
+ className: "flex flex-row gap-2",
27144
+ children: result !== null && result !== void 0 && result.success ? /*#__PURE__*/jsxRuntime.jsx(DashReact.Button2, {
27145
+ title: "Done",
27146
+ onClick: handleClose
27147
+ }) : isLastStep ? /*#__PURE__*/jsxRuntime.jsx(DashReact.Button2, {
27148
+ title: isPublishing ? "Publishing..." : "Publish",
27149
+ onClick: handlePublish,
27150
+ disabled: isPublishing
27151
+ }) : /*#__PURE__*/jsxRuntime.jsx(DashReact.Button2, {
27152
+ title: "Next",
27153
+ onClick: function onClick() {
27154
+ return handleStepChange(step + 1);
27155
+ },
27156
+ disabled: !canAdvance
27157
+ })
26632
27158
  })]
26633
- })
27159
+ })]
26634
27160
  })
26635
27161
  });
26636
27162
  };
@@ -27601,7 +28127,7 @@ var DashboardsSection = function DashboardsSection(_ref) {
27601
28127
  return window.mainApi.dashboardConfig.importDashboardConfig(appId);
27602
28128
  case 3:
27603
28129
  result = _context.sent;
27604
- if (result) {
28130
+ if (!(!result || result.canceled)) {
27605
28131
  _context.next = 4;
27606
28132
  break;
27607
28133
  }
@@ -27652,7 +28178,9 @@ var DashboardsSection = function DashboardsSection(_ref) {
27652
28178
  }),
27653
28179
  active: isSelected,
27654
28180
  onClick: function onClick() {
27655
- return setSelectedId(ws.id);
28181
+ setSelectedId(ws.id);
28182
+ setInstallMode(null);
28183
+ setImportResult(null);
27656
28184
  },
27657
28185
  badge: String(widgetCount),
27658
28186
  className: isSelected ? "bg-white/10 opacity-100" : "",