2021-06-17 15:26:43 +00:00
|
|
|
import {ColumnFilter} from 'app/client/models/ColumnFilter';
|
2021-11-19 20:30:11 +00:00
|
|
|
import {ColumnRec, ViewFieldRec, ViewSectionRec} from 'app/client/models/DocModel';
|
2020-10-02 15:10:00 +00:00
|
|
|
import {TableData} from 'app/client/models/TableData';
|
2021-06-17 15:26:43 +00:00
|
|
|
import {buildColFilter, ColumnFilterFunc} from 'app/common/ColumnFilterFunc';
|
|
|
|
import {buildRowFilter, RowFilterFunc, RowValueFunc } from 'app/common/RowFilterFunc';
|
2023-08-28 09:16:17 +00:00
|
|
|
import {UIRowId} from 'app/plugin/GristAPI';
|
2023-12-18 17:50:57 +00:00
|
|
|
import {Computed, Disposable, Observable, UseCB} from 'grainjs';
|
2021-06-17 15:26:43 +00:00
|
|
|
|
(core) Speed up and upgrade build.
Summary:
- Upgrades to build-related packages:
- Upgrade typescript, related libraries and typings.
- Upgrade webpack, eslint; add tsc-watch, node-dev, eslint_d.
- Build organization changes:
- Build webpack from original typescript, transpiling only; with errors still
reported by a background tsc watching process.
- Typescript-related changes:
- Reduce imports of AWS dependencies (very noticeable speedup)
- Avoid auto-loading global @types
- Client code is now built with isolatedModules flag (for safe transpilation)
- Use allowJs to avoid copying JS files manually.
- Linting changes
- Enhance Arcanist ESLintLinter to run before/after commands, and set up to use eslint_d
- Update eslint config, and include .eslintignore to avoid linting generated files.
- Include a bunch of eslint-prompted and eslint-generated fixes
- Add no-unused-expression rule to eslint, and fix a few warnings about it
- Other items:
- Refactor cssInput to avoid circular dependency
- Remove a bit of unused code, libraries, dependencies
Test Plan: No behavior changes, all existing tests pass. There are 30 tests fewer reported because `test_gpath.py` was removed (it's been unused for years)
Reviewers: paulfitz
Reviewed By: paulfitz
Subscribers: paulfitz
Differential Revision: https://phab.getgrist.com/D3498
2022-06-27 20:09:41 +00:00
|
|
|
export type {ColumnFilterFunc};
|
2020-10-02 15:10:00 +00:00
|
|
|
|
|
|
|
interface OpenColumnFilter {
|
2021-11-19 20:30:11 +00:00
|
|
|
colRef: number;
|
2020-10-02 15:10:00 +00:00
|
|
|
colFilter: ColumnFilter;
|
|
|
|
}
|
|
|
|
|
2021-11-19 20:30:11 +00:00
|
|
|
type ColFilterCB = (fieldOrColumn: ViewFieldRec|ColumnRec, colFilter: ColumnFilterFunc|null) => ColumnFilterFunc|null;
|
2021-06-17 15:26:43 +00:00
|
|
|
|
2020-10-02 15:10:00 +00:00
|
|
|
/**
|
|
|
|
* SectionFilter represents a collection of column filters in place for a view section. It is created
|
2021-11-19 20:30:11 +00:00
|
|
|
* out of `filters` (in `viewSection`) and `tableData`, and provides a Computed `sectionFilterFunc` that users can
|
2020-10-02 15:10:00 +00:00
|
|
|
* subscribe to in order to update their FilteredRowSource.
|
|
|
|
*
|
|
|
|
* Additionally, `setFilterOverride()` provides a way to override the current filter for a given colRef,
|
2023-12-18 17:50:57 +00:00
|
|
|
* to reflect the changes in an open filter dialog.
|
2020-10-02 15:10:00 +00:00
|
|
|
*/
|
|
|
|
export class SectionFilter extends Disposable {
|
2023-07-07 08:54:01 +00:00
|
|
|
public readonly sectionFilterFunc: Observable<RowFilterFunc<UIRowId>>;
|
2020-10-02 15:10:00 +00:00
|
|
|
|
|
|
|
private _openFilterOverride: Observable<OpenColumnFilter|null> = Observable.create(this, null);
|
|
|
|
|
2023-12-18 17:50:57 +00:00
|
|
|
constructor(
|
|
|
|
public viewSection: ViewSectionRec,
|
|
|
|
private _tableData: TableData,
|
|
|
|
private _resetExemptRows: () => void,
|
|
|
|
) {
|
2020-10-02 15:10:00 +00:00
|
|
|
super();
|
|
|
|
|
2023-12-18 17:50:57 +00:00
|
|
|
this.sectionFilterFunc = Computed.create(this, this._openFilterOverride, (use, openFilter) => {
|
2021-06-17 15:26:43 +00:00
|
|
|
const openFilterFilterFunc = openFilter && use(openFilter.colFilter.filterFunc);
|
2021-11-19 20:30:11 +00:00
|
|
|
function getFilterFunc(fieldOrColumn: ViewFieldRec|ColumnRec, colFilter: ColumnFilterFunc|null) {
|
2022-06-23 08:01:12 +00:00
|
|
|
if (openFilter?.colRef === fieldOrColumn.origCol().getRowId()) {
|
2021-06-17 15:26:43 +00:00
|
|
|
return openFilterFilterFunc;
|
|
|
|
}
|
|
|
|
return colFilter;
|
|
|
|
}
|
2023-12-18 17:50:57 +00:00
|
|
|
return this.buildFilterFunc(getFilterFunc, use);
|
2020-10-02 15:10:00 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-11-19 20:30:11 +00:00
|
|
|
* Allows to override a single filter for a given colRef. Multiple calls to `setFilterOverride` will overwrite
|
2020-10-02 15:10:00 +00:00
|
|
|
* previously set values.
|
|
|
|
*/
|
2021-11-19 20:30:11 +00:00
|
|
|
public setFilterOverride(colRef: number, colFilter: ColumnFilter) {
|
|
|
|
this._openFilterOverride.set(({colRef, colFilter}));
|
2020-10-02 15:10:00 +00:00
|
|
|
colFilter.onDispose(() => {
|
|
|
|
const override = this._openFilterOverride.get();
|
|
|
|
if (override && override.colFilter === colFilter) {
|
|
|
|
this._openFilterOverride.set(null);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-06-17 15:26:43 +00:00
|
|
|
/**
|
2021-11-19 20:30:11 +00:00
|
|
|
* Builds a filter function that combines the filter function of all the columns. You can use
|
2023-12-18 17:50:57 +00:00
|
|
|
* `getFilterFunc(column, colFilter)` to customize the filter func for each column. It calls
|
|
|
|
* `getFilterFunc` right away.
|
|
|
|
* This also immediately resets rows that were temporarily exempted from filtering.
|
2021-06-17 15:26:43 +00:00
|
|
|
*/
|
|
|
|
public buildFilterFunc(getFilterFunc: ColFilterCB, use: UseCB) {
|
2023-12-18 17:50:57 +00:00
|
|
|
this._resetExemptRows();
|
2021-11-19 20:30:11 +00:00
|
|
|
const filters = use(this.viewSection.filters);
|
2023-07-07 08:54:01 +00:00
|
|
|
const funcs: Array<RowFilterFunc<UIRowId> | null> = filters.map(({filter, fieldOrColumn}) => {
|
2021-11-19 20:30:11 +00:00
|
|
|
const colFilter = buildColFilter(use(filter), use(use(fieldOrColumn.origCol).type));
|
|
|
|
const filterFunc = getFilterFunc(fieldOrColumn, colFilter);
|
2021-06-17 15:26:43 +00:00
|
|
|
|
2021-11-19 20:30:11 +00:00
|
|
|
const getter = this._tableData.getRowPropFunc(fieldOrColumn.colId.peek());
|
2021-06-17 15:26:43 +00:00
|
|
|
|
|
|
|
if (!filterFunc || !getter) { return null; }
|
|
|
|
|
2023-07-07 08:54:01 +00:00
|
|
|
return buildRowFilter(getter as RowValueFunc<UIRowId>, filterFunc);
|
2021-06-17 15:26:43 +00:00
|
|
|
}).filter(f => f !== null); // Filter out columns that don't have a filter
|
|
|
|
|
2023-12-18 17:50:57 +00:00
|
|
|
return (rowId: UIRowId) => rowId === 'new' || funcs.every(f => Boolean(f && f(rowId)));
|
2021-06-17 15:26:43 +00:00
|
|
|
}
|
2020-10-02 15:10:00 +00:00
|
|
|
}
|