@trops/dash-core 0.1.109 → 0.1.110

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
@@ -39038,17 +39038,22 @@ var DashSidebar = function DashSidebar(_ref) {
39038
39038
  menuItems = _ref$menuItems === void 0 ? [] : _ref$menuItems,
39039
39039
  _ref$activeTabId = _ref.activeTabId,
39040
39040
  activeTabId = _ref$activeTabId === void 0 ? null : _ref$activeTabId,
39041
+ _ref$recentDashboards = _ref.recentDashboards,
39042
+ recentDashboards = _ref$recentDashboards === void 0 ? [] : _ref$recentDashboards,
39043
+ _ref$authStatus = _ref.authStatus,
39044
+ authStatus = _ref$authStatus === void 0 ? "loading" : _ref$authStatus,
39045
+ _ref$authProfile = _ref.authProfile,
39046
+ authProfile = _ref$authProfile === void 0 ? null : _ref$authProfile,
39041
39047
  onOpenWorkspace = _ref.onOpenWorkspace,
39042
39048
  onNewDashboard = _ref.onNewDashboard,
39043
- onGoHome = _ref.onGoHome,
39044
- onOpenProviders = _ref.onOpenProviders,
39045
- onOpenThemeManager = _ref.onOpenThemeManager,
39046
- onOpenFolders = _ref.onOpenFolders,
39047
39049
  onOpenSettings = _ref.onOpenSettings,
39048
- onOpenCommandPalette = _ref.onOpenCommandPalette;
39050
+ onOpenCommandPalette = _ref.onOpenCommandPalette,
39051
+ onSignIn = _ref.onSignIn,
39052
+ onSignOut = _ref.onSignOut;
39049
39053
  var _useContext = React.useContext(DashReact.ThemeContext),
39050
39054
  themeVariant = _useContext.themeVariant,
39051
39055
  changeThemeVariant = _useContext.changeThemeVariant;
39056
+ _useContext.currentTheme;
39052
39057
  var workspacesForFolder = function workspacesForFolder(folderId) {
39053
39058
  return workspaces.filter(function (ws) {
39054
39059
  return ws.menuId === folderId;
@@ -39059,6 +39064,13 @@ var DashSidebar = function DashSidebar(_ref) {
39059
39064
  return mi.id === ws.menuId;
39060
39065
  });
39061
39066
  });
39067
+
39068
+ // Filter recents: only show workspaces that still exist, max 5
39069
+ var visibleRecents = recentDashboards.filter(function (r) {
39070
+ return workspaces.some(function (ws) {
39071
+ return ws.id === r.workspaceId;
39072
+ });
39073
+ }).slice(0, 5);
39062
39074
  return /*#__PURE__*/jsxRuntime.jsxs(DashReact.Sidebar, {
39063
39075
  collapsed: collapsed,
39064
39076
  onCollapsedChange: onCollapsedChange,
@@ -39074,57 +39086,32 @@ var DashSidebar = function DashSidebar(_ref) {
39074
39086
  })
39075
39087
  }), /*#__PURE__*/jsxRuntime.jsxs(DashReact.Sidebar.Content, {
39076
39088
  children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
39077
- icon: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
39078
- icon: "home",
39079
- className: "h-3.5 w-3.5"
39080
- }),
39081
- active: activeTabId === null,
39082
- onClick: onGoHome,
39083
- children: "Home"
39084
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
39085
39089
  icon: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
39086
39090
  icon: "magnifying-glass",
39087
39091
  className: "h-3.5 w-3.5"
39088
39092
  }),
39089
39093
  onClick: onOpenCommandPalette,
39090
39094
  children: "Search"
39091
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
39092
- icon: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
39093
- icon: "plug",
39094
- className: "h-3.5 w-3.5"
39095
- }),
39096
- onClick: onOpenProviders,
39097
- children: "Providers"
39098
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
39099
- icon: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
39100
- icon: "palette",
39101
- className: "h-3.5 w-3.5"
39102
- }),
39103
- onClick: onOpenThemeManager,
39104
- children: "Themes"
39105
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
39106
- icon: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
39107
- icon: "folder",
39108
- className: "h-3.5 w-3.5"
39109
- }),
39110
- onClick: onOpenFolders,
39111
- children: "Folders"
39112
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
39113
- icon: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
39114
- icon: "cog",
39115
- className: "h-3.5 w-3.5"
39116
- }),
39117
- onClick: onOpenSettings,
39118
- children: "Settings"
39119
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
39120
- icon: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
39121
- icon: themeVariant === "dark" ? "sun" : "moon",
39122
- className: "h-3.5 w-3.5"
39123
- }),
39124
- onClick: function onClick() {
39125
- return changeThemeVariant(themeVariant === "dark" ? "light" : "dark");
39126
- },
39127
- children: themeVariant === "dark" ? "Light Mode" : "Dark Mode"
39095
+ }), !collapsed && visibleRecents.length > 0 && /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Group, {
39096
+ label: "Recents",
39097
+ children: visibleRecents.map(function (recent) {
39098
+ var ws = workspaces.find(function (w) {
39099
+ return w.id === recent.workspaceId;
39100
+ });
39101
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
39102
+ icon: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
39103
+ icon: "clock-rotate-left",
39104
+ className: "h-3.5 w-3.5"
39105
+ }),
39106
+ active: recent.workspaceId === activeTabId,
39107
+ onClick: function onClick() {
39108
+ return ws && onOpenWorkspace(ws);
39109
+ },
39110
+ children: (recent.name || "Untitled").replace(/^./, function (c) {
39111
+ return c.toUpperCase();
39112
+ })
39113
+ }, recent.workspaceId);
39114
+ })
39128
39115
  }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Group, {
39129
39116
  label: "Dashboards",
39130
39117
  children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
@@ -39177,6 +39164,107 @@ var DashSidebar = function DashSidebar(_ref) {
39177
39164
  })
39178
39165
  })]
39179
39166
  })]
39167
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Footer, {
39168
+ children: /*#__PURE__*/jsxRuntime.jsx(FooterPopover, {
39169
+ collapsed: collapsed,
39170
+ themeVariant: themeVariant,
39171
+ changeThemeVariant: changeThemeVariant,
39172
+ authStatus: authStatus,
39173
+ authProfile: authProfile,
39174
+ onOpenSettings: onOpenSettings,
39175
+ onSignIn: onSignIn,
39176
+ onSignOut: onSignOut
39177
+ })
39178
+ })]
39179
+ });
39180
+ };
39181
+ var FooterPopover = function FooterPopover(_ref2) {
39182
+ var collapsed = _ref2.collapsed,
39183
+ themeVariant = _ref2.themeVariant,
39184
+ changeThemeVariant = _ref2.changeThemeVariant,
39185
+ authStatus = _ref2.authStatus,
39186
+ authProfile = _ref2.authProfile,
39187
+ onOpenSettings = _ref2.onOpenSettings,
39188
+ onSignIn = _ref2.onSignIn,
39189
+ onSignOut = _ref2.onSignOut;
39190
+ var displayName = authStatus === "authenticated" && authProfile ? authProfile.displayName || authProfile.username : "Account";
39191
+ return /*#__PURE__*/jsxRuntime.jsx(react.Popover, {
39192
+ className: "relative",
39193
+ children: function children(_ref3) {
39194
+ var close = _ref3.close;
39195
+ return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
39196
+ children: [/*#__PURE__*/jsxRuntime.jsxs(react.Popover.Button, {
39197
+ className: "flex items-center w-full gap-2 px-3 py-2 rounded-md text-sm opacity-80 hover:opacity-100 transition-colors duration-150 cursor-pointer hover:bg-white/5 focus:outline-none",
39198
+ title: collapsed ? displayName : undefined,
39199
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
39200
+ icon: authStatus === "authenticated" ? "circle-user" : "user",
39201
+ className: "h-3.5 w-3.5 flex-shrink-0"
39202
+ }), !collapsed && /*#__PURE__*/jsxRuntime.jsx("span", {
39203
+ className: "flex-1 text-left truncate",
39204
+ children: displayName
39205
+ })]
39206
+ }), /*#__PURE__*/jsxRuntime.jsx(react.Transition, {
39207
+ enter: "transition ease-out duration-100",
39208
+ enterFrom: "transform opacity-0 scale-95",
39209
+ enterTo: "transform opacity-100 scale-100",
39210
+ leave: "transition ease-in duration-75",
39211
+ leaveFrom: "transform opacity-100 scale-100",
39212
+ leaveTo: "transform opacity-0 scale-95",
39213
+ children: /*#__PURE__*/jsxRuntime.jsx(react.Popover.Panel, {
39214
+ className: "absolute bottom-full left-0 mb-2 w-52 rounded-lg border border-white/10 bg-neutral-900 shadow-xl z-50",
39215
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
39216
+ className: "p-1.5 space-y-0.5",
39217
+ children: [/*#__PURE__*/jsxRuntime.jsx(PopoverItem, {
39218
+ icon: "cog",
39219
+ label: "Settings",
39220
+ onClick: function onClick() {
39221
+ onOpenSettings();
39222
+ close();
39223
+ }
39224
+ }), /*#__PURE__*/jsxRuntime.jsx(PopoverItem, {
39225
+ icon: themeVariant === "dark" ? "sun" : "moon",
39226
+ label: themeVariant === "dark" ? "Light Mode" : "Dark Mode",
39227
+ onClick: function onClick() {
39228
+ changeThemeVariant(themeVariant === "dark" ? "light" : "dark");
39229
+ close();
39230
+ }
39231
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
39232
+ className: "border-t border-white/10 my-1"
39233
+ }), authStatus === "authenticated" ? /*#__PURE__*/jsxRuntime.jsx(PopoverItem, {
39234
+ icon: "right-from-bracket",
39235
+ label: "Sign Out",
39236
+ onClick: function onClick() {
39237
+ onSignOut();
39238
+ close();
39239
+ }
39240
+ }) : /*#__PURE__*/jsxRuntime.jsx(PopoverItem, {
39241
+ icon: "right-to-bracket",
39242
+ label: "Sign In",
39243
+ onClick: function onClick() {
39244
+ onSignIn();
39245
+ close();
39246
+ }
39247
+ })]
39248
+ })
39249
+ })
39250
+ })]
39251
+ });
39252
+ }
39253
+ });
39254
+ };
39255
+ var PopoverItem = function PopoverItem(_ref4) {
39256
+ var icon = _ref4.icon,
39257
+ label = _ref4.label,
39258
+ onClick = _ref4.onClick;
39259
+ return /*#__PURE__*/jsxRuntime.jsxs("button", {
39260
+ type: "button",
39261
+ onClick: onClick,
39262
+ className: "flex items-center w-full gap-2 px-3 py-2 rounded-md text-sm text-white/80 hover:text-white hover:bg-white/10 transition-colors duration-150 cursor-pointer",
39263
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
39264
+ icon: icon,
39265
+ className: "h-3.5 w-3.5 flex-shrink-0"
39266
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
39267
+ children: label
39180
39268
  })]
39181
39269
  });
39182
39270
  };
@@ -39931,6 +40019,23 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
39931
40019
  widgetSidebarCollapsed = _useState0[0],
39932
40020
  setWidgetSidebarCollapsed = _useState0[1];
39933
40021
 
40022
+ // ─── Recents + Session ──────────────────────────────────────────
40023
+ var _useState1 = React.useState([]),
40024
+ _useState10 = _slicedToArray(_useState1, 2),
40025
+ recentDashboards = _useState10[0],
40026
+ setRecentDashboards = _useState10[1];
40027
+ var sessionRestored = React.useRef(false);
40028
+
40029
+ // ─── Registry Auth (for sidebar) ────────────────────────────────
40030
+ var _useState11 = React.useState("loading"),
40031
+ _useState12 = _slicedToArray(_useState11, 2),
40032
+ authStatus = _useState12[0],
40033
+ setAuthStatus = _useState12[1];
40034
+ var _useState13 = React.useState(null),
40035
+ _useState14 = _slicedToArray(_useState13, 2),
40036
+ authProfile = _useState14[0],
40037
+ setAuthProfile = _useState14[1];
40038
+
39934
40039
  // Derive workspaceSelected from active tab
39935
40040
  var workspaceSelected = activeTabId ? (_openTabs$find$worksp = (_openTabs$find = openTabs.find(function (tab) {
39936
40041
  return tab.id === activeTabId;
@@ -39939,66 +40044,92 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
39939
40044
  /**
39940
40045
  * @param {Boolean} previewMode this is a toggle telling the dash we are editing
39941
40046
  */
39942
- var _useState1 = React.useState(preview),
39943
- _useState10 = _slicedToArray(_useState1, 2),
39944
- previewMode = _useState10[0],
39945
- setPreviewMode = _useState10[1];
40047
+ var _useState15 = React.useState(preview),
40048
+ _useState16 = _slicedToArray(_useState15, 2),
40049
+ previewMode = _useState16[0],
40050
+ setPreviewMode = _useState16[1];
39946
40051
 
39947
40052
  /**
39948
40053
  * @param {String["layout", "workspace", "widget"]} editMode this is the actual mode we are in
39949
40054
  */
39950
- var _useState11 = React.useState("all"),
39951
- _useState12 = _slicedToArray(_useState11, 1),
39952
- editMode = _useState12[0]; // for the time being use "all" as our "old" way
40055
+ var _useState17 = React.useState("all"),
40056
+ _useState18 = _slicedToArray(_useState17, 1),
40057
+ editMode = _useState18[0]; // for the time being use "all" as our "old" way
39953
40058
 
39954
40059
  // Workspace Management (loading)
39955
- var _useState13 = React.useState(false),
39956
- _useState14 = _slicedToArray(_useState13, 2),
39957
- isLoadingWorkspaces = _useState14[0],
39958
- setIsLoadingWorkspaces = _useState14[1];
39959
- var _useState15 = React.useState(false),
39960
- _useState16 = _slicedToArray(_useState15, 2),
39961
- isLoadingMenuItems = _useState16[0],
39962
- setIsLoadingMenuItems = _useState16[1];
39963
- var _useState17 = React.useState([]),
39964
- _useState18 = _slicedToArray(_useState17, 2),
39965
- menuItems = _useState18[0],
39966
- setMenuItems = _useState18[1];
39967
- var _useState19 = React.useState([]),
40060
+ var _useState19 = React.useState(false),
39968
40061
  _useState20 = _slicedToArray(_useState19, 2),
39969
- workspaceConfig = _useState20[0],
39970
- setWorkspaceConfig = _useState20[1];
39971
-
39972
- // Modal state
40062
+ isLoadingWorkspaces = _useState20[0],
40063
+ setIsLoadingWorkspaces = _useState20[1];
39973
40064
  var _useState21 = React.useState(false),
39974
40065
  _useState22 = _slicedToArray(_useState21, 2),
39975
- isThemeManagerOpen = _useState22[0],
39976
- setIsThemeManagerOpen = _useState22[1];
39977
- var _useState23 = React.useState(false),
40066
+ isLoadingMenuItems = _useState22[0],
40067
+ setIsLoadingMenuItems = _useState22[1];
40068
+ var _useState23 = React.useState([]),
39978
40069
  _useState24 = _slicedToArray(_useState23, 2),
39979
- isDashboardLoaderOpen = _useState24[0],
39980
- setIsDashboardLoaderOpen = _useState24[1];
39981
- var _useState25 = React.useState(false),
40070
+ menuItems = _useState24[0],
40071
+ setMenuItems = _useState24[1];
40072
+ var _useState25 = React.useState([]),
39982
40073
  _useState26 = _slicedToArray(_useState25, 2),
39983
- isLayoutPickerOpen = _useState26[0],
39984
- setIsLayoutPickerOpen = _useState26[1];
40074
+ workspaceConfig = _useState26[0],
40075
+ setWorkspaceConfig = _useState26[1];
39985
40076
 
39986
- // Unified App Settings Modal
40077
+ // Modal state
39987
40078
  var _useState27 = React.useState(false),
39988
40079
  _useState28 = _slicedToArray(_useState27, 2),
39989
- isAppSettingsOpen = _useState28[0],
39990
- setIsAppSettingsOpen = _useState28[1];
39991
- var _useState29 = React.useState("dashboards"),
40080
+ isThemeManagerOpen = _useState28[0],
40081
+ setIsThemeManagerOpen = _useState28[1];
40082
+ var _useState29 = React.useState(false),
39992
40083
  _useState30 = _slicedToArray(_useState29, 2),
39993
- appSettingsInitialSection = _useState30[0],
39994
- setAppSettingsInitialSection = _useState30[1];
40084
+ isDashboardLoaderOpen = _useState30[0],
40085
+ setIsDashboardLoaderOpen = _useState30[1];
40086
+ var _useState31 = React.useState(false),
40087
+ _useState32 = _slicedToArray(_useState31, 2),
40088
+ isLayoutPickerOpen = _useState32[0],
40089
+ setIsLayoutPickerOpen = _useState32[1];
40090
+
40091
+ // Unified App Settings Modal
40092
+ var _useState33 = React.useState(false),
40093
+ _useState34 = _slicedToArray(_useState33, 2),
40094
+ isAppSettingsOpen = _useState34[0],
40095
+ setIsAppSettingsOpen = _useState34[1];
40096
+ var _useState35 = React.useState("dashboards"),
40097
+ _useState36 = _slicedToArray(_useState35, 2),
40098
+ appSettingsInitialSection = _useState36[0],
40099
+ setAppSettingsInitialSection = _useState36[1];
39995
40100
  function openAppSettings() {
39996
- var section = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "dashboards";
40101
+ var section = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "general";
39997
40102
  setAppSettingsInitialSection(section);
39998
40103
  setIsAppSettingsOpen(true);
39999
40104
  }
40000
-
40001
- // Ref to access LayoutBuilder's current workspace without re-render cascades
40105
+ function handleProfileUpdated() {
40106
+ return _handleProfileUpdated.apply(this, arguments);
40107
+ } // Ref to access LayoutBuilder's current workspace without re-render cascades
40108
+ function _handleProfileUpdated() {
40109
+ _handleProfileUpdated = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
40110
+ var _window$mainApi11, profile;
40111
+ return _regeneratorRuntime.wrap(function (_context2) {
40112
+ while (1) switch (_context2.prev = _context2.next) {
40113
+ case 0:
40114
+ _context2.prev = 0;
40115
+ _context2.next = 1;
40116
+ return (_window$mainApi11 = window.mainApi) === null || _window$mainApi11 === void 0 || (_window$mainApi11 = _window$mainApi11.registryAuth) === null || _window$mainApi11 === void 0 ? void 0 : _window$mainApi11.getProfile();
40117
+ case 1:
40118
+ profile = _context2.sent;
40119
+ if (profile) setAuthProfile(profile);
40120
+ _context2.next = 3;
40121
+ break;
40122
+ case 2:
40123
+ _context2.prev = 2;
40124
+ _context2["catch"](0);
40125
+ case 3:
40126
+ case "end":
40127
+ return _context2.stop();
40128
+ }
40129
+ }, _callee2, null, [[0, 2]]);
40130
+ }));
40131
+ return _handleProfileUpdated.apply(this, arguments);
40132
+ }
40002
40133
  var currentWorkspaceRef = React.useRef(null);
40003
40134
 
40004
40135
  // Snapshot of the workspace before editing — used to restore on Cancel
@@ -40044,6 +40175,114 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
40044
40175
  // eslint-disable-next-line react-hooks/exhaustive-deps
40045
40176
  }, [popout]);
40046
40177
 
40178
+ // ─── Load recents on mount ───────────────────────────────────────
40179
+ React.useEffect(function () {
40180
+ var _window$mainApi4;
40181
+ if (popout) return;
40182
+ (_window$mainApi4 = window.mainApi) === null || _window$mainApi4 === void 0 || (_window$mainApi4 = _window$mainApi4.session) === null || _window$mainApi4 === void 0 || _window$mainApi4.getRecents().then(function (recents) {
40183
+ if (recents) setRecentDashboards(recents);
40184
+ });
40185
+ }, [popout]);
40186
+
40187
+ // ─── Session save (continuous) ──────────────────────────────────
40188
+ React.useEffect(function () {
40189
+ var _window$mainApi5;
40190
+ if (popout) return;
40191
+ var tabIds = openTabs.map(function (t) {
40192
+ return t.id;
40193
+ });
40194
+ (_window$mainApi5 = window.mainApi) === null || _window$mainApi5 === void 0 || (_window$mainApi5 = _window$mainApi5.session) === null || _window$mainApi5 === void 0 || _window$mainApi5.saveState(tabIds, activeTabId);
40195
+ }, [openTabs, activeTabId, popout]);
40196
+
40197
+ // ─── Session restore on launch ─────────────────────────────────
40198
+ React.useEffect(function () {
40199
+ var _window$mainApi6;
40200
+ if (popout || workspaceConfig.length === 0 || sessionRestored.current) return;
40201
+ sessionRestored.current = true;
40202
+ (_window$mainApi6 = window.mainApi) === null || _window$mainApi6 === void 0 || (_window$mainApi6 = _window$mainApi6.session) === null || _window$mainApi6 === void 0 || _window$mainApi6.getState().then(function (state) {
40203
+ var _state$openTabIds, _window$mainApi7;
40204
+ if (!(state !== null && state !== void 0 && (_state$openTabIds = state.openTabIds) !== null && _state$openTabIds !== void 0 && _state$openTabIds.length)) return;
40205
+ state.openTabIds.forEach(function (wsId) {
40206
+ var ws = workspaceConfig.find(function (w) {
40207
+ return w.id === wsId;
40208
+ });
40209
+ if (ws) handleOpenTab(ws);
40210
+ });
40211
+ if (state.activeTabId) setActiveTabId(state.activeTabId);
40212
+ (_window$mainApi7 = window.mainApi) === null || _window$mainApi7 === void 0 || (_window$mainApi7 = _window$mainApi7.session) === null || _window$mainApi7 === void 0 || _window$mainApi7.clearState();
40213
+ });
40214
+ // eslint-disable-next-line react-hooks/exhaustive-deps
40215
+ }, [workspaceConfig, popout]);
40216
+
40217
+ // ─── Auth status check (for sidebar) ────────────────────────────
40218
+ React.useEffect(function () {
40219
+ if (popout) return;
40220
+ var cancelled = false;
40221
+ function checkAuth() {
40222
+ return _checkAuth.apply(this, arguments);
40223
+ }
40224
+ function _checkAuth() {
40225
+ _checkAuth = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
40226
+ var _window$mainApi8, status, _window$mainApi9, profile;
40227
+ return _regeneratorRuntime.wrap(function (_context) {
40228
+ while (1) switch (_context.prev = _context.next) {
40229
+ case 0:
40230
+ _context.prev = 0;
40231
+ _context.next = 1;
40232
+ return (_window$mainApi8 = window.mainApi) === null || _window$mainApi8 === void 0 || (_window$mainApi8 = _window$mainApi8.registryAuth) === null || _window$mainApi8 === void 0 ? void 0 : _window$mainApi8.getStatus();
40233
+ case 1:
40234
+ status = _context.sent;
40235
+ if (!cancelled) {
40236
+ _context.next = 2;
40237
+ break;
40238
+ }
40239
+ return _context.abrupt("return");
40240
+ case 2:
40241
+ if (!(status !== null && status !== void 0 && status.authenticated)) {
40242
+ _context.next = 5;
40243
+ break;
40244
+ }
40245
+ _context.next = 3;
40246
+ return (_window$mainApi9 = window.mainApi) === null || _window$mainApi9 === void 0 || (_window$mainApi9 = _window$mainApi9.registryAuth) === null || _window$mainApi9 === void 0 ? void 0 : _window$mainApi9.getProfile();
40247
+ case 3:
40248
+ profile = _context.sent;
40249
+ if (!cancelled) {
40250
+ _context.next = 4;
40251
+ break;
40252
+ }
40253
+ return _context.abrupt("return");
40254
+ case 4:
40255
+ if (profile) {
40256
+ setAuthProfile(profile);
40257
+ setAuthStatus("authenticated");
40258
+ } else {
40259
+ setAuthStatus("unauthenticated");
40260
+ }
40261
+ _context.next = 6;
40262
+ break;
40263
+ case 5:
40264
+ setAuthStatus("unauthenticated");
40265
+ case 6:
40266
+ _context.next = 8;
40267
+ break;
40268
+ case 7:
40269
+ _context.prev = 7;
40270
+ _context["catch"](0);
40271
+ if (!cancelled) setAuthStatus("unauthenticated");
40272
+ case 8:
40273
+ case "end":
40274
+ return _context.stop();
40275
+ }
40276
+ }, _callee, null, [[0, 7]]);
40277
+ }));
40278
+ return _checkAuth.apply(this, arguments);
40279
+ }
40280
+ checkAuth();
40281
+ return function () {
40282
+ cancelled = true;
40283
+ };
40284
+ }, [popout]);
40285
+
40047
40286
  // ─── Tab Handlers ─────────────────────────────────────────────────
40048
40287
 
40049
40288
  function handleOpenTab(workspaceItem) {
@@ -40076,6 +40315,14 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
40076
40315
  }
40077
40316
  setPreviewMode(true);
40078
40317
  setSidebarCollapsed(true);
40318
+
40319
+ // Track in recents
40320
+ if (!popout) {
40321
+ var _window$mainApi0;
40322
+ (_window$mainApi0 = window.mainApi) === null || _window$mainApi0 === void 0 || (_window$mainApi0 = _window$mainApi0.session) === null || _window$mainApi0 === void 0 || _window$mainApi0.addRecent(workspaceItem.id, workspaceItem.name || "Untitled").then(function (updated) {
40323
+ if (updated) setRecentDashboards(updated);
40324
+ });
40325
+ }
40079
40326
  }
40080
40327
  function handleCloseTab(tabId) {
40081
40328
  setOpenTabs(function (prev) {
@@ -40428,15 +40675,113 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
40428
40675
  function handleToggleThemeVariant() {
40429
40676
  changeThemeVariant(themeVariant === "dark" ? "light" : "dark");
40430
40677
  }
40678
+ function handleSidebarSignIn() {
40679
+ return _handleSidebarSignIn.apply(this, arguments);
40680
+ }
40681
+ function _handleSidebarSignIn() {
40682
+ _handleSidebarSignIn = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
40683
+ var flow, interval, poll;
40684
+ return _regeneratorRuntime.wrap(function (_context4) {
40685
+ while (1) switch (_context4.prev = _context4.next) {
40686
+ case 0:
40687
+ _context4.prev = 0;
40688
+ _context4.next = 1;
40689
+ return window.mainApi.registryAuth.initiateLogin();
40690
+ case 1:
40691
+ flow = _context4.sent;
40692
+ if (flow.verificationUrlComplete) {
40693
+ window.mainApi.shell.openExternal(flow.verificationUrlComplete);
40694
+ }
40695
+ interval = (flow.interval || 5) * 1000;
40696
+ poll = setInterval(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
40697
+ var result, profile;
40698
+ return _regeneratorRuntime.wrap(function (_context3) {
40699
+ while (1) switch (_context3.prev = _context3.next) {
40700
+ case 0:
40701
+ _context3.prev = 0;
40702
+ _context3.next = 1;
40703
+ return window.mainApi.registryAuth.pollToken(flow.deviceCode);
40704
+ case 1:
40705
+ result = _context3.sent;
40706
+ if (!(result.status === "authorized")) {
40707
+ _context3.next = 3;
40708
+ break;
40709
+ }
40710
+ clearInterval(poll);
40711
+ _context3.next = 2;
40712
+ return window.mainApi.registryAuth.getProfile();
40713
+ case 2:
40714
+ profile = _context3.sent;
40715
+ setAuthProfile(profile);
40716
+ setAuthStatus("authenticated");
40717
+ _context3.next = 4;
40718
+ break;
40719
+ case 3:
40720
+ if (result.status === "expired") {
40721
+ clearInterval(poll);
40722
+ }
40723
+ case 4:
40724
+ _context3.next = 6;
40725
+ break;
40726
+ case 5:
40727
+ _context3.prev = 5;
40728
+ _context3["catch"](0);
40729
+ clearInterval(poll);
40730
+ case 6:
40731
+ case "end":
40732
+ return _context3.stop();
40733
+ }
40734
+ }, _callee3, null, [[0, 5]]);
40735
+ })), interval);
40736
+ _context4.next = 3;
40737
+ break;
40738
+ case 2:
40739
+ _context4.prev = 2;
40740
+ _context4["catch"](0);
40741
+ case 3:
40742
+ case "end":
40743
+ return _context4.stop();
40744
+ }
40745
+ }, _callee4, null, [[0, 2]]);
40746
+ }));
40747
+ return _handleSidebarSignIn.apply(this, arguments);
40748
+ }
40749
+ function handleSidebarSignOut() {
40750
+ return _handleSidebarSignOut.apply(this, arguments);
40751
+ }
40752
+ function _handleSidebarSignOut() {
40753
+ _handleSidebarSignOut = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5() {
40754
+ return _regeneratorRuntime.wrap(function (_context5) {
40755
+ while (1) switch (_context5.prev = _context5.next) {
40756
+ case 0:
40757
+ _context5.prev = 0;
40758
+ _context5.next = 1;
40759
+ return window.mainApi.registryAuth.logout();
40760
+ case 1:
40761
+ setAuthStatus("unauthenticated");
40762
+ setAuthProfile(null);
40763
+ _context5.next = 3;
40764
+ break;
40765
+ case 2:
40766
+ _context5.prev = 2;
40767
+ _context5["catch"](0);
40768
+ case 3:
40769
+ case "end":
40770
+ return _context5.stop();
40771
+ }
40772
+ }, _callee5, null, [[0, 2]]);
40773
+ }));
40774
+ return _handleSidebarSignOut.apply(this, arguments);
40775
+ }
40431
40776
  function handlePopout() {
40432
- var _window$mainApi4;
40433
- if (workspaceSelected && (_window$mainApi4 = window.mainApi) !== null && _window$mainApi4 !== void 0 && (_window$mainApi4 = _window$mainApi4.popout) !== null && _window$mainApi4 !== void 0 && _window$mainApi4.open) {
40777
+ var _window$mainApi1;
40778
+ if (workspaceSelected && (_window$mainApi1 = window.mainApi) !== null && _window$mainApi1 !== void 0 && (_window$mainApi1 = _window$mainApi1.popout) !== null && _window$mainApi1 !== void 0 && _window$mainApi1.open) {
40434
40779
  window.mainApi.popout.open(workspaceSelected.id);
40435
40780
  }
40436
40781
  }
40437
40782
  function handleWidgetPopout(widgetId) {
40438
- var _window$mainApi5;
40439
- if (workspaceSelected && (_window$mainApi5 = window.mainApi) !== null && _window$mainApi5 !== void 0 && (_window$mainApi5 = _window$mainApi5.widgetPopout) !== null && _window$mainApi5 !== void 0 && _window$mainApi5.open) {
40783
+ var _window$mainApi10;
40784
+ if (workspaceSelected && (_window$mainApi10 = window.mainApi) !== null && _window$mainApi10 !== void 0 && (_window$mainApi10 = _window$mainApi10.widgetPopout) !== null && _window$mainApi10 !== void 0 && _window$mainApi10.open) {
40440
40785
  window.mainApi.widgetPopout.open(workspaceSelected.id, widgetId);
40441
40786
  }
40442
40787
  }
@@ -40458,26 +40803,21 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
40458
40803
  workspaces: workspaceConfig,
40459
40804
  menuItems: menuItems,
40460
40805
  activeTabId: activeTabId,
40806
+ recentDashboards: recentDashboards,
40807
+ authStatus: authStatus,
40808
+ authProfile: authProfile,
40461
40809
  onOpenWorkspace: handleOpenTab,
40462
40810
  onNewDashboard: function onNewDashboard() {
40463
40811
  return setIsLayoutPickerOpen(true);
40464
40812
  },
40465
- onGoHome: function onGoHome() {
40466
- return activeTabId && handleCloseTab(activeTabId);
40467
- },
40468
- onOpenProviders: function onOpenProviders() {
40469
- return openAppSettings("providers");
40470
- },
40471
- onOpenThemeManager: handleOpenThemeManager,
40472
- onOpenFolders: function onOpenFolders() {
40473
- return openAppSettings("folders");
40474
- },
40475
40813
  onOpenSettings: function onOpenSettings() {
40476
40814
  return openAppSettings("general");
40477
40815
  },
40478
40816
  onOpenCommandPalette: function onOpenCommandPalette() {
40479
40817
  return setIsCommandPaletteOpen(true);
40480
- }
40818
+ },
40819
+ onSignIn: handleSidebarSignIn,
40820
+ onSignOut: handleSidebarSignOut
40481
40821
  }), /*#__PURE__*/jsxRuntime.jsx("div", {
40482
40822
  className: "flex flex-col flex-1 min-w-0 overflow-hidden",
40483
40823
  children: workspaceSelected !== null ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
@@ -40551,7 +40891,12 @@ var DashboardStageInner = function DashboardStageInner(_ref2) {
40551
40891
  onOpenThemeEditor: function onOpenThemeEditor() {
40552
40892
  setIsAppSettingsOpen(false);
40553
40893
  setIsThemeManagerOpen(true);
40554
- }
40894
+ },
40895
+ authStatus: authStatus,
40896
+ authProfile: authProfile,
40897
+ onSignIn: handleSidebarSignIn,
40898
+ onSignOut: handleSidebarSignOut,
40899
+ onProfileUpdated: handleProfileUpdated
40555
40900
  }), /*#__PURE__*/jsxRuntime.jsx(ThemeManagerModal, {
40556
40901
  open: isThemeManagerOpen,
40557
40902
  setIsOpen: function setIsOpen() {