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:
@@ -78,7 +78,7 @@ function BaseView(gristDoc, viewSectionModel, options) {
|
||||
// Create a section filter and a filtered row source that subscribes to its changes.
|
||||
// `sectionFilter` also provides an `addTemporaryRow()` to allow views to display newly inserted rows,
|
||||
// and `setFilterOverride()` to allow controlling a filter from a column menu.
|
||||
this._sectionFilter = SectionFilter.create(this, this.viewSection.viewFields, this.tableModel.tableData);
|
||||
this._sectionFilter = SectionFilter.create(this, this.viewSection, this.tableModel.tableData);
|
||||
this._filteredRowSource = rowset.FilteredRowSource.create(this, this._sectionFilter.sectionFilterFunc.get());
|
||||
this._filteredRowSource.subscribeTo(this._mainRowSource);
|
||||
this.autoDispose(this._sectionFilter.sectionFilterFunc.addListener(filterFunc => {
|
||||
@@ -669,10 +669,11 @@ BaseView.prototype.getLastDataRowIndex = function() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates and opens ColumnFilterMenu for a given field, and returns its PopupControl.
|
||||
* Creates and opens ColumnFilterMenu for a given field/column, and returns its PopupControl.
|
||||
*/
|
||||
BaseView.prototype.createFilterMenu = function(openCtl, field, onClose) {
|
||||
return createFilterMenu(openCtl, this._sectionFilter, field, this._mainRowSource, this.tableModel.tableData, onClose);
|
||||
BaseView.prototype.createFilterMenu = function(openCtl, filterInfo, onClose) {
|
||||
return createFilterMenu(openCtl, this._sectionFilter, filterInfo, this._mainRowSource,
|
||||
this.tableModel.tableData, onClose);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1386,7 +1386,9 @@ GridView.prototype._getColumnMenuOptions = function(copySelection) {
|
||||
|
||||
GridView.prototype._columnFilterMenu = function(ctl, field) {
|
||||
this.ctxMenuHolder.autoDispose(ctl);
|
||||
return this.createFilterMenu(ctl, field);
|
||||
const filterInfo = this.viewSection.filters()
|
||||
.find(({fieldOrColumn}) => fieldOrColumn.origCol().origColRef() === field.column().origColRef());
|
||||
return this.createFilterMenu(ctl, filterInfo);
|
||||
};
|
||||
|
||||
GridView.prototype.maybeSelectColumn = function (elem, field) {
|
||||
|
||||
@@ -650,9 +650,9 @@ export class GristDoc extends DisposableWithEvents {
|
||||
}
|
||||
|
||||
public getCsvLink() {
|
||||
const filters = this.viewModel.activeSection.peek().filteredFields.get().map(field=> ({
|
||||
colRef : field.colRef.peek(),
|
||||
filter : field.activeFilter.peek()
|
||||
const filters = this.viewModel.activeSection.peek().activeFilters.get().map(filterInfo => ({
|
||||
colRef : filterInfo.fieldOrColumn.origCol().origColRef(),
|
||||
filter : filterInfo.filter()
|
||||
}));
|
||||
|
||||
const params = {
|
||||
|
||||
@@ -576,29 +576,34 @@ ViewConfigTab.prototype._buildFilterDom = function() {
|
||||
}
|
||||
|
||||
return [
|
||||
grainjsDom.forEach(section.filteredFields, (field) => {
|
||||
grainjsDom.forEach(section.activeFilters, (filterInfo) => {
|
||||
return cssRow(
|
||||
cssIconWrapper(
|
||||
cssFilterIcon('FilterSimple', cssNoMarginLeft.cls('')),
|
||||
attachColumnFilterMenu(section, field, {
|
||||
attachColumnFilterMenu(section, filterInfo, {
|
||||
placement: 'bottom-end', attach: 'body',
|
||||
trigger: ['click', (_el, popupControl) => popupControls.set(field, popupControl)],
|
||||
trigger: [
|
||||
'click',
|
||||
(_el, popupControl) => popupControls.set(filterInfo.fieldOrColumn.origCol(), popupControl)
|
||||
],
|
||||
}),
|
||||
),
|
||||
cssLabel(grainjsDom.text(field.label)),
|
||||
cssLabel(grainjsDom.text(filterInfo.fieldOrColumn.label)),
|
||||
cssIconWrapper(
|
||||
cssFilterIcon('Remove', dom.on('click', () => field.activeFilter('')),
|
||||
testId('remove-filter')),
|
||||
cssFilterIcon('Remove',
|
||||
dom.on('click', () => section.setFilter(filterInfo.fieldOrColumn.origCol().origColRef(), '')),
|
||||
testId('remove-filter')
|
||||
),
|
||||
),
|
||||
testId('filter'),
|
||||
);
|
||||
}),
|
||||
cssRow(
|
||||
grainjsDom.domComputed((use) => {
|
||||
const fields = use(use(section.viewFields).getObservable());
|
||||
const filters = use(section.filters);
|
||||
return cssTextBtn(
|
||||
cssPlusIcon('Plus'), 'Add Filter',
|
||||
addFilterMenu(fields, popupControls, {placement: 'bottom-end'}),
|
||||
addFilterMenu(filters, section, popupControls, {placement: 'bottom-end'}),
|
||||
testId('add-filter-btn'),
|
||||
);
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user