(core) When hidden pages are present in the page list, allow removing them

Summary:
After an incomplete import, any GristHidden_* tables will show up in the page
list, but may not be removable if there is only one non-hidden table remaining.
Such tables should still be removable in this case.

Test Plan: Added a test case

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3058
This commit is contained in:
Dmitry S 2021-10-04 19:52:20 -04:00
parent 40ddb57dfc
commit cf7a3153f9
3 changed files with 21 additions and 9 deletions

View File

@ -22,7 +22,7 @@ import {urlState} from 'app/client/models/gristUrlState';
import * as MetaRowModel from 'app/client/models/MetaRowModel'; import * as MetaRowModel from 'app/client/models/MetaRowModel';
import * as MetaTableModel from 'app/client/models/MetaTableModel'; import * as MetaTableModel from 'app/client/models/MetaTableModel';
import * as rowset from 'app/client/models/rowset'; import * as rowset from 'app/client/models/rowset';
import {RowId} from 'app/client/models/rowset'; import {isHiddenTable} from 'app/client/models/isHiddenTable';
import {schema, SchemaTypes} from 'app/common/schema'; import {schema, SchemaTypes} from 'app/common/schema';
import {ACLRuleRec, createACLRuleRec} from 'app/client/models/entities/ACLRuleRec'; import {ACLRuleRec, createACLRuleRec} from 'app/client/models/entities/ACLRuleRec';
@ -207,16 +207,11 @@ export class DocModel {
/** /**
* Helper to create an observable array of tables, sorted by tableId, and excluding summary * Helper to create an observable array of tables, sorted by tableId, and excluding hidden
* tables. * tables.
*/ */
function createUserTablesArray(tablesModel: MetaTableModel<TableRec>): KoArray<TableRec> { function createUserTablesArray(tablesModel: MetaTableModel<TableRec>): KoArray<TableRec> {
// Create a rowSource that filters out table records with non-zero summarySourceTable const rowSource = new rowset.FilteredRowSource(r => !isHiddenTable(tablesModel.tableData, r));
// and GristHidden tables for import.
const tableIdGetter = tablesModel.tableData.getRowPropFunc('tableId') as (r: RowId) => string;
const sumTableGetter = tablesModel.tableData.getRowPropFunc('summarySourceTable') as (r: RowId) => number;
const rowSource = new rowset.FilteredRowSource(r => (sumTableGetter(r) === 0 &&
!tableIdGetter(r).startsWith('GristHidden')));
rowSource.subscribeTo(tablesModel); rowSource.subscribeTo(tablesModel);
// Create an observable RowModel array based on this rowSource, sorted by tableId. // Create an observable RowModel array based on this rowSource, sorted by tableId.
return tablesModel._createRowSetModel(rowSource, 'tableId'); return tablesModel._createRowSetModel(rowSource, 'tableId');

View File

@ -0,0 +1,12 @@
import {RowId} from 'app/client/models/rowset';
import {TableData} from 'app/client/models/TableData';
/**
* Return whether a table identified by the rowId of its metadata record, should normally be
* hidden from the user (e.g. as an option in the page-widget picker).
*/
export function isHiddenTable(tablesData: TableData, tableRef: RowId): boolean {
const tableId = tablesData.getValue(tableRef, 'tableId') as string|undefined;
return tablesData.getValue(tableRef, 'summarySourceTable') !== 0 ||
Boolean(tableId?.startsWith('GristHidden'));
}

View File

@ -3,6 +3,7 @@ import { duplicatePage } from "app/client/components/duplicatePage";
import { GristDoc } from "app/client/components/GristDoc"; import { GristDoc } from "app/client/components/GristDoc";
import { PageRec } from "app/client/models/DocModel"; import { PageRec } from "app/client/models/DocModel";
import { urlState } from "app/client/models/gristUrlState"; import { urlState } from "app/client/models/gristUrlState";
import { isHiddenTable } from 'app/client/models/isHiddenTable';
import * as MetaTableModel from "app/client/models/MetaTableModel"; import * as MetaTableModel from "app/client/models/MetaTableModel";
import { find as findInTree, fromTableData, TreeItemRecord, TreeRecord, import { find as findInTree, fromTableData, TreeItemRecord, TreeRecord,
TreeTableData} from "app/client/models/TreeModel"; TreeTableData} from "app/client/models/TreeModel";
@ -80,7 +81,11 @@ function buildDomFromTable(pagesTable: MetaTableModel<PageRec>, activeDoc: Grist
actions.onRemove = () => confirmModal( actions.onRemove = () => confirmModal(
`Delete ${pageName()} data, and remove it from all pages?`, 'Delete', doRemove); `Delete ${pageName()} data, and remove it from all pages?`, 'Delete', doRemove);
actions.isRemoveDisabled = () => (docModel.allTables.all().length <= 1); // Disable removing the last page. Sometimes hidden pages end up showing in the side panel
// (e.g. GristHidden_import* for aborted imports); those aren't listed in allTables, and we
// should allow removing them.
actions.isRemoveDisabled = () => (docModel.allTables.all().length <= 1) &&
!isHiddenTable(docModel.tables.tableData, tableRef);
} }
return buildPageDom(fromKo(pageName), actions, urlState().setLinkUrl({docPage: viewId})); return buildPageDom(fromKo(pageName), actions, urlState().setLinkUrl({docPage: viewId}));