(core) Fixing couple of bugs in collapsed section layout

Summary:
The previous implementation for collapsing sections involved disposing of a view instance (Grid or Chart component). This caused numerous bugs with
linking sections as the implementation is located in the BaseView.js. Now the view instance is kept and attached to a dom in a hidden div, so it can respond
and function as a normal rendered section. It is also passed from between collapsed and main layout, when sections are dragged or moved using section's
menu commands (`collapse` and `add to main page`)

It also implies that the ViewLayout must still be rendered when a section is maximized (as it is responsible for the view instance), so the dom, and
some logic for rendering it, had to be changed.

Test Plan: New and updated

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3826
This commit is contained in:
Jarosław Sadziński
2023-03-22 16:21:53 +01:00
parent be8e13df64
commit a9ff6b9a84
11 changed files with 364 additions and 138 deletions

View File

@@ -114,14 +114,14 @@ export class LayoutBox extends Disposable implements ContentBox {
this));
this.isMaximized = this.autoDispose(ko.pureComputed(() => {
const leafId = this.layout?.maximized();
const leafId = this.layout?.maximizedLeaf();
if (!leafId) { return false; }
if (leafId === this.leafId()) { return true; }
return this.childBoxes.all().some(function(child) { return child.isMaximized(); });
}, this));
this.isHidden = this.autoDispose(ko.pureComputed(() => {
// If there isn't any maximized box, then no box is hidden.
const maximized = this.layout?.maximized();
const maximized = this.layout?.maximizedLeaf();
if (!maximized) { return false; }
return !this.isMaximized();
}, this));
@@ -150,10 +150,10 @@ export class LayoutBox extends Disposable implements ContentBox {
return this.dom || (this.dom = this.autoDispose(this.buildDom()));
}
public maximize() {
if (this.layout.maximized.peek() !== this.leafId.peek()) {
this.layout.maximized(this.leafId());
if (this.layout.maximizedLeaf.peek() !== this.leafId.peek()) {
this.layout.maximizedLeaf(this.leafId());
} else {
this.layout.maximized(null);
this.layout.maximizedLeaf(null);
}
}
public buildDom() {
@@ -371,7 +371,7 @@ export class Layout extends Disposable {
public trigger: BackboneEvents["trigger"]; // set by Backbone
public stopListening: BackboneEvents["stopListening"]; // set by Backbone
public maximized: ko.Observable<string|null>;
public maximizedLeaf: ko.Observable<string|null>;
public rootBox: ko.Observable<LayoutBox|null>;
public createLeafFunc: (id: string) => HTMLElement;
public fillWindow: boolean;
@@ -381,7 +381,7 @@ export class Layout extends Disposable {
private _leafIdMap: Map<any, LayoutBox>|null;
public create(boxSpec: BoxSpec, createLeafFunc: (id: string) => HTMLElement, optFillWindow: boolean) {
this.maximized = observable(null as (string|null));
this.maximizedLeaf = observable(null as (string|null));
this.rootBox = observable(null as any);
this.createLeafFunc = createLeafFunc;
this._leafIdMap = null;
@@ -422,7 +422,7 @@ export class Layout extends Disposable {
return dom('div.layout_root',
domData('layoutModel', this),
toggleClass('layout_fill_window', this.fillWindow),
toggleClass('layout_box_maximized', this.maximized),
toggleClass('layout_box_maximized', this.maximizedLeaf),
scope(this.rootBox, (rootBox: LayoutBox) => {
return rootBox ? rootBox.getDom() : null;
})