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);
|
||||
}
|
||||
|
||||
public get columnType() {
|
||||
return this._columnType;
|
||||
}
|
||||
|
||||
public setState(filterJson: string|FilterSpec) {
|
||||
const state = makeFilterState(filterJson);
|
||||
this._include = state.include;
|
||||
|
@ -22,10 +22,10 @@ export class ColumnFilterMenuModel extends Disposable {
|
||||
// computes a set of all keys that matches the search text.
|
||||
public readonly filterSet = Computed.create(this, this.searchValue, (_use, searchValue) => {
|
||||
const searchRegex = new RegExp(escapeRegExp(searchValue), 'i');
|
||||
const showAllOptions = ['Bool', 'Choice', 'ChoiceList'].includes(this.columnFilter.columnType!);
|
||||
return new Set(
|
||||
this._valueCount
|
||||
.filter(([_, {count}]) => count)
|
||||
.filter(([_, {label}]) => searchRegex.test(label))
|
||||
.filter(([_, {label, count}]) => (showAllOptions ? true : count) && searchRegex.test(label))
|
||||
.map(([key]) => key)
|
||||
);
|
||||
});
|
||||
|
@ -276,6 +276,23 @@ function formatUniqueCount(values: Array<[CellValue, IFilterCount]>) {
|
||||
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().
|
||||
*/
|
||||
@ -297,14 +314,13 @@ export function createFilterMenu(openCtl: IOpenController, sectionFilter: Sectio
|
||||
sectionFilter.setFilterOverride(fieldOrColumn.getRowId(), columnFilter); // Will be removed on menu disposal
|
||||
|
||||
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, hiddenRows, {keyMapFunc, labelMapFunc, columnType,
|
||||
areHiddenRows: true});
|
||||
|
||||
const model = ColumnFilterMenuModel.create(openCtl, columnFilter, Array.from(valueCounts));
|
||||
|
||||
|
||||
return columnFilterMenu(openCtl, {
|
||||
model,
|
||||
valueCounts,
|
||||
|
Loading…
Reference in New Issue
Block a user