mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Allow filtering hidden columns
Summary: Existing filters are now moved out of fields and into a new metadata table for filters, and the client is updated to retrieve/update/save filters from the new table. This enables storing of filters for columns that don't have fields (notably, hidden columns). Test Plan: Browser and server tests. Reviewers: jarek Reviewed By: jarek Differential Revision: https://phab.getgrist.com/D3138
This commit is contained in:
@@ -217,33 +217,39 @@ export async function exportSection(
|
||||
.filterRecords({ parentId: table.id }) as GristTablesColumn[];
|
||||
const viewSectionFields = safeTable(docData, '_grist_Views_section_field');
|
||||
const fields = viewSectionFields.filterRecords({ parentId: viewSection.id }) as GristViewsSectionField[];
|
||||
const savedFilters = safeTable(docData, '_grist_Filters')
|
||||
.filterRecords({ viewSectionRef: viewSection.id }) as GristFilter[];
|
||||
|
||||
const tableColsById = _.indexBy(columns, 'id');
|
||||
const fieldsByColRef = _.indexBy(fields, 'colRef');
|
||||
const savedFiltersByColRef = _.indexBy(savedFilters, 'colRef');
|
||||
const unsavedFiltersByColRef = _.indexBy(filters ?? [], 'colRef');
|
||||
|
||||
// Produce a column description matching what user will see / expect to export
|
||||
const viewify = (col: GristTablesColumn, field: GristViewsSectionField) => {
|
||||
field = field || {};
|
||||
const displayCol = tableColsById[field.displayCol || col.displayCol || col.id];
|
||||
const viewify = (col: GristTablesColumn, field?: GristViewsSectionField) => {
|
||||
const displayCol = tableColsById[field?.displayCol || col.displayCol || col.id];
|
||||
const colWidgetOptions = gutil.safeJsonParse(col.widgetOptions, {});
|
||||
const fieldWidgetOptions = gutil.safeJsonParse(field.widgetOptions, {});
|
||||
const filterString = (filters || []).find(x => x.colRef === field.colRef)?.filter || field.filter;
|
||||
const fieldWidgetOptions = field ? gutil.safeJsonParse(field.widgetOptions, {}) : {};
|
||||
const filterString = unsavedFiltersByColRef[col.id]?.filter || savedFiltersByColRef[col.id]?.filter;
|
||||
const filterFunc = buildColFilter(filterString, col.type);
|
||||
return {
|
||||
filterFunc,
|
||||
id: displayCol.id,
|
||||
colId: displayCol.colId,
|
||||
label: col.label,
|
||||
type: col.type,
|
||||
parentPos: col.parentPos,
|
||||
filterFunc,
|
||||
widgetOptions: Object.assign(colWidgetOptions, fieldWidgetOptions)
|
||||
widgetOptions: Object.assign(colWidgetOptions, fieldWidgetOptions),
|
||||
};
|
||||
};
|
||||
const viewColumns = _.sortBy(fields, 'parentPos').map(
|
||||
(field) => viewify(tableColsById[field.colRef], field));
|
||||
const tableColumns = columns
|
||||
.filter(column => !gristTypes.isHiddenCol(column.colId))
|
||||
.map(column => viewify(column, fieldsByColRef[column.id]));
|
||||
const viewColumns = _.sortBy(fields, 'parentPos')
|
||||
.map((field) => viewify(tableColsById[field.colRef], field));
|
||||
|
||||
// The columns named in sort order need to now become display columns
|
||||
sortSpec = sortSpec || gutil.safeJsonParse(viewSection.sortColRefs, []);
|
||||
const fieldsByColRef = _.indexBy(fields, 'colRef');
|
||||
sortSpec = sortSpec!.map((colSpec) => {
|
||||
const colRef = Sort.getColRef(colSpec);
|
||||
const col = tableColsById[colRef];
|
||||
@@ -264,10 +270,10 @@ export async function exportSection(
|
||||
sorter.updateSpec(sortSpec);
|
||||
rowIds.sort((a, b) => sorter.compare(a, b));
|
||||
// create cell accessors
|
||||
const access = viewColumns.map(col => getters.getColGetter(col.id)!);
|
||||
const tableAccess = tableColumns.map(col => getters.getColGetter(col.id)!);
|
||||
// create row filter based on all columns filter
|
||||
const rowFilter = viewColumns
|
||||
.map((col, c) => buildRowFilter(access[c], col.filterFunc))
|
||||
const rowFilter = tableColumns
|
||||
.map((col, c) => buildRowFilter(tableAccess[c], col.filterFunc))
|
||||
.reduce((prevFilter, curFilter) => (id) => prevFilter(id) && curFilter(id), () => true);
|
||||
// filter rows numbers
|
||||
rowIds = rowIds.filter(rowFilter);
|
||||
@@ -276,11 +282,11 @@ export async function exportSection(
|
||||
const docSettings = gutil.safeJsonParse(docInfo.documentSettings, {});
|
||||
|
||||
return {
|
||||
rowIds,
|
||||
docSettings,
|
||||
tableName: table.tableId,
|
||||
docName: activeDoc.docName,
|
||||
rowIds,
|
||||
access,
|
||||
docSettings,
|
||||
access: viewColumns.map(col => getters.getColGetter(col.id)!),
|
||||
columns: viewColumns
|
||||
};
|
||||
}
|
||||
@@ -294,6 +300,7 @@ type GristTables = RowModel<'_grist_Tables'>
|
||||
type GristViewsSectionField = RowModel<'_grist_Views_section_field'>
|
||||
type GristTablesColumn = RowModel<'_grist_Tables_column'>
|
||||
type GristView = RowModel<'_grist_Views'>
|
||||
type GristFilter = RowModel<'_grist_Filters'>
|
||||
type DocInfo = RowModel<'_grist_DocInfo'>
|
||||
|
||||
// Type for filters passed from the client
|
||||
|
||||
@@ -6,7 +6,7 @@ export const GRIST_DOC_SQL = `
|
||||
PRAGMA foreign_keys=OFF;
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE IF NOT EXISTS "_grist_DocInfo" (id INTEGER PRIMARY KEY, "docId" TEXT DEFAULT '', "peers" TEXT DEFAULT '', "basketId" TEXT DEFAULT '', "schemaVersion" INTEGER DEFAULT 0, "timezone" TEXT DEFAULT '', "documentSettings" TEXT DEFAULT '');
|
||||
INSERT INTO _grist_DocInfo VALUES(1,'','','',24,'UTC','{"locale": "en-US"}');
|
||||
INSERT INTO _grist_DocInfo VALUES(1,'','','',25,'UTC','{"locale": "en-US"}');
|
||||
CREATE TABLE IF NOT EXISTS "_grist_Tables" (id INTEGER PRIMARY KEY, "tableId" TEXT DEFAULT '', "primaryViewId" INTEGER DEFAULT 0, "summarySourceTable" INTEGER DEFAULT 0, "onDemand" BOOLEAN DEFAULT 0);
|
||||
CREATE TABLE IF NOT EXISTS "_grist_Tables_column" (id INTEGER PRIMARY KEY, "parentId" INTEGER DEFAULT 0, "parentPos" NUMERIC DEFAULT 1e999, "colId" TEXT DEFAULT '', "type" TEXT DEFAULT '', "widgetOptions" TEXT DEFAULT '', "isFormula" BOOLEAN DEFAULT 0, "formula" TEXT DEFAULT '', "label" TEXT DEFAULT '', "untieColIdFromLabel" BOOLEAN DEFAULT 0, "summarySourceCol" INTEGER DEFAULT 0, "displayCol" INTEGER DEFAULT 0, "visibleCol" INTEGER DEFAULT 0, "recalcWhen" INTEGER DEFAULT 0, "recalcDeps" TEXT DEFAULT NULL);
|
||||
CREATE TABLE IF NOT EXISTS "_grist_Imports" (id INTEGER PRIMARY KEY, "tableRef" INTEGER DEFAULT 0, "origFileName" TEXT DEFAULT '', "parseFormula" TEXT DEFAULT '', "delimiter" TEXT DEFAULT '', "doublequote" BOOLEAN DEFAULT 0, "escapechar" TEXT DEFAULT '', "quotechar" TEXT DEFAULT '', "skipinitialspace" BOOLEAN DEFAULT 0, "encoding" TEXT DEFAULT '', "hasHeaders" BOOLEAN DEFAULT 0);
|
||||
@@ -33,6 +33,7 @@ INSERT INTO _grist_ACLPrincipals VALUES(2,'group','','','Admins','');
|
||||
INSERT INTO _grist_ACLPrincipals VALUES(3,'group','','','Editors','');
|
||||
INSERT INTO _grist_ACLPrincipals VALUES(4,'group','','','Viewers','');
|
||||
CREATE TABLE IF NOT EXISTS "_grist_ACLMemberships" (id INTEGER PRIMARY KEY, "parent" INTEGER DEFAULT 0, "child" INTEGER DEFAULT 0);
|
||||
CREATE TABLE IF NOT EXISTS "_grist_Filters" (id INTEGER PRIMARY KEY, "viewSectionRef" INTEGER DEFAULT 0, "colRef" INTEGER DEFAULT 0, "filter" TEXT DEFAULT '');
|
||||
COMMIT;
|
||||
`;
|
||||
|
||||
@@ -40,7 +41,7 @@ export const GRIST_DOC_WITH_TABLE1_SQL = `
|
||||
PRAGMA foreign_keys=OFF;
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE IF NOT EXISTS "_grist_DocInfo" (id INTEGER PRIMARY KEY, "docId" TEXT DEFAULT '', "peers" TEXT DEFAULT '', "basketId" TEXT DEFAULT '', "schemaVersion" INTEGER DEFAULT 0, "timezone" TEXT DEFAULT '', "documentSettings" TEXT DEFAULT '');
|
||||
INSERT INTO _grist_DocInfo VALUES(1,'','','',24,'UTC','{"locale": "en-US"}');
|
||||
INSERT INTO _grist_DocInfo VALUES(1,'','','',25,'UTC','{"locale": "en-US"}');
|
||||
CREATE TABLE IF NOT EXISTS "_grist_Tables" (id INTEGER PRIMARY KEY, "tableId" TEXT DEFAULT '', "primaryViewId" INTEGER DEFAULT 0, "summarySourceTable" INTEGER DEFAULT 0, "onDemand" BOOLEAN DEFAULT 0);
|
||||
INSERT INTO _grist_Tables VALUES(1,'Table1',1,0,0);
|
||||
CREATE TABLE IF NOT EXISTS "_grist_Tables_column" (id INTEGER PRIMARY KEY, "parentId" INTEGER DEFAULT 0, "parentPos" NUMERIC DEFAULT 1e999, "colId" TEXT DEFAULT '', "type" TEXT DEFAULT '', "widgetOptions" TEXT DEFAULT '', "isFormula" BOOLEAN DEFAULT 0, "formula" TEXT DEFAULT '', "label" TEXT DEFAULT '', "untieColIdFromLabel" BOOLEAN DEFAULT 0, "summarySourceCol" INTEGER DEFAULT 0, "displayCol" INTEGER DEFAULT 0, "visibleCol" INTEGER DEFAULT 0, "recalcWhen" INTEGER DEFAULT 0, "recalcDeps" TEXT DEFAULT NULL);
|
||||
@@ -79,6 +80,7 @@ INSERT INTO _grist_ACLPrincipals VALUES(2,'group','','','Admins','');
|
||||
INSERT INTO _grist_ACLPrincipals VALUES(3,'group','','','Editors','');
|
||||
INSERT INTO _grist_ACLPrincipals VALUES(4,'group','','','Viewers','');
|
||||
CREATE TABLE IF NOT EXISTS "_grist_ACLMemberships" (id INTEGER PRIMARY KEY, "parent" INTEGER DEFAULT 0, "child" INTEGER DEFAULT 0);
|
||||
CREATE TABLE IF NOT EXISTS "_grist_Filters" (id INTEGER PRIMARY KEY, "viewSectionRef" INTEGER DEFAULT 0, "colRef" INTEGER DEFAULT 0, "filter" TEXT DEFAULT '');
|
||||
CREATE TABLE IF NOT EXISTS "Table1" (id INTEGER PRIMARY KEY, "manualSort" NUMERIC DEFAULT 1e999, "A" BLOB DEFAULT NULL, "B" BLOB DEFAULT NULL, "C" BLOB DEFAULT NULL);
|
||||
COMMIT;
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user