@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.esm.js CHANGED
@@ -53405,6 +53405,44 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
53405
53405
  // eslint-disable-next-line react-hooks/exhaustive-deps
53406
53406
  }, []);
53407
53407
 
53408
+ // ─── Listen for external "open workspace" requests ──────────────
53409
+ // Fired by: Dash.js notification click, MCP state-changed for
53410
+ // create_dashboard, etc. Any code that wants to switch the active
53411
+ // dashboard from outside this component dispatches
53412
+ // window.dispatchEvent(new CustomEvent("dash:navigate-workspace",
53413
+ // { detail: { workspaceId: <number> } }))
53414
+ // We record the requested ID and open it once it appears in
53415
+ // workspaceConfig — handles the case where the workspace was just
53416
+ // created and the config reload is still in flight.
53417
+ var _useState49 = useState(null),
53418
+ _useState50 = _slicedToArray(_useState49, 2),
53419
+ pendingOpenWorkspaceId = _useState50[0],
53420
+ setPendingOpenWorkspaceId = _useState50[1];
53421
+ useEffect(function () {
53422
+ var handler = function handler(e) {
53423
+ var _e$detail;
53424
+ var id = e === null || e === void 0 || (_e$detail = e.detail) === null || _e$detail === void 0 ? void 0 : _e$detail.workspaceId;
53425
+ if (id != null) setPendingOpenWorkspaceId(Number(id));
53426
+ };
53427
+ window.addEventListener("dash:navigate-workspace", handler);
53428
+ return function () {
53429
+ return window.removeEventListener("dash:navigate-workspace", handler);
53430
+ };
53431
+ }, []);
53432
+ useEffect(function () {
53433
+ if (pendingOpenWorkspaceId == null) return;
53434
+ var ws = workspaceConfig.find(function (w) {
53435
+ return Number(w.id) === Number(pendingOpenWorkspaceId);
53436
+ });
53437
+ if (ws) {
53438
+ handleOpenTab(ws);
53439
+ setPendingOpenWorkspaceId(null);
53440
+ }
53441
+ // If not found yet, keep the pending ID and wait for the next
53442
+ // workspaceConfig update (workspace:saved triggers a reload).
53443
+ // eslint-disable-next-line react-hooks/exhaustive-deps
53444
+ }, [pendingOpenWorkspaceId, workspaceConfig]);
53445
+
53408
53446
  // ─── Load recents on mount ───────────────────────────────────────
53409
53447
  useEffect(function () {
53410
53448
  var _window$mainApi4;
@@ -53656,6 +53694,22 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
53656
53694
  setWorkspaceConfig(function () {
53657
53695
  return workspacesTemp;
53658
53696
  });
53697
+ // Also sync fresh workspace data into any open tabs. Without this,
53698
+ // MCP-driven mutations (update_layout, add_widget, etc.) update the
53699
+ // config but the active tab keeps its stale snapshot — users only
53700
+ // see the change after closing and reopening the tab.
53701
+ setOpenTabs(function (prevTabs) {
53702
+ return prevTabs.map(function (tab) {
53703
+ var fresh = workspacesTemp.find(function (w) {
53704
+ return Number(w.id) === Number(tab.id);
53705
+ });
53706
+ if (!fresh) return tab; // workspace was deleted; leave tab for handleCloseTab to reap
53707
+ return _objectSpread$6(_objectSpread$6({}, tab), {}, {
53708
+ name: fresh.name || tab.name,
53709
+ workspace: fresh
53710
+ });
53711
+ });
53712
+ });
53659
53713
  setIsLoadingWorkspaces(false);
53660
53714
  } catch (e) {
53661
53715
  }
@@ -53729,10 +53783,10 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
53729
53783
  }
53730
53784
 
53731
53785
  // ─── Page State ──────────────────────────────────────────────────
53732
- var _useState49 = useState(null),
53733
- _useState50 = _slicedToArray(_useState49, 2),
53734
- activePageId = _useState50[0],
53735
- setActivePageId = _useState50[1];
53786
+ var _useState51 = useState(null),
53787
+ _useState52 = _slicedToArray(_useState51, 2),
53788
+ activePageId = _useState52[0],
53789
+ setActivePageId = _useState52[1];
53736
53790
 
53737
53791
  // Page history stack for goBack() — pushes the previous page id
53738
53792
  // whenever a navigation happens through navigateToPage().
@@ -53792,8 +53846,8 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
53792
53846
  if (prev) setActivePageId(prev); // bypass history recording
53793
53847
  }
53794
53848
  function onSetNavSidebar(e) {
53795
- var _e$detail;
53796
- setSidebarCollapsed(!!((_e$detail = e.detail) !== null && _e$detail !== void 0 && _e$detail.collapsed));
53849
+ var _e$detail2;
53850
+ setSidebarCollapsed(!!((_e$detail2 = e.detail) !== null && _e$detail2 !== void 0 && _e$detail2.collapsed));
53797
53851
  }
53798
53852
  function onToggleNavSidebar() {
53799
53853
  setSidebarCollapsed(function (c) {
@@ -53829,16 +53883,18 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
53829
53883
  }, []);
53830
53884
  var workspacePages = (workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.pages) || [];
53831
53885
 
53832
- // Memoize sorted pages so page object references stay stable across re-renders
53886
+ // Memoize sorted pages so page object references stay stable across re-renders.
53887
+ // Depend on `workspaceSelected` so the memo invalidates whenever the workspace
53888
+ // is refreshed (e.g. after an MCP-driven layout/widget change). Without this,
53889
+ // PageLayoutBuilder's React.memo would see the same page reference and skip
53890
+ // re-rendering even though the page's layout array changed underneath.
53833
53891
  var sortedPagesForRender = useMemo(function () {
53834
53892
  return _toConsumableArray(workspacePages).sort(function (a, b) {
53835
53893
  return (a.order || 0) - (b.order || 0);
53836
53894
  });
53837
53895
  },
53838
53896
  // eslint-disable-next-line react-hooks/exhaustive-deps
53839
- [workspacePages.length,
53840
- // Re-sort when page names/order change but not on every parent render
53841
- workspacePages.map(function (p) {
53897
+ [workspaceSelected, workspacePages.length, workspacePages.map(function (p) {
53842
53898
  return "".concat(p.id, ":").concat(p.order, ":").concat(p.name);
53843
53899
  }).join(",")]);
53844
53900
  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);
@@ -53859,8 +53915,8 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
53859
53915
  // Listen for open/close dashboard actions via DashboardActionsApi
53860
53916
  useEffect(function () {
53861
53917
  function onOpen(e) {
53862
- var _e$detail2;
53863
- var name = (_e$detail2 = e.detail) === null || _e$detail2 === void 0 ? void 0 : _e$detail2.name;
53918
+ var _e$detail3;
53919
+ var name = (_e$detail3 = e.detail) === null || _e$detail3 === void 0 ? void 0 : _e$detail3.name;
53864
53920
  if (!name) return;
53865
53921
  var ws = (workspaceConfigRef.current || []).find(function (w) {
53866
53922
  return (w.name || "").toLowerCase() === name.toLowerCase();
@@ -53868,8 +53924,8 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
53868
53924
  if (ws && handleOpenTabRef.current) handleOpenTabRef.current(ws);
53869
53925
  }
53870
53926
  function onClose(e) {
53871
- var _e$detail3;
53872
- var name = (_e$detail3 = e.detail) === null || _e$detail3 === void 0 ? void 0 : _e$detail3.name;
53927
+ var _e$detail4;
53928
+ var name = (_e$detail4 = e.detail) === null || _e$detail4 === void 0 ? void 0 : _e$detail4.name;
53873
53929
  if (name) {
53874
53930
  var tab = (openTabsRef.current || []).find(function (t) {
53875
53931
  return (t.name || "").toLowerCase() === name.toLowerCase();
@@ -57326,6 +57382,10 @@ function ChatCore(_ref) {
57326
57382
  setStreamingText("");
57327
57383
  setSessionActive(false);
57328
57384
  saveConversation([]);
57385
+ // Allow the initial-message auto-send to re-fire on the fresh
57386
+ // empty conversation. Without this reset, the greeting only ever
57387
+ // appears once per mount, and New Chat leaves the panel blank.
57388
+ initialMessageFiredRef.current = false;
57329
57389
  if (isCliBackend && mainApi !== null && mainApi !== void 0 && (_mainApi$llm3 = mainApi.llm) !== null && _mainApi$llm3 !== void 0 && _mainApi$llm3.clearCliSession) {
57330
57390
  mainApi.llm.clearCliSession(uuid || persistKey || sessionKey);
57331
57391
  }