mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) Filter menu show all options for Bool/Choice/Choice List columns
Summary: > Toggle, Choice, and Choice List need all possible values available in filter, not just values present in current records https://grist.quip.com/cjw4A8AHx1vh/Filtering-Improvements#temp:C:PZHc42e8be8cd8547bb8ce93fdb0 Test Plan: Adds new nbrowser test Reviewers: georgegevoian Reviewed By: georgegevoian Differential Revision: https://phab.getgrist.com/D3436
This commit is contained in:
parent
309ddb0fe7
commit
8f4f21e94a
@ -29,6 +29,10 @@ export class ColumnFilter extends Disposable {
|
|||||||
this.setState(_initialFilterJson);
|
this.setState(_initialFilterJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get columnType() {
|
||||||
|
return this._columnType;
|
||||||
|
}
|
||||||
|
|
||||||
public setState(filterJson: string|FilterSpec) {
|
public setState(filterJson: string|FilterSpec) {
|
||||||
const state = makeFilterState(filterJson);
|
const state = makeFilterState(filterJson);
|
||||||
this._include = state.include;
|
this._include = state.include;
|
||||||
|
@ -22,10 +22,10 @@ export class ColumnFilterMenuModel extends Disposable {
|
|||||||
// computes a set of all keys that matches the search text.
|
// computes a set of all keys that matches the search text.
|
||||||
public readonly filterSet = Computed.create(this, this.searchValue, (_use, searchValue) => {
|
public readonly filterSet = Computed.create(this, this.searchValue, (_use, searchValue) => {
|
||||||
const searchRegex = new RegExp(escapeRegExp(searchValue), 'i');
|
const searchRegex = new RegExp(escapeRegExp(searchValue), 'i');
|
||||||
|
const showAllOptions = ['Bool', 'Choice', 'ChoiceList'].includes(this.columnFilter.columnType!);
|
||||||
return new Set(
|
return new Set(
|
||||||
this._valueCount
|
this._valueCount
|
||||||
.filter(([_, {count}]) => count)
|
.filter(([_, {label, count}]) => (showAllOptions ? true : count) && searchRegex.test(label))
|
||||||
.filter(([_, {label}]) => searchRegex.test(label))
|
|
||||||
.map(([key]) => key)
|
.map(([key]) => key)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -276,6 +276,23 @@ function formatUniqueCount(values: Array<[CellValue, IFilterCount]>) {
|
|||||||
return count ? '(' + count.toLocaleString() + ')' : '';
|
return count ? '(' + count.toLocaleString() + ')' : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new `Map` object to holds pairs of `CellValue` and `IFilterCount`. For `Bool`, `Choice`
|
||||||
|
* and `ChoiceList` type of column, the map is initialized with all possible values in order to make
|
||||||
|
* sure they get shown to the user.
|
||||||
|
*/
|
||||||
|
function getEmptyCountMap(fieldOrColumn: ViewFieldRec|ColumnRec): Map<CellValue, IFilterCount> {
|
||||||
|
const columnType = fieldOrColumn.origCol().type();
|
||||||
|
let values: any[] = [];
|
||||||
|
if (columnType === 'Bool') {
|
||||||
|
values = [true, false];
|
||||||
|
} else if (['Choice', 'ChoiceList'].includes(columnType)) {
|
||||||
|
const options = fieldOrColumn.origCol().widgetOptionsJson;
|
||||||
|
values = options.prop('choices')();
|
||||||
|
}
|
||||||
|
return new Map(values.map((v) => [v, {label: String(v), count: 0}]));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns content for the newly created columnFilterMenu; for use with setPopupToCreateDom().
|
* Returns content for the newly created columnFilterMenu; for use with setPopupToCreateDom().
|
||||||
*/
|
*/
|
||||||
@ -297,14 +314,13 @@ export function createFilterMenu(openCtl: IOpenController, sectionFilter: Sectio
|
|||||||
sectionFilter.setFilterOverride(fieldOrColumn.getRowId(), columnFilter); // Will be removed on menu disposal
|
sectionFilter.setFilterOverride(fieldOrColumn.getRowId(), columnFilter); // Will be removed on menu disposal
|
||||||
|
|
||||||
const [allRows, hiddenRows] = partition(Array.from(rowSource.getAllRows()), filterFunc.get());
|
const [allRows, hiddenRows] = partition(Array.from(rowSource.getAllRows()), filterFunc.get());
|
||||||
const valueCounts: Map<CellValue, {label: string, count: number}> = new Map();
|
const valueCounts = getEmptyCountMap(fieldOrColumn);
|
||||||
addCountsToMap(valueCounts, allRows, {keyMapFunc, labelMapFunc, columnType});
|
addCountsToMap(valueCounts, allRows, {keyMapFunc, labelMapFunc, columnType});
|
||||||
addCountsToMap(valueCounts, hiddenRows, {keyMapFunc, labelMapFunc, columnType,
|
addCountsToMap(valueCounts, hiddenRows, {keyMapFunc, labelMapFunc, columnType,
|
||||||
areHiddenRows: true});
|
areHiddenRows: true});
|
||||||
|
|
||||||
const model = ColumnFilterMenuModel.create(openCtl, columnFilter, Array.from(valueCounts));
|
const model = ColumnFilterMenuModel.create(openCtl, columnFilter, Array.from(valueCounts));
|
||||||
|
|
||||||
|
|
||||||
return columnFilterMenu(openCtl, {
|
return columnFilterMenu(openCtl, {
|
||||||
model,
|
model,
|
||||||
valueCounts,
|
valueCounts,
|
||||||
|
Loading…
Reference in New Issue
Block a user