@trops/dash-core 0.1.383 → 0.1.384

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
@@ -53423,6 +53423,44 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
53423
53423
  // eslint-disable-next-line react-hooks/exhaustive-deps
53424
53424
  }, []);
53425
53425
 
53426
+ // ─── Listen for external "open workspace" requests ──────────────
53427
+ // Fired by: Dash.js notification click, MCP state-changed for
53428
+ // create_dashboard, etc. Any code that wants to switch the active
53429
+ // dashboard from outside this component dispatches
53430
+ // window.dispatchEvent(new CustomEvent("dash:navigate-workspace",
53431
+ // { detail: { workspaceId: <number> } }))
53432
+ // We record the requested ID and open it once it appears in
53433
+ // workspaceConfig — handles the case where the workspace was just
53434
+ // created and the config reload is still in flight.
53435
+ var _useState49 = React.useState(null),
53436
+ _useState50 = _slicedToArray(_useState49, 2),
53437
+ pendingOpenWorkspaceId = _useState50[0],
53438
+ setPendingOpenWorkspaceId = _useState50[1];
53439
+ React.useEffect(function () {
53440
+ var handler = function handler(e) {
53441
+ var _e$detail;
53442
+ var id = e === null || e === void 0 || (_e$detail = e.detail) === null || _e$detail === void 0 ? void 0 : _e$detail.workspaceId;
53443
+ if (id != null) setPendingOpenWorkspaceId(Number(id));
53444
+ };
53445
+ window.addEventListener("dash:navigate-workspace", handler);
53446
+ return function () {
53447
+ return window.removeEventListener("dash:navigate-workspace", handler);
53448
+ };
53449
+ }, []);
53450
+ React.useEffect(function () {
53451
+ if (pendingOpenWorkspaceId == null) return;
53452
+ var ws = workspaceConfig.find(function (w) {
53453
+ return Number(w.id) === Number(pendingOpenWorkspaceId);
53454
+ });
53455
+ if (ws) {
53456
+ handleOpenTab(ws);
53457
+ setPendingOpenWorkspaceId(null);
53458
+ }
53459
+ // If not found yet, keep the pending ID and wait for the next
53460
+ // workspaceConfig update (workspace:saved triggers a reload).
53461
+ // eslint-disable-next-line react-hooks/exhaustive-deps
53462
+ }, [pendingOpenWorkspaceId, workspaceConfig]);
53463
+
53426
53464
  // ─── Load recents on mount ───────────────────────────────────────
53427
53465
  React.useEffect(function () {
53428
53466
  var _window$mainApi4;
@@ -53674,6 +53712,22 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
53674
53712
  setWorkspaceConfig(function () {
53675
53713
  return workspacesTemp;
53676
53714
  });
53715
+ // Also sync fresh workspace data into any open tabs. Without this,
53716
+ // MCP-driven mutations (update_layout, add_widget, etc.) update the
53717
+ // config but the active tab keeps its stale snapshot — users only
53718
+ // see the change after closing and reopening the tab.
53719
+ setOpenTabs(function (prevTabs) {
53720
+ return prevTabs.map(function (tab) {
53721
+ var fresh = workspacesTemp.find(function (w) {
53722
+ return Number(w.id) === Number(tab.id);
53723
+ });
53724
+ if (!fresh) return tab; // workspace was deleted; leave tab for handleCloseTab to reap
53725
+ return _objectSpread$6(_objectSpread$6({}, tab), {}, {
53726
+ name: fresh.name || tab.name,
53727
+ workspace: fresh
53728
+ });
53729
+ });
53730
+ });
53677
53731
  setIsLoadingWorkspaces(false);
53678
53732
  } catch (e) {
53679
53733
  }
@@ -53747,10 +53801,10 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
53747
53801
  }
53748
53802
 
53749
53803
  // ─── Page State ──────────────────────────────────────────────────
53750
- var _useState49 = React.useState(null),
53751
- _useState50 = _slicedToArray(_useState49, 2),
53752
- activePageId = _useState50[0],
53753
- setActivePageId = _useState50[1];
53804
+ var _useState51 = React.useState(null),
53805
+ _useState52 = _slicedToArray(_useState51, 2),
53806
+ activePageId = _useState52[0],
53807
+ setActivePageId = _useState52[1];
53754
53808
 
53755
53809
  // Page history stack for goBack() — pushes the previous page id
53756
53810
  // whenever a navigation happens through navigateToPage().
@@ -53810,8 +53864,8 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
53810
53864
  if (prev) setActivePageId(prev); // bypass history recording
53811
53865
  }
53812
53866
  function onSetNavSidebar(e) {
53813
- var _e$detail;
53814
- setSidebarCollapsed(!!((_e$detail = e.detail) !== null && _e$detail !== void 0 && _e$detail.collapsed));
53867
+ var _e$detail2;
53868
+ setSidebarCollapsed(!!((_e$detail2 = e.detail) !== null && _e$detail2 !== void 0 && _e$detail2.collapsed));
53815
53869
  }
53816
53870
  function onToggleNavSidebar() {
53817
53871
  setSidebarCollapsed(function (c) {
@@ -53847,16 +53901,18 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
53847
53901
  }, []);
53848
53902
  var workspacePages = (workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.pages) || [];
53849
53903
 
53850
- // Memoize sorted pages so page object references stay stable across re-renders
53904
+ // Memoize sorted pages so page object references stay stable across re-renders.
53905
+ // Depend on `workspaceSelected` so the memo invalidates whenever the workspace
53906
+ // is refreshed (e.g. after an MCP-driven layout/widget change). Without this,
53907
+ // PageLayoutBuilder's React.memo would see the same page reference and skip
53908
+ // re-rendering even though the page's layout array changed underneath.
53851
53909
  var sortedPagesForRender = React.useMemo(function () {
53852
53910
  return _toConsumableArray(workspacePages).sort(function (a, b) {
53853
53911
  return (a.order || 0) - (b.order || 0);
53854
53912
  });
53855
53913
  },
53856
53914
  // eslint-disable-next-line react-hooks/exhaustive-deps
53857
- [workspacePages.length,
53858
- // Re-sort when page names/order change but not on every parent render
53859
- workspacePages.map(function (p) {
53915
+ [workspaceSelected, workspacePages.length, workspacePages.map(function (p) {
53860
53916
  return "".concat(p.id, ":").concat(p.order, ":").concat(p.name);
53861
53917
  }).join(",")]);
53862
53918
  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);
@@ -53877,8 +53933,8 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
53877
53933
  // Listen for open/close dashboard actions via DashboardActionsApi
53878
53934
  React.useEffect(function () {
53879
53935
  function onOpen(e) {
53880
- var _e$detail2;
53881
- var name = (_e$detail2 = e.detail) === null || _e$detail2 === void 0 ? void 0 : _e$detail2.name;
53936
+ var _e$detail3;
53937
+ var name = (_e$detail3 = e.detail) === null || _e$detail3 === void 0 ? void 0 : _e$detail3.name;
53882
53938
  if (!name) return;
53883
53939
  var ws = (workspaceConfigRef.current || []).find(function (w) {
53884
53940
  return (w.name || "").toLowerCase() === name.toLowerCase();
@@ -53886,8 +53942,8 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
53886
53942
  if (ws && handleOpenTabRef.current) handleOpenTabRef.current(ws);
53887
53943
  }
53888
53944
  function onClose(e) {
53889
- var _e$detail3;
53890
- var name = (_e$detail3 = e.detail) === null || _e$detail3 === void 0 ? void 0 : _e$detail3.name;
53945
+ var _e$detail4;
53946
+ var name = (_e$detail4 = e.detail) === null || _e$detail4 === void 0 ? void 0 : _e$detail4.name;
53891
53947
  if (name) {
53892
53948
  var tab = (openTabsRef.current || []).find(function (t) {
53893
53949
  return (t.name || "").toLowerCase() === name.toLowerCase();
@@ -57344,6 +57400,10 @@ function ChatCore(_ref) {
57344
57400
  setStreamingText("");
57345
57401
  setSessionActive(false);
57346
57402
  saveConversation([]);
57403
+ // Allow the initial-message auto-send to re-fire on the fresh
57404
+ // empty conversation. Without this reset, the greeting only ever
57405
+ // appears once per mount, and New Chat leaves the panel blank.
57406
+ initialMessageFiredRef.current = false;
57347
57407
  if (isCliBackend && mainApi !== null && mainApi !== void 0 && (_mainApi$llm3 = mainApi.llm) !== null && _mainApi$llm3 !== void 0 && _mainApi$llm3.clearCliSession) {
57348
57408
  mainApi.llm.clearCliSession(uuid || persistKey || sessionKey);
57349
57409
  }