(core) Freezing columns on a GridView

Summary:
User can freeze any number of columns, which will not move when a user scrolls grid horizontally.
Main use cases:
- Frozen columns don't move when a user scrolls horizontally
- The number of frozen columns is automatically persisted
- Readonly viewers see frozen columns and can modify them - but the change is not persisted
- On a small screen - frozen columns still moves to the left when scrolled, to reveal at least one column
- There is a single menu option - Toggle freeze - which offers the best action considering selected columns
- When a user clicks a single column - action to freeze/unfreeze is always there
- When a user clicks multiple columns - action is offered only where it makes sens (columns are near the frozen border)

Test Plan: Browser tests

Reviewers: dsagal, paulfitz

Reviewed By: dsagal

Differential Revision: https://phab.getgrist.com/D2852
This commit is contained in:
Jarosław Sadziński
2021-06-18 11:22:27 +02:00
parent 698c9d4e40
commit bdd4d3c46e
8 changed files with 366 additions and 16 deletions

View File

@@ -89,6 +89,11 @@ export interface ViewSectionRec extends IRowModel<"_grist_Views_section"> {
isSorted: ko.Computed<boolean>;
disableDragRows: ko.Computed<boolean>;
activeFilterBar: modelUtil.CustomComputed<boolean>;
// Number of frozen columns
rawNumFrozen: modelUtil.CustomComputed<number>;
// Number for frozen columns to display.
// We won't freeze all the columns on a grid, it will leave at least 1 column unfrozen.
numFrozen: ko.Computed<number>;
// Save all filters of fields in the section.
saveFilters(): Promise<void>;
@@ -133,6 +138,7 @@ export function createViewSectionRec(this: ViewSectionRec, docModel: DocModel):
zebraStripes: false,
customView: '',
filterBar: false,
numFrozen: 0
};
this.optionsObj = modelUtil.jsonObservable(this.options,
(obj: any) => defaults(obj || {}, defaultOptions));
@@ -276,4 +282,17 @@ export function createViewSectionRec(this: ViewSectionRec, docModel: DocModel):
this.disableDragRows = ko.pureComputed(() => this.isSorted() || !this.table().supportsManualSort());
this.activeFilterBar = modelUtil.customValue(this.optionsObj.prop('filterBar'));
// Number of frozen columns
this.rawNumFrozen = modelUtil.customValue(this.optionsObj.prop('numFrozen'));
// Number for frozen columns to display
this.numFrozen = ko.pureComputed(() =>
Math.max(
0,
Math.min(
this.rawNumFrozen(),
this.viewFields().all().length - 1
)
)
);
}