@adaptabletools/adaptable-cjs 21.0.0-canary.1 → 21.0.0-canary.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/AdaptableInterfaces/IAdaptable.d.ts +3 -2
- package/src/AdaptableOptions/DefaultAdaptableOptions.js +0 -1
- package/src/AdaptableOptions/EditOptions.d.ts +6 -1
- package/src/AdaptableOptions/FilterOptions.d.ts +20 -8
- package/src/AdaptableOptions/LayoutOptions.d.ts +3 -0
- package/src/AdaptableState/Common/AdaptableColumn.d.ts +2 -2
- package/src/Api/ColumnFilterApi.d.ts +5 -5
- package/src/Api/Implementation/ColumnApiImpl.js +1 -1
- package/src/Api/Implementation/ColumnFilterApiImpl.d.ts +3 -3
- package/src/Api/Implementation/ColumnFilterApiImpl.js +6 -6
- package/src/Api/Internal/ColumnFilterInternalApi.d.ts +3 -3
- package/src/Api/Internal/ColumnFilterInternalApi.js +19 -24
- package/src/Api/Internal/ColumnInternalApi.js +1 -1
- package/src/Api/Internal/GridInternalApi.d.ts +3 -2
- package/src/Api/Internal/GridInternalApi.js +3 -2
- package/src/Api/Internal/PredicateInternalApi.js +0 -1
- package/src/Redux/Store/AdaptableStore.js +0 -2
- package/src/Strategy/ColumnFilterModule.js +8 -1
- package/src/Utilities/adaptableQlUtils.js +1 -1
- package/src/View/Components/ColumnFilter/components/FloatingFilterValues.d.ts +5 -1
- package/src/View/Components/ColumnFilter/components/FloatingFilterValues.js +52 -16
- package/src/View/Components/ColumnFilter/utils.js +0 -1
- package/src/View/Components/FilterForm/ListBoxFilterForm.js +1 -1
- package/src/View/Components/PredicateEditor/PredicateEditor.js +14 -0
- package/src/View/Components/Selectors/PermittedValuesSelector.d.ts +2 -4
- package/src/View/Components/Selectors/PermittedValuesSelector.js +6 -5
- package/src/agGrid/AdaptableAgGrid.d.ts +3 -2
- package/src/agGrid/AdaptableAgGrid.js +20 -10
- package/src/agGrid/AdaptableFilterHandler.d.ts +12 -4
- package/src/agGrid/AdaptableFilterHandler.js +38 -11
- package/src/agGrid/AgGridColumnAdapter.js +5 -2
- package/src/agGrid/AgGridExportAdapter.js +2 -4
- package/src/agGrid/AgGridModulesAdapter.js +5 -1
- package/src/agGrid/agGridDataTypeDefinitions.js +1 -8
- package/src/components/Select/Select.d.ts +1 -0
- package/src/components/Select/Select.js +5 -4
- package/src/env.js +2 -2
- package/src/metamodel/adaptable.metamodel.d.ts +15 -0
- package/src/metamodel/adaptable.metamodel.js +1 -1
- package/src/migration/VersionUpgrade20.js +1 -2
- package/src/types.d.ts +2 -2
- package/tsconfig.cjs.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adaptabletools/adaptable-cjs",
|
|
3
|
-
"version": "21.0.0-canary.
|
|
3
|
+
"version": "21.0.0-canary.3",
|
|
4
4
|
"description": "Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"web-components",
|
|
@@ -10,7 +10,7 @@ import { SelectedCellInfo } from '../AdaptableState/Selection/SelectedCellInfo';
|
|
|
10
10
|
import { AdaptableTheme } from '../AdaptableState/ThemeState';
|
|
11
11
|
import { IAdaptableStore } from '../Redux/Store/Interface/IAdaptableStore';
|
|
12
12
|
import { IModuleCollection } from '../Strategy/Interface/IModule';
|
|
13
|
-
import { AdaptableMenuItem, AdaptableOptions, AdaptablePlugin, AdaptableState, ChartDefinition,
|
|
13
|
+
import { AdaptableMenuItem, AdaptableOptions, AdaptablePlugin, AdaptableState, ChartDefinition, InFilterValueResult, SelectedRowInfo } from '../types';
|
|
14
14
|
import { ICalculatedColumnExpressionService } from '../Utilities/Services/Interface/ICalculatedColumnExpressionService';
|
|
15
15
|
import { IDataService } from '../Utilities/Services/Interface/IDataService';
|
|
16
16
|
import { AnnotationsService } from '../Utilities/Services/AnnotationsService';
|
|
@@ -183,7 +183,8 @@ export interface IAdaptable {
|
|
|
183
183
|
getDistinctFilterValuesForColumn(options: {
|
|
184
184
|
column: AdaptableColumn;
|
|
185
185
|
currentSearchValue: string;
|
|
186
|
-
|
|
186
|
+
previousResult: InFilterValueResult | undefined;
|
|
187
|
+
}): Promise<InFilterValueResult>;
|
|
187
188
|
getGridCellFromRowNode(rowNode: IRowNode, columnId: string): GridCell | undefined;
|
|
188
189
|
getRawValueFromRowNode(rowNode: IRowNode, columnId: string): any;
|
|
189
190
|
getDisplayValueFromRowNode(rowNode: IRowNode, columnId: string): string | undefined;
|
|
@@ -154,7 +154,6 @@ const DefaultAdaptableOptions = {
|
|
|
154
154
|
columnFilterOptions: {
|
|
155
155
|
indicateFilteredColumns: true,
|
|
156
156
|
autoApplyColumnFilter: true,
|
|
157
|
-
cacheInFilterValues: true,
|
|
158
157
|
defaultNumericColumnFilter: 'Equals',
|
|
159
158
|
defaultTextColumnFilter: 'Contains',
|
|
160
159
|
defaultDateColumnFilter: 'On',
|
|
@@ -58,7 +58,12 @@ export interface EditColumnValueInfo {
|
|
|
58
58
|
value: any;
|
|
59
59
|
label?: string;
|
|
60
60
|
}
|
|
61
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Information about items in the custom Edit Controls
|
|
63
|
+
*/
|
|
64
|
+
export interface CustomEditColumnValueInfo {
|
|
65
|
+
value: any;
|
|
66
|
+
label?: string;
|
|
62
67
|
}
|
|
63
68
|
/**
|
|
64
69
|
* Used for Server Validation ie. after an edit in AG Grid which must be checked on Server
|
|
@@ -30,7 +30,7 @@ export interface FilterOptions<TData = any> {
|
|
|
30
30
|
* @param context
|
|
31
31
|
* @returns
|
|
32
32
|
*/
|
|
33
|
-
customInFilterValues?: (context: CustomInFilterValuesContext<TData>) => Promise<
|
|
33
|
+
customInFilterValues?: (context: CustomInFilterValuesContext<TData>) => Promise<InFilterValueResult> | InFilterValueResult;
|
|
34
34
|
/**
|
|
35
35
|
* When to re-filter grid after data changes: 'Always', 'Never' or 'Throttle' (with a delay value)
|
|
36
36
|
*
|
|
@@ -86,13 +86,6 @@ export interface ColumnFilterOptions<TData = any> {
|
|
|
86
86
|
* @noCodeItem
|
|
87
87
|
*/
|
|
88
88
|
autoApplyColumnFilter?: boolean | ((context: AdaptableColumnContext) => boolean);
|
|
89
|
-
/**
|
|
90
|
-
* Whether to cache the values in the IN Filter component
|
|
91
|
-
* @defaultValue true
|
|
92
|
-
* @gridInfoItem
|
|
93
|
-
* @noCodeItem
|
|
94
|
-
*/
|
|
95
|
-
cacheInFilterValues?: boolean | ((context: AdaptableColumnContext) => boolean);
|
|
96
89
|
/**
|
|
97
90
|
* Default filter type for numeric Columns
|
|
98
91
|
*
|
|
@@ -212,6 +205,20 @@ export interface InFilterValue<ValueType = any> {
|
|
|
212
205
|
*/
|
|
213
206
|
tooltip?: boolean | string;
|
|
214
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Result when providing custom values for the IN Column Filter
|
|
210
|
+
*/
|
|
211
|
+
export type InFilterValueResult = {
|
|
212
|
+
/**
|
|
213
|
+
* List of Items to display in the IN Column Filter
|
|
214
|
+
*/
|
|
215
|
+
values: InFilterValue[];
|
|
216
|
+
/**
|
|
217
|
+
* When TRUE, displays the provided values without any filtering.
|
|
218
|
+
* When FALSE, the values are filtered based on the current search text.
|
|
219
|
+
*/
|
|
220
|
+
skipDefaultSearch?: boolean;
|
|
221
|
+
};
|
|
215
222
|
/**
|
|
216
223
|
* Information about items in the IN Column Filter
|
|
217
224
|
*/
|
|
@@ -253,6 +260,11 @@ export interface CustomInFilterValuesContext<TData = any> extends AdaptableColum
|
|
|
253
260
|
* Search text in the IN Filter component - used when filtering on server
|
|
254
261
|
*/
|
|
255
262
|
currentSearchValue: string;
|
|
263
|
+
/**
|
|
264
|
+
* Memoized result from previous invocation. Helps avoid expensive recomputations,
|
|
265
|
+
* especially for async operations (e.g. server-side filtering).
|
|
266
|
+
*/
|
|
267
|
+
previousFilterResult?: InFilterValueResult;
|
|
256
268
|
}
|
|
257
269
|
/**
|
|
258
270
|
* List of Editors that can be used when creating the Grid Filter
|
|
@@ -122,5 +122,8 @@ export interface DefaultLayoutProperties {
|
|
|
122
122
|
* Context for `LayoutOptions.defaultLayoutProperties` function
|
|
123
123
|
*/
|
|
124
124
|
export interface DefaultLayoutPropertiesContext extends BaseContext {
|
|
125
|
+
/**
|
|
126
|
+
* Type of Layout ('table' | 'pivot')
|
|
127
|
+
*/
|
|
125
128
|
layoutType: 'table' | 'pivot';
|
|
126
129
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { AdaptableObject } from './AdaptableObject';
|
|
2
|
-
import {
|
|
2
|
+
import { ColDef } from 'ag-grid-enterprise';
|
|
3
3
|
import { UniqueGridCell } from '../Selection/GridCell';
|
|
4
4
|
import { ColumnFilter } from './ColumnFilter';
|
|
5
5
|
/**
|
|
6
6
|
* Defines data type of a Column; can be an AG Grid BaseCellDataType or an AdapTable array-related one
|
|
7
7
|
*/
|
|
8
|
-
export type AdaptableColumnDataType =
|
|
8
|
+
export type AdaptableColumnDataType = 'text' | 'number' | 'boolean' | 'date' | 'object' | 'textArray' | 'numberArray' | 'tupleArray' | 'objectArray' | 'unknown';
|
|
9
9
|
/**
|
|
10
10
|
* Column Types recognised by AdapTable; to be set in GridOptions
|
|
11
11
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AdaptableColumn, ColumnFilter, ColumnFilterPredicate,
|
|
1
|
+
import { AdaptableColumn, ColumnFilter, ColumnFilterPredicate, InFilterValueInfo, InFilterValueResult } from '../types';
|
|
2
2
|
import { AdaptablePredicateDef, ColumnFilterDef } from '../AdaptableState/Common/AdaptablePredicate';
|
|
3
3
|
/**
|
|
4
4
|
* Provides run-time access to Filter section of Adaptable State.
|
|
@@ -138,16 +138,16 @@ export interface ColumnFilterApi {
|
|
|
138
138
|
* @param columnId - the ID of the Column for which to refresh filter values.
|
|
139
139
|
* @return a Promise that resolves to the list of filter values, each represented as an object with `value` and `label` properties.
|
|
140
140
|
*/
|
|
141
|
-
refreshFilterValues(columnId: string): Promise<
|
|
141
|
+
refreshFilterValues(columnId: string): Promise<InFilterValueResult>;
|
|
142
142
|
/**
|
|
143
143
|
* Refreshes (reloads) the filter values for ALL Columns (for `IN` Filter).
|
|
144
144
|
*
|
|
145
145
|
* @returns A Promise that resolves to a map where:
|
|
146
146
|
* - keys are column IDs (string)
|
|
147
|
-
* - values are
|
|
148
|
-
* Each
|
|
147
|
+
* - values are objects with a `values` property, which is an array of values for the corresponding column
|
|
148
|
+
* Each item in the array contains a `value` and display `label` property
|
|
149
149
|
*/
|
|
150
|
-
refreshAllFilterValues(): Promise<Record<string,
|
|
150
|
+
refreshAllFilterValues(): Promise<Record<string, InFilterValueResult>>;
|
|
151
151
|
/**
|
|
152
152
|
* Reset(clear cache) the filter values for a given Column (for `IN` Filter).
|
|
153
153
|
* @param columnId - the ID of the Column for which to reset filter values.
|
|
@@ -424,7 +424,7 @@ class ColumnApiImpl extends ApiBase_1.ApiBase {
|
|
|
424
424
|
return this.getUIAvailableColumns().filter((c) => c.dataType === 'textArray');
|
|
425
425
|
}
|
|
426
426
|
getDateColumns() {
|
|
427
|
-
return this.getUIAvailableColumns().filter((c) => c.dataType === 'date'
|
|
427
|
+
return this.getUIAvailableColumns().filter((c) => c.dataType === 'date');
|
|
428
428
|
}
|
|
429
429
|
getBooleanColumns() {
|
|
430
430
|
return this.getUIAvailableColumns().filter((c) => c.dataType === 'boolean');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ApiBase } from './ApiBase';
|
|
2
2
|
import { AdaptablePredicateDef, ColumnFilterDef } from '../../AdaptableState/Common/AdaptablePredicate';
|
|
3
3
|
import { AdaptableColumn } from '../../AdaptableState/Common/AdaptableColumn';
|
|
4
|
-
import { ColumnFilter, ColumnFilterPredicate, InFilterValueInfo,
|
|
4
|
+
import { ColumnFilter, ColumnFilterPredicate, InFilterValueInfo, InFilterValueResult } from '../../types';
|
|
5
5
|
import { IAdaptable } from '../../AdaptableInterfaces/IAdaptable';
|
|
6
6
|
import { ColumnFilterInternalApi } from '../Internal/ColumnFilterInternalApi';
|
|
7
7
|
import { ColumnFilterApi } from '../ColumnFilterApi';
|
|
@@ -44,8 +44,8 @@ export declare class ColumnFilterApiImpl extends ApiBase implements ColumnFilter
|
|
|
44
44
|
suspendAllColumnFilters(): void;
|
|
45
45
|
unSuspendAllColumnFilters(): void;
|
|
46
46
|
addBlanksToInFilterValues(columnDistinctValues: InFilterValueInfo[]): InFilterValueInfo[];
|
|
47
|
-
refreshFilterValues(columnId: string): Promise<
|
|
48
|
-
refreshAllFilterValues(): Promise<Record<string,
|
|
47
|
+
refreshFilterValues(columnId: string): Promise<InFilterValueResult>;
|
|
48
|
+
refreshAllFilterValues(): Promise<Record<string, InFilterValueResult>>;
|
|
49
49
|
resetFilterValues(columnId: string): void;
|
|
50
50
|
resetAllFilterValues(): void;
|
|
51
51
|
}
|
|
@@ -218,19 +218,19 @@ class ColumnFilterApiImpl extends ApiBase_1.ApiBase {
|
|
|
218
218
|
async refreshAllFilterValues() {
|
|
219
219
|
const allFilterHandlers = this.internalApi.getAllAdaptableFilterHandlers();
|
|
220
220
|
const handlerPromises = allFilterHandlers.map(async (handler) => {
|
|
221
|
-
let
|
|
221
|
+
let result = { values: [] };
|
|
222
222
|
if (typeof handler.refreshFilterDisplayValues === 'function') {
|
|
223
|
-
|
|
223
|
+
result = await handler.refreshFilterDisplayValues();
|
|
224
224
|
}
|
|
225
225
|
else {
|
|
226
226
|
this.logWarn(`No refresh function for filter handler: ${handler.colId}`);
|
|
227
|
-
|
|
227
|
+
result = { values: [] };
|
|
228
228
|
}
|
|
229
|
-
return { columnId: handler.colId,
|
|
229
|
+
return { columnId: handler.colId, result };
|
|
230
230
|
});
|
|
231
231
|
return Promise.all(handlerPromises).then((results) => {
|
|
232
|
-
return results.reduce((acc, { columnId,
|
|
233
|
-
acc[columnId] =
|
|
232
|
+
return results.reduce((acc, { columnId, result }) => {
|
|
233
|
+
acc[columnId] = result;
|
|
234
234
|
return acc;
|
|
235
235
|
}, {});
|
|
236
236
|
});
|
|
@@ -5,7 +5,7 @@ import { AdaptablePredicateDef } from '../../AdaptableState/Common/AdaptablePred
|
|
|
5
5
|
import { ColumnFilter } from '../../AdaptableState/Common/ColumnFilter';
|
|
6
6
|
import { GridCell } from '../../AdaptableState/Selection/GridCell';
|
|
7
7
|
import { LayoutColumnFilterAction } from '../../Redux/ActionsReducers/LayoutRedux';
|
|
8
|
-
import {
|
|
8
|
+
import { InFilterValueResult } from '../../types';
|
|
9
9
|
import { ApiBase } from '../Implementation/ApiBase';
|
|
10
10
|
import { AdaptableFilterHandler } from '../../agGrid/AdaptableFilterHandler';
|
|
11
11
|
export declare class ColumnFilterInternalApi extends ApiBase {
|
|
@@ -53,8 +53,8 @@ export declare class ColumnFilterInternalApi extends ApiBase {
|
|
|
53
53
|
getColumnFilterValues(options: {
|
|
54
54
|
columnId: string;
|
|
55
55
|
currentSearchValue: string;
|
|
56
|
-
}): Promise<
|
|
56
|
+
}): Promise<InFilterValueResult>;
|
|
57
57
|
shouldAutoApplyColumnFilter(columnId: string): boolean;
|
|
58
|
-
|
|
58
|
+
getAdaptableFilterHandler(columnId: string): AdaptableFilterHandler | undefined;
|
|
59
59
|
getAllAdaptableFilterHandlers(): AdaptableFilterHandler[];
|
|
60
60
|
}
|
|
@@ -244,20 +244,28 @@ class ColumnFilterInternalApi extends ApiBase_1.ApiBase {
|
|
|
244
244
|
* Only if the FilterHandler is not available we fallback to the GridApi method
|
|
245
245
|
*/
|
|
246
246
|
async getColumnFilterValues(options) {
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
247
|
+
const filterOptions = this.getOptionsApi().getFilterOptions();
|
|
248
|
+
const newOptions = {
|
|
249
|
+
columnId: options.columnId,
|
|
250
|
+
get currentSearchValue() {
|
|
251
|
+
// we need this in order to keep it lazy
|
|
252
|
+
return options.currentSearchValue;
|
|
253
|
+
},
|
|
254
|
+
previousResult: undefined,
|
|
255
|
+
};
|
|
251
256
|
const columnFilterHandler = this.getAgGridApi().getColumnFilterHandler(options.columnId);
|
|
252
257
|
if (!columnFilterHandler) {
|
|
253
258
|
this.logWarn(`No ColumnFilterHandler found for columnId: ${options.columnId}!`);
|
|
254
|
-
return this.getGridApi().internalApi.getDistinctFilterDisplayValuesForColumn(
|
|
259
|
+
return this.getGridApi().internalApi.getDistinctFilterDisplayValuesForColumn(newOptions);
|
|
260
|
+
}
|
|
261
|
+
if (typeof columnFilterHandler.getFromCacheOrFetchFilterDisplayValues !== 'function') {
|
|
262
|
+
this.logWarn(`ColumnFilterHandler for columnId: ${options.columnId} does not have getFromCacheOrFetchFilterDisplayValues method!`);
|
|
263
|
+
return this.getGridApi().internalApi.getDistinctFilterDisplayValuesForColumn(newOptions);
|
|
255
264
|
}
|
|
256
|
-
if (
|
|
257
|
-
|
|
258
|
-
return this.getGridApi().internalApi.getDistinctFilterDisplayValuesForColumn(options);
|
|
265
|
+
if (filterOptions.customInFilterValues) {
|
|
266
|
+
return columnFilterHandler.fetchFilterDisplayValues(newOptions);
|
|
259
267
|
}
|
|
260
|
-
return columnFilterHandler.
|
|
268
|
+
return columnFilterHandler.getFromCacheOrFetchFilterDisplayValues(newOptions);
|
|
261
269
|
}
|
|
262
270
|
shouldAutoApplyColumnFilter(columnId) {
|
|
263
271
|
const autoApplyColumnFilterOpt = this.getOptionsApi().getFilterOptions().columnFilterOptions?.autoApplyColumnFilter;
|
|
@@ -275,21 +283,8 @@ class ColumnFilterInternalApi extends ApiBase_1.ApiBase {
|
|
|
275
283
|
// fallback, should never happen
|
|
276
284
|
return true;
|
|
277
285
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
if (typeof cacheColumnFilterValuesOpt === 'boolean') {
|
|
281
|
-
return cacheColumnFilterValuesOpt;
|
|
282
|
-
}
|
|
283
|
-
if (typeof cacheColumnFilterValuesOpt === 'function') {
|
|
284
|
-
const column = this.getColumnApi().getColumnWithColumnId(columnId);
|
|
285
|
-
const context = {
|
|
286
|
-
column,
|
|
287
|
-
...this.getAdaptableApi().internalApi.buildBaseContext(),
|
|
288
|
-
};
|
|
289
|
-
return cacheColumnFilterValuesOpt(context);
|
|
290
|
-
}
|
|
291
|
-
// fallback, should never happen
|
|
292
|
-
return true;
|
|
286
|
+
getAdaptableFilterHandler(columnId) {
|
|
287
|
+
return this.getAgGridApi().getColumnFilterHandler(columnId);
|
|
293
288
|
}
|
|
294
289
|
getAllAdaptableFilterHandlers() {
|
|
295
290
|
const allFilterableColumns = this.getColumnApi().getFilterableColumns();
|
|
@@ -301,7 +301,7 @@ class ColumnInternalApi extends ApiBase_1.ApiBase {
|
|
|
301
301
|
}
|
|
302
302
|
getColumnDateTypes() {
|
|
303
303
|
// this is required because Adaptable uses 'date' type for all AG Grid date types: 'date', 'dateString'
|
|
304
|
-
return ['date'
|
|
304
|
+
return ['date'];
|
|
305
305
|
}
|
|
306
306
|
}
|
|
307
307
|
exports.ColumnInternalApi = ColumnInternalApi;
|
|
@@ -5,7 +5,7 @@ import { SpecialColumnSettings } from '../../AdaptableState/Common/SpecialColumn
|
|
|
5
5
|
import { GridCell } from '../../AdaptableState/Selection/GridCell';
|
|
6
6
|
import { SelectedCellInfo } from '../../AdaptableState/Selection/SelectedCellInfo';
|
|
7
7
|
import { SelectedRowInfo } from '../../AdaptableState/Selection/SelectedRowInfo';
|
|
8
|
-
import {
|
|
8
|
+
import { InFilterValueResult } from '../../types';
|
|
9
9
|
import { ApiBase } from '../Implementation/ApiBase';
|
|
10
10
|
import { EditColumnValueInfo } from '../../AdaptableOptions/EditOptions';
|
|
11
11
|
export declare class GridInternalApi extends ApiBase {
|
|
@@ -29,7 +29,8 @@ export declare class GridInternalApi extends ApiBase {
|
|
|
29
29
|
getDistinctFilterDisplayValuesForColumn(options: {
|
|
30
30
|
columnId: string;
|
|
31
31
|
currentSearchValue: string;
|
|
32
|
-
|
|
32
|
+
previousResult: InFilterValueResult | undefined;
|
|
33
|
+
}): Promise<InFilterValueResult>;
|
|
33
34
|
getDistinctValuesForColumn(columnId: string): Promise<GridCell[]> | undefined;
|
|
34
35
|
getDistinctEditDisplayValuesForColumn(options: {
|
|
35
36
|
columnId: string;
|
|
@@ -39,15 +39,16 @@ class GridInternalApi extends ApiBase_1.ApiBase {
|
|
|
39
39
|
async getDistinctFilterDisplayValuesForColumn(options) {
|
|
40
40
|
const abColumn = this.getColumnApi().getColumnWithColumnId(options.columnId);
|
|
41
41
|
if (abColumn == undefined) {
|
|
42
|
-
return [];
|
|
42
|
+
return { values: [] };
|
|
43
43
|
}
|
|
44
44
|
const inFilterValues = await this._adaptable.getDistinctFilterValuesForColumn({
|
|
45
45
|
column: abColumn,
|
|
46
46
|
get currentSearchValue() {
|
|
47
47
|
return options.currentSearchValue;
|
|
48
48
|
},
|
|
49
|
+
previousResult: options.previousResult,
|
|
49
50
|
});
|
|
50
|
-
return inFilterValues || [];
|
|
51
|
+
return inFilterValues || { values: [] };
|
|
51
52
|
}
|
|
52
53
|
async getDistinctValuesForColumn(columnId) {
|
|
53
54
|
const abColumn = this.getColumnApi().getColumnWithColumnId(columnId);
|
|
@@ -899,8 +899,6 @@ const adaptableMiddleware = (adaptable) => (function(middlewareAPI) {
|
|
|
899
899
|
const newLayout = (newLayoutState.Layouts || []).find((l) => l.Name == newLayoutState.CurrentLayout) ||
|
|
900
900
|
newLayoutState.Layouts[0] ||
|
|
901
901
|
GeneralConstants_1.ERROR_LAYOUT;
|
|
902
|
-
const changedColumnSorts = adaptable.api.layoutApi.internalApi.getChangedColumnSorts(oldLayout.ColumnSorts, newLayout.ColumnSorts);
|
|
903
|
-
changedColumnSorts.forEach((columnId) => adaptable.api.filterApi.columnFilterApi.resetFilterValues(columnId));
|
|
904
902
|
let refreshColumnFilters = false;
|
|
905
903
|
if (adaptable.api.filterApi.columnFilterApi.internalApi.areColumnFiltersDifferent(oldLayout.ColumnFilters, newLayout.ColumnFilters)) {
|
|
906
904
|
refreshColumnFilters = true;
|
|
@@ -34,11 +34,18 @@ class ColumnFilterModule extends AdaptableModuleBase_1.AdaptableModuleBase {
|
|
|
34
34
|
// we reset the filter cache on sort change, because we might have columns
|
|
35
35
|
// with "In" filters, with custom values, which use `context.orderedValues`
|
|
36
36
|
// customInFilterValues: (context: CustomInFilterValuesContext<Car>) => {
|
|
37
|
-
// return context.orderedValues;
|
|
37
|
+
// return {values: context.orderedValues};
|
|
38
38
|
// }
|
|
39
39
|
// and that order will most likely change when sorting happens
|
|
40
40
|
// so we need to reset the cached filter values when sorting changes
|
|
41
41
|
this.api.eventApi.on('GridSorted', () => {
|
|
42
|
+
const filterOptions = this.api.optionsApi.getFilterOptions();
|
|
43
|
+
if (!filterOptions.customInFilterValues) {
|
|
44
|
+
// no-one is using context.sortedValues/context.orderedValues
|
|
45
|
+
// or a custom property from a value, like value.count or value.visible
|
|
46
|
+
// so no need to reset the filter display values
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
42
49
|
this.api.filterApi.columnFilterApi.resetAllFilterValues();
|
|
43
50
|
});
|
|
44
51
|
}
|
|
@@ -11,7 +11,7 @@ const mapColumnDataTypeToExpressionFunctionType = (dataType) => {
|
|
|
11
11
|
if (dataType === 'text') {
|
|
12
12
|
return 'text';
|
|
13
13
|
}
|
|
14
|
-
if (dataType === 'date'
|
|
14
|
+
if (dataType === 'date') {
|
|
15
15
|
return 'date';
|
|
16
16
|
}
|
|
17
17
|
if (dataType === 'numberArray') {
|
|
@@ -25,6 +25,7 @@ export declare function useDistinctFilterColumnValues(options: {
|
|
|
25
25
|
label: string;
|
|
26
26
|
}[];
|
|
27
27
|
dataLoadIsComplete: boolean;
|
|
28
|
+
skipDefaultSearch: boolean;
|
|
28
29
|
searchValueUsedInFilterValue: boolean;
|
|
29
30
|
};
|
|
30
31
|
setQuickFilterValues: React.Dispatch<React.SetStateAction<{
|
|
@@ -33,9 +34,12 @@ export declare function useDistinctFilterColumnValues(options: {
|
|
|
33
34
|
label: string;
|
|
34
35
|
}[];
|
|
35
36
|
dataLoadIsComplete: boolean;
|
|
37
|
+
skipDefaultSearch: boolean;
|
|
36
38
|
searchValueUsedInFilterValue: boolean;
|
|
37
39
|
}>>;
|
|
38
|
-
triggerValuesLoad: (
|
|
40
|
+
triggerValuesLoad: (options?: {
|
|
41
|
+
usePrevious: boolean;
|
|
42
|
+
}) => void;
|
|
39
43
|
};
|
|
40
44
|
/**
|
|
41
45
|
* This component was ported and modified to not know about colum filter and predicates.
|
|
@@ -24,10 +24,18 @@ function useDistinctFilterColumnValues(options) {
|
|
|
24
24
|
const { columnId, searchValueRef } = options;
|
|
25
25
|
const { api } = (0, AdaptableContext_1.useAdaptable)();
|
|
26
26
|
const [valuesLoadTrigger, setValuesLoadTrigger] = React.useState(0);
|
|
27
|
-
const
|
|
27
|
+
const usePreviousValuesProbablyBecauseOfAGGridUnnecessaryFilterRemountRef = React.useRef(false);
|
|
28
|
+
const triggerValuesLoad = React.useCallback((options) => {
|
|
29
|
+
usePreviousValuesProbablyBecauseOfAGGridUnnecessaryFilterRemountRef.current =
|
|
30
|
+
!!options?.usePrevious;
|
|
28
31
|
setValuesLoadTrigger((prev) => prev + 1);
|
|
29
32
|
}, []);
|
|
30
|
-
const [quickFilterValues, setQuickFilterValues] = React.useState({
|
|
33
|
+
const [quickFilterValues, setQuickFilterValues] = React.useState({
|
|
34
|
+
values: [],
|
|
35
|
+
dataLoadIsComplete: false,
|
|
36
|
+
skipDefaultSearch: false,
|
|
37
|
+
searchValueUsedInFilterValue: false,
|
|
38
|
+
});
|
|
31
39
|
const [isDistinctColumnValuesLoading, setIsDistinctColumnValuesLoading] = React.useState(false);
|
|
32
40
|
(0, react_1.useEffect)(() => {
|
|
33
41
|
if (valuesLoadTrigger === 0) {
|
|
@@ -37,21 +45,35 @@ function useDistinctFilterColumnValues(options) {
|
|
|
37
45
|
let ignore = false;
|
|
38
46
|
setIsDistinctColumnValuesLoading(true);
|
|
39
47
|
let searchValueUsedInFilterValue = false;
|
|
40
|
-
api.filterApi.columnFilterApi.internalApi
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
const columnFilterinternalApi = api.filterApi.columnFilterApi.internalApi;
|
|
49
|
+
let promise = undefined;
|
|
50
|
+
if (usePreviousValuesProbablyBecauseOfAGGridUnnecessaryFilterRemountRef.current) {
|
|
51
|
+
const previousResult = columnFilterinternalApi
|
|
52
|
+
.getAdaptableFilterHandler(columnId)
|
|
53
|
+
?.getLastCachedFilterDisplayValues();
|
|
54
|
+
if (previousResult) {
|
|
55
|
+
promise = Promise.resolve(previousResult);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
usePreviousValuesProbablyBecauseOfAGGridUnnecessaryFilterRemountRef.current = false;
|
|
59
|
+
if (!promise) {
|
|
60
|
+
promise = columnFilterinternalApi.getColumnFilterValues({
|
|
61
|
+
columnId,
|
|
62
|
+
get currentSearchValue() {
|
|
63
|
+
searchValueUsedInFilterValue = true;
|
|
64
|
+
return searchValueRef ? searchValueRef.current : '';
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
promise.then((distinctFilterDisplayValues) => {
|
|
49
69
|
if (ignore) {
|
|
50
70
|
return;
|
|
51
71
|
}
|
|
72
|
+
const values = distinctFilterDisplayValues.values;
|
|
52
73
|
setQuickFilterValues({
|
|
53
|
-
values
|
|
74
|
+
values,
|
|
54
75
|
dataLoadIsComplete: true,
|
|
76
|
+
skipDefaultSearch: !!distinctFilterDisplayValues.skipDefaultSearch,
|
|
55
77
|
searchValueUsedInFilterValue,
|
|
56
78
|
});
|
|
57
79
|
setIsDistinctColumnValuesLoading(false);
|
|
@@ -89,9 +111,15 @@ const FloatingFilterValues = (props) => {
|
|
|
89
111
|
if (!value || !Array.isArray(value) || value.length === 0) {
|
|
90
112
|
return;
|
|
91
113
|
}
|
|
114
|
+
// see 😅 usePreviousValuesProbablyBecauseOfAGGridUnnecessaryFilterRemountRef 😅
|
|
115
|
+
const usePrevious = !!api.filterApi.columnFilterApi.internalApi
|
|
116
|
+
.getAdaptableFilterHandler(props.columnId)
|
|
117
|
+
?.getLastCachedFilterDisplayValues();
|
|
92
118
|
// however, if the `value` prop is a non-empty array, we need to load the values
|
|
93
119
|
// so we know which labels to show
|
|
94
|
-
triggerValuesLoad(
|
|
120
|
+
triggerValuesLoad({
|
|
121
|
+
usePrevious,
|
|
122
|
+
});
|
|
95
123
|
}, []);
|
|
96
124
|
const quickFilterValuesRef = React.useRef(quickFilterValues);
|
|
97
125
|
quickFilterValuesRef.current = quickFilterValues;
|
|
@@ -121,16 +149,19 @@ const FloatingFilterValues = (props) => {
|
|
|
121
149
|
const onMenuOpen = triggerValuesLoad;
|
|
122
150
|
const onInputChange = React.useCallback((value) => {
|
|
123
151
|
searchValueRef.current = value;
|
|
124
|
-
|
|
152
|
+
const quickFilterValues = quickFilterValuesRef.current;
|
|
153
|
+
if (quickFilterValues.searchValueUsedInFilterValue || quickFilterValues.skipDefaultSearch) {
|
|
125
154
|
triggerValuesLoad();
|
|
126
155
|
}
|
|
127
|
-
}, [
|
|
156
|
+
}, []);
|
|
157
|
+
const { skipDefaultSearch } = quickFilterValues;
|
|
128
158
|
return (React.createElement(ListBoxFilterForm_1.ColumnValuesSelect, { selectProps: props.inline
|
|
129
159
|
? {
|
|
130
160
|
...props.selectProps,
|
|
131
161
|
'data-name': 'Select Values',
|
|
132
162
|
renderMultipleValues,
|
|
133
163
|
isClearable: false,
|
|
164
|
+
skipDefaultFiltering: skipDefaultSearch,
|
|
134
165
|
styles: {
|
|
135
166
|
dropdownIndicator: {
|
|
136
167
|
display: 'none',
|
|
@@ -159,6 +190,11 @@ const FloatingFilterValues = (props) => {
|
|
|
159
190
|
onMenuOpen,
|
|
160
191
|
onInputChange,
|
|
161
192
|
}
|
|
162
|
-
: {
|
|
193
|
+
: {
|
|
194
|
+
...props.selectProps,
|
|
195
|
+
skipDefaultFiltering: skipDefaultSearch,
|
|
196
|
+
onMenuOpen,
|
|
197
|
+
onInputChange,
|
|
198
|
+
}, disabled: props.disabled, isLoading: isDistinctColumnValuesLoading, column: currentColumn, dataType: currentColumn.dataType, options: quickFilterValues.values, value: props.value, onChange: props.onChange }));
|
|
163
199
|
};
|
|
164
200
|
exports.FloatingFilterValues = FloatingFilterValues;
|
|
@@ -142,7 +142,6 @@ const mapColumnFilterToQlPredicate = (columnFilter, abColumn, qlPredicateDefs, c
|
|
|
142
142
|
: { operator: 'Contains', args: [] };
|
|
143
143
|
break;
|
|
144
144
|
case 'date':
|
|
145
|
-
case 'dateString':
|
|
146
145
|
let defaultQlDatePredicate;
|
|
147
146
|
const defaultDateColumnFilter = columnFilterOptions.defaultDateColumnFilter;
|
|
148
147
|
if (defaultDateColumnFilter) {
|
|
@@ -13,7 +13,7 @@ const ColumnValuesSelect = (props) => {
|
|
|
13
13
|
const column = props.column;
|
|
14
14
|
const selectedColumnValues = props.value || [];
|
|
15
15
|
const value = [];
|
|
16
|
-
const options = props.options.filter((distinctValue
|
|
16
|
+
const options = (Array.isArray(props.options) ? props.options : []).filter((distinctValue) => {
|
|
17
17
|
let isActive = selectedColumnValues.indexOf(distinctValue.value) >= 0;
|
|
18
18
|
// special case for date objects, need to check against string values
|
|
19
19
|
if (!isActive && distinctValue.value && distinctValue.value instanceof Date) {
|
|
@@ -49,13 +49,25 @@ const PredicateEditor = (props) => {
|
|
|
49
49
|
const adaptable = (0, AdaptableContext_1.useAdaptable)();
|
|
50
50
|
const columnId = props.columnId;
|
|
51
51
|
const column = adaptable.api.columnApi.getColumnWithColumnId(columnId);
|
|
52
|
+
const searchValueRef = React.useRef('');
|
|
52
53
|
const { quickFilterValues, isDistinctColumnValuesLoading, triggerValuesLoad } = (0, FloatingFilterValues_1.useDistinctFilterColumnValues)({
|
|
53
54
|
columnId,
|
|
55
|
+
searchValueRef,
|
|
54
56
|
});
|
|
57
|
+
const quickFilterValuesRef = React.useRef(quickFilterValues);
|
|
58
|
+
quickFilterValuesRef.current = quickFilterValues;
|
|
55
59
|
(0, react_1.useEffect)(triggerValuesLoad, []);
|
|
56
60
|
const onMenuOpen = () => {
|
|
57
61
|
triggerValuesLoad();
|
|
58
62
|
};
|
|
63
|
+
const onInputChange = React.useCallback((value) => {
|
|
64
|
+
searchValueRef.current = value;
|
|
65
|
+
const quickFilterValues = quickFilterValuesRef.current;
|
|
66
|
+
if (quickFilterValues.searchValueUsedInFilterValue || quickFilterValues.skipDefaultSearch) {
|
|
67
|
+
triggerValuesLoad();
|
|
68
|
+
}
|
|
69
|
+
}, []);
|
|
70
|
+
const { skipDefaultSearch } = quickFilterValues;
|
|
59
71
|
return (React.createElement(rebass_1.Box, { className: baseClassName },
|
|
60
72
|
React.createElement(rebass_1.Flex, { justifyContent: "stretch", alignItems: "center" },
|
|
61
73
|
icon && React.createElement(Tag_1.Tag, { mr: 2 }, icon),
|
|
@@ -74,6 +86,8 @@ const PredicateEditor = (props) => {
|
|
|
74
86
|
adaptable.api.predicateApi.internalApi.IsInorNotInPredicateDef(currentPredicateDef) && (React.createElement(rebass_1.Box, { mt: 2 },
|
|
75
87
|
React.createElement(ListBoxFilterForm_1.ColumnValuesSelect, { isLoading: isDistinctColumnValuesLoading, column: column, options: quickFilterValues.values, selectProps: {
|
|
76
88
|
onMenuOpen,
|
|
89
|
+
onInputChange,
|
|
90
|
+
skipDefaultFiltering: skipDefaultSearch,
|
|
77
91
|
}, dataType: column.dataType, value: props.predicate.Inputs, onChange: handlePredicateValuesChange })))));
|
|
78
92
|
};
|
|
79
93
|
exports.PredicateEditor = PredicateEditor;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { SelectProps } from '../../../components/Select';
|
|
3
|
+
import { InFilterValue } from '../../../AdaptableOptions/FilterOptions';
|
|
3
4
|
export type ValueType = number | string | Date;
|
|
4
5
|
interface PermittedValuesSelectorProps<Value extends ValueType, IsMulti extends boolean> {
|
|
5
6
|
searchable?: false | 'inline' | 'menulist';
|
|
@@ -17,10 +18,7 @@ interface PermittedValuesSelectorProps<Value extends ValueType, IsMulti extends
|
|
|
17
18
|
menuPortalTarget?: HTMLElement;
|
|
18
19
|
loadValues?: (options: {
|
|
19
20
|
currentSearchValue: string;
|
|
20
|
-
}) => Promise<
|
|
21
|
-
value: any;
|
|
22
|
-
label: string;
|
|
23
|
-
}[]>;
|
|
21
|
+
}) => Promise<InFilterValue[]>;
|
|
24
22
|
}
|
|
25
23
|
export declare const PermittedValuesSelector: <Value extends ValueType, IsMulti extends boolean = false>(props: PermittedValuesSelectorProps<Value, IsMulti>) => React.JSX.Element;
|
|
26
24
|
export {};
|