mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Adds limitShown option to ColumnFilterMenu, defaults to 500
Summary: - Allows ColumnFilter to add/delete keys by batch - Add options limitShown to ColumnFilterMenu - Add summary checkboxes Other Matching/Other Non-Matching/Other Values - Adds missing type to chai declaration Test Plan: - Adds project test to new file projects/ColumnFilterMenu2 - Adds nbrowser test to new file nbrowser/ColumnFilterMenu Reviewers: paulfitz Reviewed By: paulfitz Differential Revision: https://phab.getgrist.com/D2763
This commit is contained in:
@@ -85,13 +85,17 @@ export class ColumnFilter extends Disposable {
|
||||
return this._values.has(val) === this._include;
|
||||
}
|
||||
|
||||
public add(val: CellValue) {
|
||||
this._include ? this._values.add(val) : this._values.delete(val);
|
||||
public add(...values: CellValue[]) {
|
||||
for (const val of values) {
|
||||
this._include ? this._values.add(val) : this._values.delete(val);
|
||||
}
|
||||
this._updateState();
|
||||
}
|
||||
|
||||
public delete(val: CellValue) {
|
||||
this._include ? this._values.delete(val) : this._values.add(val);
|
||||
public delete(...values: CellValue[]) {
|
||||
for (const val of values) {
|
||||
this._include ? this._values.delete(val) : this._values.add(val);
|
||||
}
|
||||
this._updateState();
|
||||
}
|
||||
|
||||
|
||||
49
app/client/models/ColumnFilterMenuModel.ts
Normal file
49
app/client/models/ColumnFilterMenuModel.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Computed, Disposable, Observable } from "grainjs";
|
||||
import escapeRegExp = require("lodash/escapeRegExp");
|
||||
import { CellValue } from "app/plugin/GristData";
|
||||
import { localeCompare } from "app/common/gutil";
|
||||
import { ColumnFilter } from "./ColumnFilter";
|
||||
|
||||
const MAXIMUM_SHOWN_FILTER_ITEMS = 500;
|
||||
|
||||
export interface IFilterCount {
|
||||
label: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
|
||||
export class ColumnFilterMenuModel extends Disposable {
|
||||
|
||||
public readonly searchValue = Observable.create(this, '');
|
||||
|
||||
// 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');
|
||||
return new Set(this._valueCount.filter(([_, {label}]) => searchRegex.test(label)).map(([key]) => key));
|
||||
});
|
||||
|
||||
// computes the sorted array of all values (ie: pair of key and IFilterCount) that matches the search text.
|
||||
public readonly filteredValues = Computed.create(this, this.filterSet, (_use, filter) => {
|
||||
return this._valueCount.filter(([key]) => filter.has(key))
|
||||
.sort((a, b) => localeCompare(a[1].label, b[1].label));
|
||||
});
|
||||
|
||||
// computes the array of all values that does NOT matches the search text
|
||||
public readonly otherValues = Computed.create(this, this.filterSet, (_use, filter) => {
|
||||
return this._valueCount.filter(([key]) => !filter.has(key));
|
||||
});
|
||||
|
||||
// computes the array of keys that matches the search text
|
||||
public readonly filteredKeys = Computed.create(this, this.filteredValues, (_use, values) => (
|
||||
values.map(([key]) => key)
|
||||
));
|
||||
|
||||
public readonly valuesBeyondLimit = Computed.create(this, this.filteredValues, (_use, values) => (
|
||||
values.slice(this.limitShown)
|
||||
));
|
||||
|
||||
constructor(public columnFilter: ColumnFilter, private _valueCount: Array<[CellValue, IFilterCount]>,
|
||||
public limitShown: number = MAXIMUM_SHOWN_FILTER_ITEMS) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user