(core) Initial data tables page

Summary:
- Added a new special page for viewing raw data widgets:
  - Implemented in DataTables.ts
  - Accessible only via the special URL path `/p/data`
  - Future diffs should make this page prettier and easily accessible
  - Shows a list of user tables
  - Clicking on a table name shows its `rawViewSection` by setting `GristDoc.viewModel.activeSectionId`. Note that in this case `GristDoc.viewModel` is an empty record, so this is a bit of a hack, but it works well and causes no known issues.
- Added `ViewSectionRec.isRaw` to know if the record represents a raw data widget.
- Added various restrictions in the UI for raw data widgets:
  - 'Delete widget' is disabled in the 3-dot widget menu.
  - Prevent hiding columns:
    - "Hide column" in the column context menu is disabled
    - The "VISIBLE/HIDDEN COLUMNS" section of the right panel > Table > Widget is hidden
  - The toggle bar isn't configurable to ensure that users know when raw data is filtered:
    - The filter bar always shows if and only if some filters are present
    - "Toggle Filter Bar" is hidden in:
      - Right panel > Table > Sort & Filter
      - The sort/filter menu next to the three-dot menu for widgets.
  - Other restrictions in the right panel:
    - In the Column tab:
      - 'Use separate settings' is disabled
    - In the Table tab:
      - In the Widget subtab:
        - 'Change Widget' is hidden
      - In the Data subtab:
        - 'Edit Data Selection' is hidden
        - 'SELECT BY' is hidden

Test Plan: Tested manually. The behaviour of raw data widgets may still change and they aren't easily visible to users yet.

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3248
This commit is contained in:
Alex Hall
2022-02-07 16:02:26 +02:00
parent 0f4153dc23
commit 592a43ec36
15 changed files with 193 additions and 111 deletions

View File

@@ -1,5 +1,5 @@
import {KoArray} from 'app/client/lib/koArray';
import {DocModel, IRowModel, recordSet, refRecord} from 'app/client/models/DocModel';
import {DocModel, IRowModel, recordSet, refRecord, ViewSectionRec} from 'app/client/models/DocModel';
import {ColumnRec, ValidationRec, ViewRec} from 'app/client/models/DocModel';
import {MANUALSORT} from 'app/common/gristTypes';
import * as ko from 'knockout';
@@ -12,6 +12,7 @@ export interface TableRec extends IRowModel<"_grist_Tables"> {
validations: ko.Computed<KoArray<ValidationRec>>;
primaryView: ko.Computed<ViewRec>;
rawViewSection: ko.Computed<ViewSectionRec>;
summarySource: ko.Computed<TableRec>;
// A Set object of colRefs for all summarySourceCols of table.
@@ -37,6 +38,7 @@ export function createTableRec(this: TableRec, docModel: DocModel): void {
this.validations = recordSet(this, docModel.validations, 'tableRef');
this.primaryView = refRecord(docModel.views, this.primaryViewId);
this.rawViewSection = refRecord(docModel.viewSections, this.rawViewSectionRef);
this.summarySource = refRecord(docModel.tables, this.summarySourceTable);
// A Set object of colRefs for all summarySourceCols of this table.

View File

@@ -32,7 +32,9 @@ export function createViewRec(this: ViewRec, docModel: DocModel): void {
// The default function which is used when the conditional case is true.
// Read may occur for recently disposed sections, must check condition first.
return !this.isDisposed() &&
this.viewSections().all().length > 0 ? this.viewSections().at(0)!.getRowId() : 0;
// `!this.getRowId()` implies that this is an empty (non-existent) view record
// which happens when viewing the raw data tables, in which case the default is no active view section.
this.getRowId() && this.viewSections().all().length > 0 ? this.viewSections().at(0)!.getRowId() : 0;
});
this.activeSection = refRecord(docModel.viewSections, this.activeSectionId);

View File

@@ -47,6 +47,10 @@ export interface ViewSectionRec extends IRowModel<"_grist_Views_section"> {
tableTitle: ko.Computed<string>;
titleDef: modelUtil.KoSaveableObservable<string>;
// true if this record is its table's rawViewSection, i.e. a 'raw data view'
// in which case the UI prevents various things like hiding columns or changing the widget type.
isRaw: ko.Computed<boolean>;
borderWidthPx: ko.Computed<string>;
layoutSpecObj: modelUtil.ObjObservable<any>;
@@ -276,6 +280,10 @@ export function createViewSectionRec(this: ViewSectionRec, docModel: DocModel):
)
);
// true if this record is its table's rawViewSection, i.e. a 'raw data view'
// in which case the UI prevents various things like hiding columns or changing the widget type.
this.isRaw = this.autoDispose(ko.pureComputed(() => this.table().rawViewSectionRef() === this.getRowId()));
this.borderWidthPx = ko.pureComputed(function() { return this.borderWidth() + 'px'; }, this);
this.layoutSpecObj = modelUtil.jsonObservable(this.layoutSpec);