@trops/dash-core 0.1.334 → 0.1.336

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
@@ -27298,6 +27298,34 @@ var SettingsModel = function SettingsModel() {
27298
27298
  return obj;
27299
27299
  };
27300
27300
 
27301
+ /**
27302
+ * Default layout for a brand-new workspace: a single 1x1 grid container
27303
+ * with one empty cell. Mirrors DashboardModel._initializeLayout().
27304
+ */
27305
+ function defaultGridLayout() {
27306
+ return [LayoutModel({
27307
+ id: 1,
27308
+ order: 1,
27309
+ type: "grid",
27310
+ component: "LayoutGridContainer",
27311
+ hasChildren: 1,
27312
+ scrollable: false,
27313
+ parent: 0,
27314
+ menuId: 1,
27315
+ width: "w-full",
27316
+ height: "h-full",
27317
+ grid: {
27318
+ rows: 1,
27319
+ cols: 1,
27320
+ gap: "gap-2",
27321
+ 1.1: {
27322
+ component: null,
27323
+ hide: false
27324
+ }
27325
+ }
27326
+ }, [])];
27327
+ }
27328
+
27301
27329
  /**
27302
27330
  * A Model for a Workspace (Dashboard)
27303
27331
  * The Workspace in this instance is the entire Dashboard Layout inclusive of the workspaces and widgets
@@ -27330,20 +27358,36 @@ var WorkspaceModel = function WorkspaceModel(workspaceItem) {
27330
27358
  workspace.type = "type" in obj ? sanitizeType(obj["type"]) : "workspace";
27331
27359
  workspace.label = "label" in obj ? obj["label"] : "New Dashboard";
27332
27360
  workspace.version = "version" in obj ? obj["version"] : 1;
27333
- workspace.layout = "layout" in obj ? obj["layout"] : [];
27361
+ // Use the provided layout if it exists and is non-empty; otherwise
27362
+ // create a default 1x1 grid so the workspace always has a renderable
27363
+ // grid container.
27364
+ var rawLayout = "layout" in obj && Array.isArray(obj["layout"]) && obj["layout"].length > 0 ? obj["layout"] : defaultGridLayout();
27365
+
27366
+ // Normalize each layout item through LayoutModel so renderers get a
27367
+ // fully-shaped object (contexts, listeners, eventHandlers, etc.).
27368
+ // Without this, layouts coming from createLayoutFromTemplate (the
27369
+ // wizard) are missing fields and the grid container fails to render.
27370
+ // Skip items already produced by LayoutModel (idempotent: LayoutModel
27371
+ // is safe to call on its own output).
27372
+ var wsId = "id" in obj ? obj["id"] : workspace.id;
27373
+ workspace.layout = rawLayout.map(function (item) {
27374
+ return LayoutModel(item, rawLayout, wsId);
27375
+ });
27334
27376
  workspace.pages = "pages" in obj ? obj["pages"] : [];
27335
27377
  workspace.activePageId = "activePageId" in obj ? obj["activePageId"] : null;
27336
27378
 
27337
27379
  // Always-pages model: every workspace must have at least one page.
27338
- // If the source data is single-page (empty pages array but populated
27339
- // layout), wrap the layout into pages[0] now so renderers always have
27340
- // a page to display. Idempotent: a no-op if pages is already populated.
27380
+ // If the source data is single-page (empty pages array), wrap the
27381
+ // layout into pages[0] so renderers always have a page to display.
27382
+ // The page is named "Page 1" when only one page exists, the
27383
+ // PageTabBar hides it; when the user adds a second page, both
27384
+ // "Page 1" and the new page become visible. Idempotent.
27341
27385
  if (!Array.isArray(workspace.pages) || workspace.pages.length === 0) {
27342
27386
  var page = {
27343
27387
  id: "page-".concat(workspace.id || Date.now()),
27344
- name: workspace.name || "Page 1",
27388
+ name: "Page 1",
27345
27389
  order: 0,
27346
- layout: workspace.layout || []
27390
+ layout: workspace.layout
27347
27391
  };
27348
27392
  workspace.pages = [page];
27349
27393
  workspace.activePageId = page.id;
@@ -49046,7 +49090,7 @@ var PageTabBar = function PageTabBar(_ref) {
49046
49090
  };
49047
49091
  return /*#__PURE__*/jsxs("div", {
49048
49092
  className: "flex flex-row items-center shrink-0 overflow-x-auto gap-1 px-2 py-1.5 border-b ".concat(currentTheme["border-primary-dark"] || "border-gray-700", " ").concat(currentTheme["bg-primary-medium"] || "bg-gray-800/50", " scrollbar-none"),
49049
- children: [sortedPages.map(function (page) {
49093
+ children: [pages.length > 1 && sortedPages.map(function (page) {
49050
49094
  var isActive = page.id === activePageId;
49051
49095
  var isDragOver = page.id === dragOverId;
49052
49096
  return /*#__PURE__*/jsxs("button", {
@@ -49118,7 +49162,7 @@ var PageTabBar = function PageTabBar(_ref) {
49118
49162
  }), /*#__PURE__*/jsx("span", {
49119
49163
  children: "Add Page"
49120
49164
  })]
49121
- }), editMode && onScrollableChange && /*#__PURE__*/jsx("div", {
49165
+ }), editMode && pages.length > 1 && onScrollableChange && /*#__PURE__*/jsx("div", {
49122
49166
  className: "ml-auto flex items-center shrink-0",
49123
49167
  children: /*#__PURE__*/jsx(Toggle, {
49124
49168
  text: "Scrollable",
@@ -51649,6 +51693,16 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
51649
51693
  // whenever a navigation happens through navigateToPage().
51650
51694
  var pageHistoryRef = useRef([]);
51651
51695
 
51696
+ // Reset local activePageId when the active tab changes so the next
51697
+ // render falls back to the new workspace's saved activePageId
51698
+ // (or its first page). Without this, a stale activePageId from a
51699
+ // previously-active dashboard would prevent the new dashboard's
51700
+ // pages from rendering (no page matches → all hidden).
51701
+ useEffect(function () {
51702
+ setActivePageId(null);
51703
+ pageHistoryRef.current = [];
51704
+ }, [activeTabId]);
51705
+
51652
51706
  // Wrapper that records history before switching pages.
51653
51707
  // Pass recordHistory=false to switch without recording (e.g. for goBack).
51654
51708
  var navigateToPage = useCallback(function (pageId) {
@@ -51810,7 +51864,18 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
51810
51864
  }, [currentActivePageId, workspacePages, workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.id, workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.name]);
51811
51865
  function handleAddPage() {
51812
51866
  if (!workspaceSelected) return;
51813
- var existingPages = _toConsumableArray(workspacePages);
51867
+ // Sync existing pages with their live layouts from refs so any
51868
+ // unsaved user edits to the current page are preserved when
51869
+ // adding a new page (especially relevant when going from 1 → 2
51870
+ // pages where the lone page's tab is hidden but its grid is live).
51871
+ var existingPages = workspacePages.map(function (p) {
51872
+ var _pageRef$current;
51873
+ var pageRef = pageRefsMap.current[p.id];
51874
+ var liveLayout = pageRef === null || pageRef === void 0 || (_pageRef$current = pageRef.current) === null || _pageRef$current === void 0 ? void 0 : _pageRef$current.layout;
51875
+ return liveLayout ? _objectSpread$5(_objectSpread$5({}, p), {}, {
51876
+ layout: liveLayout
51877
+ }) : p;
51878
+ });
51814
51879
  var newPage = DashboardModel.createPage("Page ".concat(existingPages.length + 1));
51815
51880
  newPage.order = existingPages.length;
51816
51881
  var updatedWorkspace = _objectSpread$5(_objectSpread$5({}, workspaceSelected), {}, {
@@ -52043,11 +52108,11 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
52043
52108
 
52044
52109
  // Derive scrollable state from the active page's root layout item
52045
52110
  function getRootScrollable() {
52046
- var _pageRef$current, _ws$pages;
52111
+ var _pageRef$current2, _ws$pages;
52047
52112
  var ws = currentWorkspaceRef.current || workspaceSelected;
52048
52113
  if (!ws) return false;
52049
52114
  var pageRef = pageRefsMap.current[currentActivePageId];
52050
- var layout = (pageRef === null || pageRef === void 0 || (_pageRef$current = pageRef.current) === null || _pageRef$current === void 0 ? void 0 : _pageRef$current.layout) || ((_ws$pages = ws.pages) === null || _ws$pages === void 0 || (_ws$pages = _ws$pages.find(function (p) {
52115
+ var layout = (pageRef === null || pageRef === void 0 || (_pageRef$current2 = pageRef.current) === null || _pageRef$current2 === void 0 ? void 0 : _pageRef$current2.layout) || ((_ws$pages = ws.pages) === null || _ws$pages === void 0 || (_ws$pages = _ws$pages.find(function (p) {
52051
52116
  return p.id === currentActivePageId;
52052
52117
  })) === null || _ws$pages === void 0 ? void 0 : _ws$pages.layout);
52053
52118
  if (!layout) return false;
@@ -52064,9 +52129,9 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
52064
52129
  // Gather latest layout from each page's LayoutBuilder ref
52065
52130
  var workspaceToSave = deepCopy(workspaceSelected);
52066
52131
  workspaceToSave.pages = (workspaceToSave.pages || []).map(function (page) {
52067
- var _pageRef$current2;
52132
+ var _pageRef$current3;
52068
52133
  var pageRef = pageRefsMap.current[page.id];
52069
- var latestLayout = (pageRef === null || pageRef === void 0 || (_pageRef$current2 = pageRef.current) === null || _pageRef$current2 === void 0 ? void 0 : _pageRef$current2.layout) || page.layout || [];
52134
+ var latestLayout = (pageRef === null || pageRef === void 0 || (_pageRef$current3 = pageRef.current) === null || _pageRef$current3 === void 0 ? void 0 : _pageRef$current3.layout) || page.layout || [];
52070
52135
  return _objectSpread$5(_objectSpread$5({}, page), {}, {
52071
52136
  layout: latestLayout.map(function (item) {
52072
52137
  var copy = _objectSpread$5({}, item);
@@ -52351,7 +52416,9 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
52351
52416
  onFolderChange: popout ? null : handleWorkspaceFolderChange,
52352
52417
  onThemeChange: popout ? null : handleWorkspaceThemeChange,
52353
52418
  sidebarEnabled: sidebarEnabled,
52354
- onSidebarChange: popout ? null : handleSidebarToggle
52419
+ onSidebarChange: popout ? null : handleSidebarToggle,
52420
+ scrollableEnabled: workspacePages.length <= 1 ? getRootScrollable() : undefined,
52421
+ onScrollableChange: workspacePages.length <= 1 && !popout ? handleScrollableChange : null
52355
52422
  }), /*#__PURE__*/jsxs(DashboardThemeProvider, {
52356
52423
  themeKey: workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.themeKey,
52357
52424
  children: [hasMissing && missingComponents.length >= 2 && !dismissedMissingForWorkspace.has(workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.id) && /*#__PURE__*/jsxs("div", {