(core) DuplicatePage function didn't duplicated collapsed widgets

Summary:
When one of 2 widget was collapsed, the resulting widget can become a root section. Then,
when a page was duplicated, the layout was duplicated incorrectly (with wrong collapsed
section). This resulted in a bug, when the root section was deleted, as it was the last
section in the saved layout, but not the last section on the visible layout.

Test Plan: Added 2 tests

Reviewers: dsagal

Reviewed By: dsagal

Subscribers: dsagal

Differential Revision: https://phab.getgrist.com/D4227
This commit is contained in:
Jarosław Sadziński
2024-04-10 09:31:10 +02:00
parent bddbcddbef
commit 661f1c1804
4 changed files with 116 additions and 8 deletions

View File

@@ -334,7 +334,12 @@ export class ViewLayout extends DisposableWithEvents implements IDomComponent {
function addToSpec(leafId: number) {
const newBox = tmpLayout.buildLayoutBox({ leaf: leafId });
const rows = tmpLayout.rootBox()!.childBoxes.peek();
const root = tmpLayout.rootBox();
if (!root || root.isDisposed()) {
tmpLayout.setRoot(newBox);
return newBox;
}
const rows = root.childBoxes.peek();
const lastRow = rows[rows.length - 1];
if (rows.length >= 1 && lastRow.isLeaf()) {
// Add a new child to the last row.

View File

@@ -199,13 +199,20 @@ function newViewSectionAction(widget: IPageWidget, viewId: number) {
/**
* Replaces each `leaf` id in layoutSpec by its corresponding id in mapIds. Leave unchanged if id is
* missing from mapIds.
* LayoutSpec is a tree structure with leaves (that have `leaf` property) or containers of leaves. The root
* container (or leaf) also includes a list of collapsed leaves in `collapsed` property.
*
* Example use:
* patchLayoutSpec({
* leaf: 1,
* collapsed: [{leaf: 2}]
* }, {1: 10, 2: 20})
*/
export function patchLayoutSpec(layoutSpec: any, mapIds: {[id: number]: number}) {
return cloneDeepWith(layoutSpec, (val) => {
if (typeof val === 'object' && val !== null) {
if (mapIds[val.leaf]) {
return {...val, leaf: mapIds[val.leaf]};
}
const cloned = cloneDeepWith(layoutSpec, (val, key) => {
if (key === 'leaf' && mapIds[val]) {
return mapIds[val];
}
});
return cloned;
}