@trops/dash-core 0.1.330 → 0.1.331

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
@@ -613,10 +613,13 @@ var DashboardApi = {
613
613
  * Widgets can call these methods directly (not via events) to
614
614
  * control the dashboard they are rendered in.
615
615
  *
616
- * Internally dispatches CustomEvents on `window` so the API
617
- * stays decoupled from the React component tree.
616
+ * Write actions internally dispatch CustomEvents on `window` so the
617
+ * API stays decoupled from the React component tree. Read methods
618
+ * return values from `window.__dashState`, which DashboardStage
619
+ * keeps up-to-date as workspace/page state changes.
618
620
  */
619
621
  var DashboardActionsApi = {
622
+ // ─── Page Navigation ──────────────────────────────────────────────
620
623
  /**
621
624
  * Switch the active page by its internal ID.
622
625
  * @param {string} pageId - The ID of the page to switch to
@@ -638,6 +641,119 @@ var DashboardActionsApi = {
638
641
  pageName: pageName
639
642
  }
640
643
  }));
644
+ },
645
+ /**
646
+ * Navigate to the previous page in history (browser-style back).
647
+ */
648
+ goBack: function goBack() {
649
+ window.dispatchEvent(new CustomEvent("dash:go-back"));
650
+ },
651
+ // ─── Workspace Nav Sidebar (far-left DashSidebar) ─────────────────
652
+ /**
653
+ * Collapse the workspace nav sidebar.
654
+ */
655
+ closeSidebar: function closeSidebar() {
656
+ window.dispatchEvent(new CustomEvent("dash:set-nav-sidebar", {
657
+ detail: {
658
+ collapsed: true
659
+ }
660
+ }));
661
+ },
662
+ /**
663
+ * Expand the workspace nav sidebar.
664
+ */
665
+ openSidebar: function openSidebar() {
666
+ window.dispatchEvent(new CustomEvent("dash:set-nav-sidebar", {
667
+ detail: {
668
+ collapsed: false
669
+ }
670
+ }));
671
+ },
672
+ /**
673
+ * Toggle the workspace nav sidebar.
674
+ */
675
+ toggleSidebar: function toggleSidebar() {
676
+ window.dispatchEvent(new CustomEvent("dash:toggle-nav-sidebar"));
677
+ },
678
+ // ─── Workspace (Dashboard) Navigation ─────────────────────────────
679
+ /**
680
+ * Open another dashboard in a tab by name.
681
+ * @param {string} name - The display name of the dashboard
682
+ */
683
+ openDashboardByName: function openDashboardByName(name) {
684
+ window.dispatchEvent(new CustomEvent("dash:open-dashboard", {
685
+ detail: {
686
+ name: name
687
+ }
688
+ }));
689
+ },
690
+ /**
691
+ * Close a dashboard tab. Closes the active tab if no name is given.
692
+ * @param {string} [name] - Optional: name of the dashboard tab to close
693
+ */
694
+ closeDashboard: function closeDashboard(name) {
695
+ window.dispatchEvent(new CustomEvent("dash:close-dashboard", {
696
+ detail: {
697
+ name: name
698
+ }
699
+ }));
700
+ },
701
+ // ─── Notifications (in-app toasts) ────────────────────────────────
702
+ /**
703
+ * Show an in-app toast notification.
704
+ * @param {string} message - The toast message
705
+ * @param {object} [options]
706
+ * @param {"success"|"error"|"info"|"warning"} [options.type="info"]
707
+ * @param {string} [options.title]
708
+ * @param {number} [options.duration=4000] - Auto-dismiss after ms
709
+ */
710
+ notify: function notify(message) {
711
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
712
+ window.dispatchEvent(new CustomEvent("dash:notify", {
713
+ detail: {
714
+ message: message,
715
+ type: options.type || "info",
716
+ title: options.title,
717
+ duration: options.duration || 4000
718
+ }
719
+ }));
720
+ },
721
+ // ─── Read Methods (synchronous, from window.__dashState) ──────────
722
+ /**
723
+ * @returns {string|null} The ID of the active page
724
+ */
725
+ getCurrentPageId: function getCurrentPageId() {
726
+ var _window$__dashState;
727
+ return ((_window$__dashState = window.__dashState) === null || _window$__dashState === void 0 ? void 0 : _window$__dashState.currentPageId) || null;
728
+ },
729
+ /**
730
+ * @returns {string|null} The display name of the active page
731
+ */
732
+ getCurrentPageName: function getCurrentPageName() {
733
+ var _window$__dashState2;
734
+ return ((_window$__dashState2 = window.__dashState) === null || _window$__dashState2 === void 0 ? void 0 : _window$__dashState2.currentPageName) || null;
735
+ },
736
+ /**
737
+ * @returns {number|null} The ID of the active dashboard
738
+ */
739
+ getCurrentDashboardId: function getCurrentDashboardId() {
740
+ var _window$__dashState3;
741
+ return ((_window$__dashState3 = window.__dashState) === null || _window$__dashState3 === void 0 ? void 0 : _window$__dashState3.currentDashboardId) || null;
742
+ },
743
+ /**
744
+ * @returns {string|null} The display name of the active dashboard
745
+ */
746
+ getCurrentDashboardName: function getCurrentDashboardName() {
747
+ var _window$__dashState4;
748
+ return ((_window$__dashState4 = window.__dashState) === null || _window$__dashState4 === void 0 ? void 0 : _window$__dashState4.currentDashboardName) || null;
749
+ },
750
+ /**
751
+ * @returns {Array<{id: string, name: string, order: number}>}
752
+ * Pages in the current dashboard
753
+ */
754
+ listPages: function listPages() {
755
+ var _window$__dashState5;
756
+ return ((_window$__dashState5 = window.__dashState) === null || _window$__dashState5 === void 0 ? void 0 : _window$__dashState5.pages) || [];
641
757
  }
642
758
  };
643
759
 
@@ -51013,22 +51129,28 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
51013
51129
  widgetSidebarCollapsed = _useState0[0],
51014
51130
  setWidgetSidebarCollapsed = _useState0[1];
51015
51131
 
51016
- // ─── Recents + Session ──────────────────────────────────────────
51132
+ // ─── In-app toasts (driven by DashboardActionsApi.notify) ────────
51017
51133
  var _useState1 = React.useState([]),
51018
51134
  _useState10 = _slicedToArray(_useState1, 2),
51019
- recentDashboards = _useState10[0],
51020
- setRecentDashboards = _useState10[1];
51135
+ toasts = _useState10[0],
51136
+ setToasts = _useState10[1];
51137
+
51138
+ // ─── Recents + Session ──────────────────────────────────────────
51139
+ var _useState11 = React.useState([]),
51140
+ _useState12 = _slicedToArray(_useState11, 2),
51141
+ recentDashboards = _useState12[0],
51142
+ setRecentDashboards = _useState12[1];
51021
51143
  var sessionRestored = React.useRef(false);
51022
51144
 
51023
51145
  // ─── Registry Auth (for sidebar) ────────────────────────────────
51024
- var _useState11 = React.useState("loading"),
51025
- _useState12 = _slicedToArray(_useState11, 2),
51026
- authStatus = _useState12[0],
51027
- setAuthStatus = _useState12[1];
51028
- var _useState13 = React.useState(null),
51146
+ var _useState13 = React.useState("loading"),
51029
51147
  _useState14 = _slicedToArray(_useState13, 2),
51030
- authProfile = _useState14[0],
51031
- setAuthProfile = _useState14[1];
51148
+ authStatus = _useState14[0],
51149
+ setAuthStatus = _useState14[1];
51150
+ var _useState15 = React.useState(null),
51151
+ _useState16 = _slicedToArray(_useState15, 2),
51152
+ authProfile = _useState16[0],
51153
+ setAuthProfile = _useState16[1];
51032
51154
 
51033
51155
  // Derive workspaceSelected from active tab
51034
51156
  var workspaceSelected = activeTabId ? (_openTabs$find$worksp = (_openTabs$find = openTabs.find(function (tab) {
@@ -51038,84 +51160,84 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
51038
51160
  /**
51039
51161
  * @param {Boolean} previewMode this is a toggle telling the dash we are editing
51040
51162
  */
51041
- var _useState15 = React.useState(preview),
51042
- _useState16 = _slicedToArray(_useState15, 2),
51043
- previewMode = _useState16[0],
51044
- setPreviewMode = _useState16[1];
51163
+ var _useState17 = React.useState(preview),
51164
+ _useState18 = _slicedToArray(_useState17, 2),
51165
+ previewMode = _useState18[0],
51166
+ setPreviewMode = _useState18[1];
51045
51167
 
51046
51168
  /**
51047
51169
  * @param {String["layout", "workspace", "widget"]} editMode this is the actual mode we are in
51048
51170
  */
51049
- var _useState17 = React.useState("all"),
51050
- _useState18 = _slicedToArray(_useState17, 1),
51051
- editMode = _useState18[0]; // for the time being use "all" as our "old" way
51171
+ var _useState19 = React.useState("all"),
51172
+ _useState20 = _slicedToArray(_useState19, 1),
51173
+ editMode = _useState20[0]; // for the time being use "all" as our "old" way
51052
51174
 
51053
51175
  // Workspace Management (loading)
51054
- var _useState19 = React.useState(false),
51055
- _useState20 = _slicedToArray(_useState19, 2),
51056
- isLoadingWorkspaces = _useState20[0],
51057
- setIsLoadingWorkspaces = _useState20[1];
51058
51176
  var _useState21 = React.useState(false),
51059
51177
  _useState22 = _slicedToArray(_useState21, 2),
51060
- isLoadingMenuItems = _useState22[0],
51061
- setIsLoadingMenuItems = _useState22[1];
51062
- var _useState23 = React.useState([]),
51178
+ isLoadingWorkspaces = _useState22[0],
51179
+ setIsLoadingWorkspaces = _useState22[1];
51180
+ var _useState23 = React.useState(false),
51063
51181
  _useState24 = _slicedToArray(_useState23, 2),
51064
- menuItems = _useState24[0],
51065
- setMenuItems = _useState24[1];
51182
+ isLoadingMenuItems = _useState24[0],
51183
+ setIsLoadingMenuItems = _useState24[1];
51066
51184
  var _useState25 = React.useState([]),
51067
51185
  _useState26 = _slicedToArray(_useState25, 2),
51068
- workspaceConfig = _useState26[0],
51069
- setWorkspaceConfig = _useState26[1];
51186
+ menuItems = _useState26[0],
51187
+ setMenuItems = _useState26[1];
51188
+ var _useState27 = React.useState([]),
51189
+ _useState28 = _slicedToArray(_useState27, 2),
51190
+ workspaceConfig = _useState28[0],
51191
+ setWorkspaceConfig = _useState28[1];
51070
51192
 
51071
51193
  // Modal state
51072
- var _useState27 = React.useState(false),
51073
- _useState28 = _slicedToArray(_useState27, 2),
51074
- isThemeManagerOpen = _useState28[0],
51075
- setIsThemeManagerOpen = _useState28[1];
51076
51194
  var _useState29 = React.useState(false),
51077
51195
  _useState30 = _slicedToArray(_useState29, 2),
51078
- isDashboardLoaderOpen = _useState30[0],
51079
- setIsDashboardLoaderOpen = _useState30[1];
51196
+ isThemeManagerOpen = _useState30[0],
51197
+ setIsThemeManagerOpen = _useState30[1];
51080
51198
  var _useState31 = React.useState(false),
51081
51199
  _useState32 = _slicedToArray(_useState31, 2),
51082
- isLayoutPickerOpen = _useState32[0],
51083
- setIsLayoutPickerOpen = _useState32[1];
51200
+ isDashboardLoaderOpen = _useState32[0],
51201
+ setIsDashboardLoaderOpen = _useState32[1];
51084
51202
  var _useState33 = React.useState(false),
51085
51203
  _useState34 = _slicedToArray(_useState33, 2),
51086
- isWizardOpen = _useState34[0],
51087
- setIsWizardOpen = _useState34[1];
51204
+ isLayoutPickerOpen = _useState34[0],
51205
+ setIsLayoutPickerOpen = _useState34[1];
51206
+ var _useState35 = React.useState(false),
51207
+ _useState36 = _slicedToArray(_useState35, 2),
51208
+ isWizardOpen = _useState36[0],
51209
+ setIsWizardOpen = _useState36[1];
51088
51210
 
51089
51211
  // Missing widgets detection
51090
51212
  var _useMissingWidgets = useMissingWidgets(workspaceSelected),
51091
51213
  missingComponents = _useMissingWidgets.missingComponents,
51092
51214
  hasMissing = _useMissingWidgets.hasMissing;
51093
- var _useState35 = React.useState(false),
51094
- _useState36 = _slicedToArray(_useState35, 2),
51095
- isMissingWidgetsModalOpen = _useState36[0],
51096
- setIsMissingWidgetsModalOpen = _useState36[1];
51097
- var _useState37 = React.useState(new Set()),
51215
+ var _useState37 = React.useState(false),
51098
51216
  _useState38 = _slicedToArray(_useState37, 2),
51099
- dismissedMissingForWorkspace = _useState38[0],
51100
- setDismissedMissingForWorkspace = _useState38[1];
51217
+ isMissingWidgetsModalOpen = _useState38[0],
51218
+ setIsMissingWidgetsModalOpen = _useState38[1];
51219
+ var _useState39 = React.useState(new Set()),
51220
+ _useState40 = _slicedToArray(_useState39, 2),
51221
+ dismissedMissingForWorkspace = _useState40[0],
51222
+ setDismissedMissingForWorkspace = _useState40[1];
51101
51223
 
51102
51224
  // Unified App Settings Modal
51103
- var _useState39 = React.useState(false),
51104
- _useState40 = _slicedToArray(_useState39, 2),
51105
- isAppSettingsOpen = _useState40[0],
51106
- setIsAppSettingsOpen = _useState40[1];
51107
- var _useState41 = React.useState("dashboards"),
51225
+ var _useState41 = React.useState(false),
51108
51226
  _useState42 = _slicedToArray(_useState41, 2),
51109
- appSettingsInitialSection = _useState42[0],
51110
- setAppSettingsInitialSection = _useState42[1];
51111
- var _useState43 = React.useState(null),
51227
+ isAppSettingsOpen = _useState42[0],
51228
+ setIsAppSettingsOpen = _useState42[1];
51229
+ var _useState43 = React.useState("dashboards"),
51112
51230
  _useState44 = _slicedToArray(_useState43, 2),
51113
- appSettingsInitialProvider = _useState44[0],
51114
- setAppSettingsInitialProvider = _useState44[1];
51115
- var _useState45 = React.useState(false),
51231
+ appSettingsInitialSection = _useState44[0],
51232
+ setAppSettingsInitialSection = _useState44[1];
51233
+ var _useState45 = React.useState(null),
51116
51234
  _useState46 = _slicedToArray(_useState45, 2),
51117
- appSettingsCreateProvider = _useState46[0],
51118
- setAppSettingsCreateProvider = _useState46[1];
51235
+ appSettingsInitialProvider = _useState46[0],
51236
+ setAppSettingsInitialProvider = _useState46[1];
51237
+ var _useState47 = React.useState(false),
51238
+ _useState48 = _slicedToArray(_useState47, 2),
51239
+ appSettingsCreateProvider = _useState48[0],
51240
+ setAppSettingsCreateProvider = _useState48[1];
51119
51241
  function openAppSettings() {
51120
51242
  var section = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "general";
51121
51243
  var providerName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
@@ -51521,10 +51643,29 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
51521
51643
  }
51522
51644
 
51523
51645
  // ─── Page State ──────────────────────────────────────────────────
51524
- var _useState47 = React.useState(null),
51525
- _useState48 = _slicedToArray(_useState47, 2),
51526
- activePageId = _useState48[0],
51527
- setActivePageId = _useState48[1];
51646
+ var _useState49 = React.useState(null),
51647
+ _useState50 = _slicedToArray(_useState49, 2),
51648
+ activePageId = _useState50[0],
51649
+ setActivePageId = _useState50[1];
51650
+
51651
+ // Page history stack for goBack() — pushes the previous page id
51652
+ // whenever a navigation happens through navigateToPage().
51653
+ var pageHistoryRef = React.useRef([]);
51654
+
51655
+ // Wrapper that records history before switching pages.
51656
+ // Pass recordHistory=false to switch without recording (e.g. for goBack).
51657
+ var navigateToPage = React.useCallback(function (pageId) {
51658
+ var recordHistory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
51659
+ if (!pageId) return;
51660
+ if (recordHistory) {
51661
+ var _workspaceSelected$pa, _workspaceSelected$pa2;
51662
+ var prevId = activePageId || (workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.activePageId) || ((_workspaceSelected$pa = workspaceSelected === null || workspaceSelected === void 0 || (_workspaceSelected$pa2 = workspaceSelected.pages) === null || _workspaceSelected$pa2 === void 0 || (_workspaceSelected$pa2 = _workspaceSelected$pa2[0]) === null || _workspaceSelected$pa2 === void 0 ? void 0 : _workspaceSelected$pa2.id) !== null && _workspaceSelected$pa !== void 0 ? _workspaceSelected$pa : null);
51663
+ if (prevId && prevId !== pageId) {
51664
+ pageHistoryRef.current.push(prevId);
51665
+ }
51666
+ }
51667
+ setActivePageId(pageId);
51668
+ }, [activePageId, workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.activePageId, workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.pages]);
51528
51669
 
51529
51670
  // Listen for programmatic page switches via DashboardActionsApi
51530
51671
  React.useEffect(function () {
@@ -51533,20 +51674,63 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
51533
51674
  pageId = _ref4.pageId,
51534
51675
  pageName = _ref4.pageName;
51535
51676
  if (pageId) {
51536
- setActivePageId(pageId);
51677
+ navigateToPage(pageId);
51537
51678
  } else if (pageName) {
51538
51679
  var pages = (workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.pages) || [];
51539
51680
  var match = pages.find(function (p) {
51540
51681
  return p.name.toLowerCase() === pageName.toLowerCase();
51541
51682
  });
51542
- if (match) setActivePageId(match.id);
51683
+ if (match) navigateToPage(match.id);
51543
51684
  }
51544
51685
  }
51545
51686
  window.addEventListener("dash:switch-page", onSwitchPage);
51546
51687
  return function () {
51547
51688
  return window.removeEventListener("dash:switch-page", onSwitchPage);
51548
51689
  };
51549
- }, [workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.pages]);
51690
+ }, [workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.pages, navigateToPage]);
51691
+
51692
+ // Listen for runtime UX actions: goBack, sidebar control, notify
51693
+ React.useEffect(function () {
51694
+ function onGoBack() {
51695
+ var prev = pageHistoryRef.current.pop();
51696
+ if (prev) setActivePageId(prev); // bypass history recording
51697
+ }
51698
+ function onSetNavSidebar(e) {
51699
+ var _e$detail;
51700
+ setSidebarCollapsed(!!((_e$detail = e.detail) !== null && _e$detail !== void 0 && _e$detail.collapsed));
51701
+ }
51702
+ function onToggleNavSidebar() {
51703
+ setSidebarCollapsed(function (c) {
51704
+ return !c;
51705
+ });
51706
+ }
51707
+ function onNotify(e) {
51708
+ var id = "".concat(Date.now(), "-").concat(Math.random());
51709
+ var toast = _objectSpread$5({
51710
+ id: id
51711
+ }, e.detail || {});
51712
+ setToasts(function (prev) {
51713
+ return [].concat(_toConsumableArray(prev), [toast]);
51714
+ });
51715
+ setTimeout(function () {
51716
+ setToasts(function (prev) {
51717
+ return prev.filter(function (t) {
51718
+ return t.id !== id;
51719
+ });
51720
+ });
51721
+ }, toast.duration || 4000);
51722
+ }
51723
+ window.addEventListener("dash:go-back", onGoBack);
51724
+ window.addEventListener("dash:set-nav-sidebar", onSetNavSidebar);
51725
+ window.addEventListener("dash:toggle-nav-sidebar", onToggleNavSidebar);
51726
+ window.addEventListener("dash:notify", onNotify);
51727
+ return function () {
51728
+ window.removeEventListener("dash:go-back", onGoBack);
51729
+ window.removeEventListener("dash:set-nav-sidebar", onSetNavSidebar);
51730
+ window.removeEventListener("dash:toggle-nav-sidebar", onToggleNavSidebar);
51731
+ window.removeEventListener("dash:notify", onNotify);
51732
+ };
51733
+ }, []);
51550
51734
  var workspacePages = (workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.pages) || [];
51551
51735
 
51552
51736
  // Memoize sorted pages so page object references stay stable across re-renders
@@ -51562,6 +51746,71 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
51562
51746
  return "".concat(p.id, ":").concat(p.order, ":").concat(p.name);
51563
51747
  }).join(",")]);
51564
51748
  var currentActivePageId = activePageId || (workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.activePageId) || ((_workspacePages$0$id = (_workspacePages$ = workspacePages[0]) === null || _workspacePages$ === void 0 ? void 0 : _workspacePages$.id) !== null && _workspacePages$0$id !== void 0 ? _workspacePages$0$id : null);
51749
+
51750
+ // Stable refs for tab/dashboard handlers so the open/close-dashboard
51751
+ // listener doesn't have to re-subscribe on every render.
51752
+ var handleOpenTabRef = React.useRef(null);
51753
+ var handleCloseTabRef = React.useRef(null);
51754
+ var workspaceConfigRef = React.useRef([]);
51755
+ var openTabsRef = React.useRef([]);
51756
+ var activeTabIdRef = React.useRef(null);
51757
+ handleOpenTabRef.current = handleOpenTab;
51758
+ handleCloseTabRef.current = handleCloseTab;
51759
+ workspaceConfigRef.current = workspaceConfig;
51760
+ openTabsRef.current = openTabs;
51761
+ activeTabIdRef.current = activeTabId;
51762
+
51763
+ // Listen for open/close dashboard actions via DashboardActionsApi
51764
+ React.useEffect(function () {
51765
+ function onOpen(e) {
51766
+ var _e$detail2;
51767
+ var name = (_e$detail2 = e.detail) === null || _e$detail2 === void 0 ? void 0 : _e$detail2.name;
51768
+ if (!name) return;
51769
+ var ws = (workspaceConfigRef.current || []).find(function (w) {
51770
+ return (w.name || "").toLowerCase() === name.toLowerCase();
51771
+ });
51772
+ if (ws && handleOpenTabRef.current) handleOpenTabRef.current(ws);
51773
+ }
51774
+ function onClose(e) {
51775
+ var _e$detail3;
51776
+ var name = (_e$detail3 = e.detail) === null || _e$detail3 === void 0 ? void 0 : _e$detail3.name;
51777
+ if (name) {
51778
+ var tab = (openTabsRef.current || []).find(function (t) {
51779
+ return (t.name || "").toLowerCase() === name.toLowerCase();
51780
+ });
51781
+ if (tab && handleCloseTabRef.current) handleCloseTabRef.current(tab.id);
51782
+ } else if (activeTabIdRef.current && handleCloseTabRef.current) {
51783
+ handleCloseTabRef.current(activeTabIdRef.current);
51784
+ }
51785
+ }
51786
+ window.addEventListener("dash:open-dashboard", onOpen);
51787
+ window.addEventListener("dash:close-dashboard", onClose);
51788
+ return function () {
51789
+ window.removeEventListener("dash:open-dashboard", onOpen);
51790
+ window.removeEventListener("dash:close-dashboard", onClose);
51791
+ };
51792
+ }, []);
51793
+
51794
+ // Maintain window.__dashState so DashboardActionsApi read methods
51795
+ // (getCurrentPageName, listPages, etc.) return up-to-date values.
51796
+ React.useEffect(function () {
51797
+ var activePage = workspacePages.find(function (p) {
51798
+ return p.id === currentActivePageId;
51799
+ });
51800
+ window.__dashState = {
51801
+ currentPageId: currentActivePageId,
51802
+ currentPageName: (activePage === null || activePage === void 0 ? void 0 : activePage.name) || null,
51803
+ currentDashboardId: (workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.id) || null,
51804
+ currentDashboardName: (workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.name) || null,
51805
+ pages: workspacePages.map(function (p) {
51806
+ return {
51807
+ id: p.id,
51808
+ name: p.name,
51809
+ order: p.order
51810
+ };
51811
+ })
51812
+ };
51813
+ }, [currentActivePageId, workspacePages, workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.id, workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.name]);
51565
51814
  function handleAddPage() {
51566
51815
  if (!workspaceSelected) return;
51567
51816
  var existingPages = _toConsumableArray(workspacePages);
@@ -51575,7 +51824,7 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
51575
51824
  handleWorkspaceChange(updatedWorkspace);
51576
51825
  }
51577
51826
  function handleSwitchPage(pageId) {
51578
- setActivePageId(pageId);
51827
+ navigateToPage(pageId);
51579
51828
  }
51580
51829
  function handleRenamePage(pageId, newName) {
51581
51830
  if (!workspaceSelected) return;
@@ -52046,7 +52295,25 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
52046
52295
  direction: "col",
52047
52296
  scrollable: false,
52048
52297
  grow: true,
52049
- children: [/*#__PURE__*/jsxRuntime.jsxs(reactDnd.DndProvider, {
52298
+ children: [toasts.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
52299
+ className: "fixed bottom-4 right-4 z-[9999] flex flex-col gap-2 pointer-events-none",
52300
+ children: toasts.map(function (t) {
52301
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
52302
+ className: "pointer-events-auto",
52303
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Toast, {
52304
+ title: t.title,
52305
+ message: t.message,
52306
+ onClose: function onClose() {
52307
+ return setToasts(function (prev) {
52308
+ return prev.filter(function (x) {
52309
+ return x.id !== t.id;
52310
+ });
52311
+ });
52312
+ }
52313
+ })
52314
+ }, t.id);
52315
+ })
52316
+ }), /*#__PURE__*/jsxRuntime.jsxs(reactDnd.DndProvider, {
52050
52317
  backend: reactDndHtml5Backend.HTML5Backend,
52051
52318
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
52052
52319
  className: "flex flex-row flex-1 overflow-hidden",