From cf7a3153f98aff6988646336c4c06653e4cd2027 Mon Sep 17 00:00:00 2001 From: Dmitry S Date: Mon, 4 Oct 2021 19:52:20 -0400 Subject: [PATCH] (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 --- app/client/models/DocModel.ts | 11 +++-------- app/client/models/isHiddenTable.ts | 12 ++++++++++++ app/client/ui/Pages.ts | 7 ++++++- 3 files changed, 21 insertions(+), 9 deletions(-) create mode 100644 app/client/models/isHiddenTable.ts diff --git a/app/client/models/DocModel.ts b/app/client/models/DocModel.ts index 65876cff..686c5740 100644 --- a/app/client/models/DocModel.ts +++ b/app/client/models/DocModel.ts @@ -22,7 +22,7 @@ import {urlState} from 'app/client/models/gristUrlState'; import * as MetaRowModel from 'app/client/models/MetaRowModel'; import * as MetaTableModel from 'app/client/models/MetaTableModel'; 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 {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. */ function createUserTablesArray(tablesModel: MetaTableModel): KoArray { - // Create a rowSource that filters out table records with non-zero summarySourceTable - // 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'))); + 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'); diff --git a/app/client/models/isHiddenTable.ts b/app/client/models/isHiddenTable.ts new file mode 100644 index 00000000..20b285b2 --- /dev/null +++ b/app/client/models/isHiddenTable.ts @@ -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')); +} diff --git a/app/client/ui/Pages.ts b/app/client/ui/Pages.ts index c9ff0c9c..0b678f36 100644 --- a/app/client/ui/Pages.ts +++ b/app/client/ui/Pages.ts @@ -3,6 +3,7 @@ import { duplicatePage } from "app/client/components/duplicatePage"; import { GristDoc } from "app/client/components/GristDoc"; import { PageRec } from "app/client/models/DocModel"; import { urlState } from "app/client/models/gristUrlState"; +import { isHiddenTable } from 'app/client/models/isHiddenTable'; import * as MetaTableModel from "app/client/models/MetaTableModel"; import { find as findInTree, fromTableData, TreeItemRecord, TreeRecord, TreeTableData} from "app/client/models/TreeModel"; @@ -80,7 +81,11 @@ function buildDomFromTable(pagesTable: MetaTableModel, activeDoc: Grist actions.onRemove = () => confirmModal( `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}));