(core) Show summary tables on Raw Data page

Summary:
Summary tables now have their own raw viewsection, and are shown
under Raw Data Tables on the Raw Data page.

Test Plan: Browser and Python tests.

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D3495
This commit is contained in:
George Gevoian
2022-07-06 00:41:09 -07:00
parent 8bab8c18fa
commit a051830aeb
31 changed files with 452 additions and 308 deletions

View File

@@ -22,7 +22,8 @@ import {urlState} from 'app/client/models/gristUrlState';
import MetaRowModel from 'app/client/models/MetaRowModel';
import MetaTableModel from 'app/client/models/MetaTableModel';
import * as rowset from 'app/client/models/rowset';
import {isHiddenTable, isRawTable} from 'app/common/isHiddenTable';
import {isHiddenTable, isSummaryTable} from 'app/common/isHiddenTable';
import {RowFilterFunc} from 'app/common/RowFilterFunc';
import {schema, SchemaTypes} from 'app/common/schema';
import {ACLRuleRec, createACLRuleRec} from 'app/client/models/entities/ACLRuleRec';
@@ -126,9 +127,11 @@ export class DocModel {
public docInfoRow: DocInfoRec;
public allTables: KoArray<TableRec>;
public rawTables: KoArray<TableRec>;
public allTableIds: KoArray<string>;
public visibleTables: KoArray<TableRec>;
public rawDataTables: KoArray<TableRec>;
public rawSummaryTables: KoArray<TableRec>;
public visibleTableIds: KoArray<string>;
// A mapping from tableId to DataTableModel for user-defined tables.
public dataTables: {[tableId: string]: DataTableModel} = {};
@@ -161,12 +164,15 @@ export class DocModel {
// An observable array of user-visible tables, sorted by tableId, excluding summary tables.
// This is a publicly exposed member.
this.allTables = createUserTablesArray(this.tables);
this.rawTables = createRawTablesArray(this.tables);
this.visibleTables = createVisibleTablesArray(this.tables);
// An observable array of user-visible tableIds. A shortcut mapped from allTables.
const allTableIds = ko.computed(() => this.allTables.all().map(t => t.tableId()));
this.allTableIds = koArray.syncedKoArray(allTableIds);
// Observable arrays of raw data and summary tables, sorted by tableId.
this.rawDataTables = createRawDataTablesArray(this.tables);
this.rawSummaryTables = createRawSummaryTablesArray(this.tables);
// An observable array of user-visible tableIds. A shortcut mapped from visibleTables.
const visibleTableIds = ko.computed(() => this.visibleTables.all().map(t => t.tableId()));
this.visibleTableIds = koArray.syncedKoArray(visibleTableIds);
// Create an observable array of RowModels for all the data tables. We'll trigger
// onAddTable/onRemoveTable in response to this array's splice events below.
@@ -219,24 +225,40 @@ export class DocModel {
}
}
/**
* Creates an observable array of tables, sorted by tableId.
*
* An optional `filterFunc` may be specified to filter tables.
*/
function createTablesArray(
tablesModel: MetaTableModel<TableRec>,
filterFunc: RowFilterFunc<rowset.RowId> = (_row) => true
) {
const rowSource = new rowset.FilteredRowSource(filterFunc);
rowSource.subscribeTo(tablesModel);
// Create an observable RowModel array based on this rowSource, sorted by tableId.
return tablesModel._createRowSetModel(rowSource, 'tableId');
}
/**
* Helper to create an observable array of tables, sorted by tableId, and excluding hidden
* Returns an observable array of user tables, sorted by tableId, and excluding hidden/summary
* tables.
*/
function createUserTablesArray(tablesModel: MetaTableModel<TableRec>): KoArray<TableRec> {
const rowSource = new rowset.FilteredRowSource(r => !isHiddenTable(tablesModel.tableData, r));
rowSource.subscribeTo(tablesModel);
// Create an observable RowModel array based on this rowSource, sorted by tableId.
return tablesModel._createRowSetModel(rowSource, 'tableId');
function createVisibleTablesArray(tablesModel: MetaTableModel<TableRec>): KoArray<TableRec> {
return createTablesArray(tablesModel, r => !isHiddenTable(tablesModel.tableData, r));
}
/**
* Helper to create an observable array of tables, sorted by tableId, and excluding summary tables.
* Returns an observable array of raw data tables, sorted by tableId, and excluding summary
* tables.
*/
function createRawTablesArray(tablesModel: MetaTableModel<TableRec>): KoArray<TableRec> {
const rowSource = new rowset.FilteredRowSource(r => isRawTable(tablesModel.tableData, r));
rowSource.subscribeTo(tablesModel);
// Create an observable RowModel array based on this rowSource, sorted by tableId.
return tablesModel._createRowSetModel(rowSource, 'tableId');
function createRawDataTablesArray(tablesModel: MetaTableModel<TableRec>): KoArray<TableRec> {
return createTablesArray(tablesModel, r => !isSummaryTable(tablesModel.tableData, r));
}
/**
* Returns an observable array of raw summary tables, sorted by tableId.
*/
function createRawSummaryTablesArray(tablesModel: MetaTableModel<TableRec>): KoArray<TableRec> {
return createTablesArray(tablesModel, r => isSummaryTable(tablesModel.tableData, r));
}

View File

@@ -188,7 +188,7 @@ class FinderImpl implements IFinder {
// If we are on a raw view page, pretend that we are looking at true pages.
if ('data' === this._gristDoc.activeViewId.get()) {
// Get all raw sections.
const rawSections = this._gristDoc.docModel.allTables.peek()
const rawSections = this._gristDoc.docModel.visibleTables.peek()
// Filter out those we don't have permissions to see (through ACL-tableId will be empty).
.filter(t => Boolean(t.tableId.peek()))
// sort in order that is the same as on the raw data list page,

View File

@@ -124,7 +124,7 @@ export function createColumnRec(this: ColumnRec, docModel: DocModel): void {
// Returns the rowModel for the referenced table, or null, if this is not a reference column.
this.refTable = ko.pureComputed(() => {
const refTableId = getReferencedTableId(this.type() || "");
return refTableId ? docModel.allTables.all().find(t => t.tableId() === refTableId) || null : null;
return refTableId ? docModel.visibleTables.all().find(t => t.tableId() === refTableId) || null : null;
});
// Helper for Reference/ReferenceList columns, which returns a formatter according to the visibleCol

View File

@@ -13,7 +13,7 @@ export function createPageRec(this: PageRec, docModel: DocModel): void {
const name = this.view().name();
const isTableHidden = () => {
const viewId = this.view().id();
const tables = docModel.rawTables.all();
const tables = docModel.rawDataTables.all();
const primaryTable = tables.find(t => t.primaryViewId() === viewId);
return !!primaryTable && primaryTable.isHidden();
};

View File

@@ -30,6 +30,9 @@ export interface TableRec extends IRowModel<"_grist_Tables"> {
tableName: modelUtil.KoSaveableObservable<string>;
// Table name with a default value (which is tableId).
tableNameDef: modelUtil.KoSaveableObservable<string>;
// Like tableNameDef, but formatted to be more suitable for displaying to
// users (e.g. including group columns for summary tables).
formattedTableName: ko.PureComputed<string>;
// If user can select this table in various places.
// Note: Some hidden tables can still be visible on RawData view.
isHidden: ko.Computed<boolean>;
@@ -114,4 +117,9 @@ export function createTableRec(this: TableRec, docModel: DocModel): void {
return table.tableId() || '';
})
);
this.formattedTableName = ko.pureComputed(() => {
return this.summarySourceTable()
? `${this.tableNameDef()} ${this.groupDesc()}`
: this.tableNameDef();
});
}