@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.js CHANGED
@@ -27316,6 +27316,34 @@ var SettingsModel = function SettingsModel() {
27316
27316
  return obj;
27317
27317
  };
27318
27318
 
27319
+ /**
27320
+ * Default layout for a brand-new workspace: a single 1x1 grid container
27321
+ * with one empty cell. Mirrors DashboardModel._initializeLayout().
27322
+ */
27323
+ function defaultGridLayout() {
27324
+ return [LayoutModel({
27325
+ id: 1,
27326
+ order: 1,
27327
+ type: "grid",
27328
+ component: "LayoutGridContainer",
27329
+ hasChildren: 1,
27330
+ scrollable: false,
27331
+ parent: 0,
27332
+ menuId: 1,
27333
+ width: "w-full",
27334
+ height: "h-full",
27335
+ grid: {
27336
+ rows: 1,
27337
+ cols: 1,
27338
+ gap: "gap-2",
27339
+ 1.1: {
27340
+ component: null,
27341
+ hide: false
27342
+ }
27343
+ }
27344
+ }, [])];
27345
+ }
27346
+
27319
27347
  /**
27320
27348
  * A Model for a Workspace (Dashboard)
27321
27349
  * The Workspace in this instance is the entire Dashboard Layout inclusive of the workspaces and widgets
@@ -27348,20 +27376,36 @@ var WorkspaceModel = function WorkspaceModel(workspaceItem) {
27348
27376
  workspace.type = "type" in obj ? sanitizeType(obj["type"]) : "workspace";
27349
27377
  workspace.label = "label" in obj ? obj["label"] : "New Dashboard";
27350
27378
  workspace.version = "version" in obj ? obj["version"] : 1;
27351
- workspace.layout = "layout" in obj ? obj["layout"] : [];
27379
+ // Use the provided layout if it exists and is non-empty; otherwise
27380
+ // create a default 1x1 grid so the workspace always has a renderable
27381
+ // grid container.
27382
+ var rawLayout = "layout" in obj && Array.isArray(obj["layout"]) && obj["layout"].length > 0 ? obj["layout"] : defaultGridLayout();
27383
+
27384
+ // Normalize each layout item through LayoutModel so renderers get a
27385
+ // fully-shaped object (contexts, listeners, eventHandlers, etc.).
27386
+ // Without this, layouts coming from createLayoutFromTemplate (the
27387
+ // wizard) are missing fields and the grid container fails to render.
27388
+ // Skip items already produced by LayoutModel (idempotent: LayoutModel
27389
+ // is safe to call on its own output).
27390
+ var wsId = "id" in obj ? obj["id"] : workspace.id;
27391
+ workspace.layout = rawLayout.map(function (item) {
27392
+ return LayoutModel(item, rawLayout, wsId);
27393
+ });
27352
27394
  workspace.pages = "pages" in obj ? obj["pages"] : [];
27353
27395
  workspace.activePageId = "activePageId" in obj ? obj["activePageId"] : null;
27354
27396
 
27355
27397
  // Always-pages model: every workspace must have at least one page.
27356
- // If the source data is single-page (empty pages array but populated
27357
- // layout), wrap the layout into pages[0] now so renderers always have
27358
- // a page to display. Idempotent: a no-op if pages is already populated.
27398
+ // If the source data is single-page (empty pages array), wrap the
27399
+ // layout into pages[0] so renderers always have a page to display.
27400
+ // The page is named "Page 1" when only one page exists, the
27401
+ // PageTabBar hides it; when the user adds a second page, both
27402
+ // "Page 1" and the new page become visible. Idempotent.
27359
27403
  if (!Array.isArray(workspace.pages) || workspace.pages.length === 0) {
27360
27404
  var page = {
27361
27405
  id: "page-".concat(workspace.id || Date.now()),
27362
- name: workspace.name || "Page 1",
27406
+ name: "Page 1",
27363
27407
  order: 0,
27364
- layout: workspace.layout || []
27408
+ layout: workspace.layout
27365
27409
  };
27366
27410
  workspace.pages = [page];
27367
27411
  workspace.activePageId = page.id;
@@ -49064,7 +49108,7 @@ var PageTabBar = function PageTabBar(_ref) {
49064
49108
  };
49065
49109
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
49066
49110
  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"),
49067
- children: [sortedPages.map(function (page) {
49111
+ children: [pages.length > 1 && sortedPages.map(function (page) {
49068
49112
  var isActive = page.id === activePageId;
49069
49113
  var isDragOver = page.id === dragOverId;
49070
49114
  return /*#__PURE__*/jsxRuntime.jsxs("button", {
@@ -49136,7 +49180,7 @@ var PageTabBar = function PageTabBar(_ref) {
49136
49180
  }), /*#__PURE__*/jsxRuntime.jsx("span", {
49137
49181
  children: "Add Page"
49138
49182
  })]
49139
- }), editMode && onScrollableChange && /*#__PURE__*/jsxRuntime.jsx("div", {
49183
+ }), editMode && pages.length > 1 && onScrollableChange && /*#__PURE__*/jsxRuntime.jsx("div", {
49140
49184
  className: "ml-auto flex items-center shrink-0",
49141
49185
  children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Toggle, {
49142
49186
  text: "Scrollable",
@@ -51667,6 +51711,16 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
51667
51711
  // whenever a navigation happens through navigateToPage().
51668
51712
  var pageHistoryRef = React.useRef([]);
51669
51713
 
51714
+ // Reset local activePageId when the active tab changes so the next
51715
+ // render falls back to the new workspace's saved activePageId
51716
+ // (or its first page). Without this, a stale activePageId from a
51717
+ // previously-active dashboard would prevent the new dashboard's
51718
+ // pages from rendering (no page matches → all hidden).
51719
+ React.useEffect(function () {
51720
+ setActivePageId(null);
51721
+ pageHistoryRef.current = [];
51722
+ }, [activeTabId]);
51723
+
51670
51724
  // Wrapper that records history before switching pages.
51671
51725
  // Pass recordHistory=false to switch without recording (e.g. for goBack).
51672
51726
  var navigateToPage = React.useCallback(function (pageId) {
@@ -51828,7 +51882,18 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
51828
51882
  }, [currentActivePageId, workspacePages, workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.id, workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.name]);
51829
51883
  function handleAddPage() {
51830
51884
  if (!workspaceSelected) return;
51831
- var existingPages = _toConsumableArray(workspacePages);
51885
+ // Sync existing pages with their live layouts from refs so any
51886
+ // unsaved user edits to the current page are preserved when
51887
+ // adding a new page (especially relevant when going from 1 → 2
51888
+ // pages where the lone page's tab is hidden but its grid is live).
51889
+ var existingPages = workspacePages.map(function (p) {
51890
+ var _pageRef$current;
51891
+ var pageRef = pageRefsMap.current[p.id];
51892
+ var liveLayout = pageRef === null || pageRef === void 0 || (_pageRef$current = pageRef.current) === null || _pageRef$current === void 0 ? void 0 : _pageRef$current.layout;
51893
+ return liveLayout ? _objectSpread$5(_objectSpread$5({}, p), {}, {
51894
+ layout: liveLayout
51895
+ }) : p;
51896
+ });
51832
51897
  var newPage = DashboardModel.createPage("Page ".concat(existingPages.length + 1));
51833
51898
  newPage.order = existingPages.length;
51834
51899
  var updatedWorkspace = _objectSpread$5(_objectSpread$5({}, workspaceSelected), {}, {
@@ -52061,11 +52126,11 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
52061
52126
 
52062
52127
  // Derive scrollable state from the active page's root layout item
52063
52128
  function getRootScrollable() {
52064
- var _pageRef$current, _ws$pages;
52129
+ var _pageRef$current2, _ws$pages;
52065
52130
  var ws = currentWorkspaceRef.current || workspaceSelected;
52066
52131
  if (!ws) return false;
52067
52132
  var pageRef = pageRefsMap.current[currentActivePageId];
52068
- 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) {
52133
+ 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) {
52069
52134
  return p.id === currentActivePageId;
52070
52135
  })) === null || _ws$pages === void 0 ? void 0 : _ws$pages.layout);
52071
52136
  if (!layout) return false;
@@ -52082,9 +52147,9 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
52082
52147
  // Gather latest layout from each page's LayoutBuilder ref
52083
52148
  var workspaceToSave = DashReact.deepCopy(workspaceSelected);
52084
52149
  workspaceToSave.pages = (workspaceToSave.pages || []).map(function (page) {
52085
- var _pageRef$current2;
52150
+ var _pageRef$current3;
52086
52151
  var pageRef = pageRefsMap.current[page.id];
52087
- var latestLayout = (pageRef === null || pageRef === void 0 || (_pageRef$current2 = pageRef.current) === null || _pageRef$current2 === void 0 ? void 0 : _pageRef$current2.layout) || page.layout || [];
52152
+ var latestLayout = (pageRef === null || pageRef === void 0 || (_pageRef$current3 = pageRef.current) === null || _pageRef$current3 === void 0 ? void 0 : _pageRef$current3.layout) || page.layout || [];
52088
52153
  return _objectSpread$5(_objectSpread$5({}, page), {}, {
52089
52154
  layout: latestLayout.map(function (item) {
52090
52155
  var copy = _objectSpread$5({}, item);
@@ -52369,7 +52434,9 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
52369
52434
  onFolderChange: popout ? null : handleWorkspaceFolderChange,
52370
52435
  onThemeChange: popout ? null : handleWorkspaceThemeChange,
52371
52436
  sidebarEnabled: sidebarEnabled,
52372
- onSidebarChange: popout ? null : handleSidebarToggle
52437
+ onSidebarChange: popout ? null : handleSidebarToggle,
52438
+ scrollableEnabled: workspacePages.length <= 1 ? getRootScrollable() : undefined,
52439
+ onScrollableChange: workspacePages.length <= 1 && !popout ? handleScrollableChange : null
52373
52440
  }), /*#__PURE__*/jsxRuntime.jsxs(DashboardThemeProvider, {
52374
52441
  themeKey: workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.themeKey,
52375
52442
  children: [hasMissing && missingComponents.length >= 2 && !dismissedMissingForWorkspace.has(workspaceSelected === null || workspaceSelected === void 0 ? void 0 : workspaceSelected.id) && /*#__PURE__*/jsxRuntime.jsxs("div", {