@adaptabletools/adaptable 21.0.11 → 21.1.0-canary.0
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/base.css +1811 -2336
- package/base.css.map +1 -1
- package/index.css +1768 -1413
- package/index.css.map +1 -1
- package/package.json +3 -3
- package/src/AdaptableInterfaces/IAdaptable.d.ts +2 -1
- package/src/AdaptableOptions/FilterOptions.d.ts +7 -0
- package/src/AdaptableOptions/PredicateOptions.d.ts +4 -3
- package/src/AdaptableState/Common/AdaptableColumn.d.ts +1 -1
- package/src/AdaptableState/Common/AdaptablePredicate.d.ts +12 -0
- package/src/AdaptableState/Common/AdaptablePredicate.js +132 -18
- package/src/AdaptableState/Selection/GridCell.d.ts +10 -0
- package/src/Api/Implementation/ExportApiImpl.js +2 -8
- package/src/Api/Implementation/PredicateApiImpl.d.ts +3 -1
- package/src/Api/Implementation/PredicateApiImpl.js +25 -2
- package/src/Api/Internal/AdaptableInternalApi.d.ts +2 -1
- package/src/Api/Internal/AdaptableInternalApi.js +6 -0
- package/src/Api/Internal/PredicateInternalApi.d.ts +3 -1
- package/src/Api/Internal/PredicateInternalApi.js +14 -0
- package/src/Api/PredicateApi.d.ts +1 -1
- package/src/Redux/Store/AdaptableStore.js +111 -3
- package/src/Utilities/Helpers/Helper.js +26 -2
- package/src/Utilities/Hooks/index.d.ts +4 -0
- package/src/Utilities/Hooks/index.js +4 -0
- package/src/Utilities/Hooks/useAdaptableColumn.d.ts +2 -0
- package/src/Utilities/Hooks/useAdaptableColumn.js +6 -0
- package/src/Utilities/Hooks/useAdaptableOptions.d.ts +2 -0
- package/src/Utilities/Hooks/useAdaptableOptions.js +5 -0
- package/src/Utilities/Hooks/useAdaptableState.d.ts +3 -0
- package/src/Utilities/Hooks/useAdaptableState.js +39 -0
- package/src/Utilities/adaptableQlUtils.js +3 -0
- package/src/View/AdaptableComputedCSSVarsContext.d.ts +12 -0
- package/src/View/AdaptableComputedCSSVarsContext.js +25 -0
- package/src/View/Components/AdaptableInput/AdaptableDateInlineInput.d.ts +1 -1
- package/src/View/Components/ColumnFilter/FloatingFilter.js +5 -1
- package/src/View/Components/ColumnFilter/components/FloatingFilterInputList.js +1 -1
- package/src/View/Components/ColumnFilter/components/FloatingFilterValues.js +34 -9
- package/src/View/Components/FilterForm/ListBoxFilterForm.d.ts +1 -0
- package/src/View/Components/FilterForm/ListBoxFilterForm.js +93 -16
- package/src/View/Layout/Wizard/sections/ColumnsSection.js +1 -1
- package/src/View/renderWithAdaptableContext.js +3 -1
- package/src/agGrid/AdaptableAgGrid.d.ts +3 -1
- package/src/agGrid/AdaptableAgGrid.js +361 -24
- package/src/agGrid/AdaptableFilterHandler.d.ts +3 -1
- package/src/agGrid/AdaptableFilterHandler.js +16 -12
- package/src/agGrid/AgGridAdapter.js +12 -6
- package/src/agGrid/AgGridColumnAdapter.js +19 -13
- package/src/components/OverlayTrigger/index.js +1 -1
- package/src/components/Select/Select.js +22 -22
- package/src/components/Tree/TreeDropdown/index.d.ts +27 -0
- package/src/components/Tree/TreeDropdown/index.js +250 -0
- package/src/components/Tree/TreeList/index.d.ts +25 -0
- package/src/components/Tree/TreeList/index.js +35 -0
- package/src/devTools/DevToolsTracks.d.ts +31 -0
- package/src/devTools/DevToolsTracks.js +31 -0
- package/src/devTools/PerfMarker.d.ts +12 -0
- package/src/devTools/PerfMarker.js +1 -0
- package/src/devTools/index.d.ts +102 -0
- package/src/devTools/index.js +159 -0
- package/src/env.js +2 -2
- package/src/layout-manager/src/index.d.ts +2 -0
- package/src/layout-manager/src/index.js +24 -0
- package/tsconfig.esm.tsbuildinfo +1 -1
|
@@ -14,6 +14,26 @@ import { isYesterday } from 'date-fns';
|
|
|
14
14
|
import StringExtensions from '../../Utilities/Extensions/StringExtensions';
|
|
15
15
|
import { parseDateValue } from '../../Utilities/Helpers/DateHelper';
|
|
16
16
|
import Helper from '../../Utilities/Helpers/Helper';
|
|
17
|
+
import { AG_GRID_GROUPED_COLUMN } from '../../Utilities/Constants/GeneralConstants';
|
|
18
|
+
function getGroupValuesForNode(config) {
|
|
19
|
+
const { node, value } = config;
|
|
20
|
+
const groupValues = node.group
|
|
21
|
+
? []
|
|
22
|
+
: /*for the leaf node, also use its value*/ value != null
|
|
23
|
+
? [value]
|
|
24
|
+
: [];
|
|
25
|
+
let currentNode = node.group ? node : node.parent;
|
|
26
|
+
while (currentNode && currentNode.groupData) {
|
|
27
|
+
if (currentNode.treeParent && !currentNode.data) {
|
|
28
|
+
// skip filler groups in tree mode
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
groupValues.unshift(currentNode.groupData[AG_GRID_GROUPED_COLUMN]);
|
|
32
|
+
}
|
|
33
|
+
currentNode = currentNode.parent;
|
|
34
|
+
}
|
|
35
|
+
return groupValues;
|
|
36
|
+
}
|
|
17
37
|
/**
|
|
18
38
|
* Array of Predicate Defs which are shipped by AdapTable
|
|
19
39
|
*/
|
|
@@ -22,7 +42,10 @@ export const SystemPredicateDefs = [
|
|
|
22
42
|
id: 'In',
|
|
23
43
|
label: 'In',
|
|
24
44
|
icon: { text: 'IN' },
|
|
25
|
-
columnScope: {
|
|
45
|
+
columnScope: {
|
|
46
|
+
DataTypes: ['text', 'number', 'date', 'textArray', 'numberArray'],
|
|
47
|
+
ColumnIds: [AG_GRID_GROUPED_COLUMN],
|
|
48
|
+
},
|
|
26
49
|
moduleScope: ['columnFilter', 'flashingcell', 'formatColumn', 'alert', 'badgeStyle'],
|
|
27
50
|
handler: (context) => {
|
|
28
51
|
const { inputs = [], column, value, adaptableApi } = context;
|
|
@@ -59,9 +82,26 @@ export const SystemPredicateDefs = [
|
|
|
59
82
|
if (inputs.length === 0) {
|
|
60
83
|
return true;
|
|
61
84
|
}
|
|
85
|
+
if (column.columnId === AG_GRID_GROUPED_COLUMN) {
|
|
86
|
+
const { node, treeSelectionState } = context;
|
|
87
|
+
const groupValues = getGroupValuesForNode({ node, value });
|
|
88
|
+
if (!treeSelectionState) {
|
|
89
|
+
// in case we don't have treeSelectionState
|
|
90
|
+
// this is another possible implementation
|
|
91
|
+
// though it won't be as performant as using the treeSelectionState
|
|
92
|
+
const currentValues = (groupValues ?? []).join('#');
|
|
93
|
+
return inputs.some((values) => {
|
|
94
|
+
const valuesString = values.join('#');
|
|
95
|
+
return currentValues.startsWith(valuesString);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
const result = groupValues ? treeSelectionState.isNodeSelected(groupValues) : false;
|
|
99
|
+
// console.log('filter', groupValues, 'pass', result, treeSelectionState.getState());
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
62
102
|
if (column.dataType === 'date') {
|
|
63
103
|
return inputs.some((input) => {
|
|
64
|
-
if (adaptableApi.
|
|
104
|
+
if (adaptableApi.predicateApi.internalApi.shouldEvaluateInPredicateUsingTime(column.columnId)) {
|
|
65
105
|
return isEqual(input, value);
|
|
66
106
|
}
|
|
67
107
|
else {
|
|
@@ -78,7 +118,7 @@ export const SystemPredicateDefs = [
|
|
|
78
118
|
return arrayValue.includes(input);
|
|
79
119
|
});
|
|
80
120
|
}
|
|
81
|
-
const useCaseSensitivity = adaptableApi.predicateApi.useCaseSensitivity();
|
|
121
|
+
const useCaseSensitivity = adaptableApi.predicateApi.useCaseSensitivity(column.columnId);
|
|
82
122
|
if (column.dataType === 'text') {
|
|
83
123
|
return useCaseSensitivity
|
|
84
124
|
? inputs
|
|
@@ -101,6 +141,80 @@ export const SystemPredicateDefs = [
|
|
|
101
141
|
toString: ({ inputs }) => `IN (${inputs.join(', ')})`,
|
|
102
142
|
shortcuts: ['#', '['],
|
|
103
143
|
},
|
|
144
|
+
// {
|
|
145
|
+
// id: 'Tree',
|
|
146
|
+
// label: 'Tree',
|
|
147
|
+
// icon: { text: 'Tree' },
|
|
148
|
+
// columnScope: { DataTypes: ['date'] },
|
|
149
|
+
// moduleScope: ['columnFilter', 'flashingcell', 'formatColumn', 'alert'],
|
|
150
|
+
// handler: (context) => {
|
|
151
|
+
// const { inputs = [], column, value, adaptableApi } = context;
|
|
152
|
+
// const predicateInputs = (context.inputs || []).reduce<AdaptablePredicateDef[]>(
|
|
153
|
+
// (acc, input) => {
|
|
154
|
+
// const predicate = adaptableApi.predicateApi.getPredicateDefById(input);
|
|
155
|
+
// if (predicate) {
|
|
156
|
+
// acc.push(predicate);
|
|
157
|
+
// }
|
|
158
|
+
// return acc;
|
|
159
|
+
// },
|
|
160
|
+
// []
|
|
161
|
+
// );
|
|
162
|
+
// if (predicateInputs.length) {
|
|
163
|
+
// const nestedContext = { ...context };
|
|
164
|
+
// delete nestedContext.inputs;
|
|
165
|
+
// const predicateResult = predicateInputs.some((predicate) => {
|
|
166
|
+
// return adaptableApi.predicateApi.handlePredicate(
|
|
167
|
+
// {
|
|
168
|
+
// PredicateId: predicate.id,
|
|
169
|
+
// },
|
|
170
|
+
// nestedContext,
|
|
171
|
+
// false
|
|
172
|
+
// );
|
|
173
|
+
// });
|
|
174
|
+
// if (predicateResult) {
|
|
175
|
+
// // We want to use the only true values, to allow for multiple predicates to be used
|
|
176
|
+
// return predicateResult;
|
|
177
|
+
// }
|
|
178
|
+
// }
|
|
179
|
+
// if (inputs.length === 0) {
|
|
180
|
+
// return true;
|
|
181
|
+
// }
|
|
182
|
+
// if (column.dataType === 'date') {
|
|
183
|
+
// const treeSelectionState = new TreeSelectionState(
|
|
184
|
+
// {
|
|
185
|
+
// defaultSelection: false,
|
|
186
|
+
// // make sure something like
|
|
187
|
+
// // Predicates: [{ PredicateId: 'Tree', Inputs: [['2021', '2'], ['2022']] }],
|
|
188
|
+
// // is always converted to numbers
|
|
189
|
+
// selectedPaths: inputs
|
|
190
|
+
// .map((array) => {
|
|
191
|
+
// if (!Array.isArray(array)) {
|
|
192
|
+
// return null;
|
|
193
|
+
// }
|
|
194
|
+
// return array.map(Number);
|
|
195
|
+
// })
|
|
196
|
+
// .filter(Boolean),
|
|
197
|
+
// },
|
|
198
|
+
// () => {
|
|
199
|
+
// return {
|
|
200
|
+
// treeDeepMap: new DeepMap<string, any>(),
|
|
201
|
+
// treePaths: new DeepMap<string, any>(),
|
|
202
|
+
// };
|
|
203
|
+
// }
|
|
204
|
+
// );
|
|
205
|
+
// const currrentDate = parseDateValue(value);
|
|
206
|
+
// const currentYear = currrentDate.getFullYear();
|
|
207
|
+
// const currentMonth = currrentDate.getMonth() + 1;
|
|
208
|
+
// const currentDay = currrentDate.getDate();
|
|
209
|
+
// const result = treeSelectionState.isNodeSelected([currentYear, currentMonth, currentDay]);
|
|
210
|
+
// // console.log({ currentYear, currentMonth, currentDay, result, inputs: inputs.join('-') });
|
|
211
|
+
// return result;
|
|
212
|
+
// }
|
|
213
|
+
// return true;
|
|
214
|
+
// },
|
|
215
|
+
// toString: ({ inputs }) => `IN Tree (${inputs.join(', ')})`,
|
|
216
|
+
// shortcuts: ['#', '['],
|
|
217
|
+
// },
|
|
104
218
|
{
|
|
105
219
|
id: 'NotIn',
|
|
106
220
|
label: 'Not In',
|
|
@@ -145,7 +259,7 @@ export const SystemPredicateDefs = [
|
|
|
145
259
|
return true;
|
|
146
260
|
}
|
|
147
261
|
if (column.dataType === 'date') {
|
|
148
|
-
if (adaptableApi.
|
|
262
|
+
if (adaptableApi.predicateApi.useCaseSensitivity(column.columnId)) {
|
|
149
263
|
return inputs.every((input) => {
|
|
150
264
|
return !isEqual(input, value);
|
|
151
265
|
});
|
|
@@ -166,7 +280,7 @@ export const SystemPredicateDefs = [
|
|
|
166
280
|
});
|
|
167
281
|
}
|
|
168
282
|
if (column.dataType === 'text') {
|
|
169
|
-
return adaptableApi.predicateApi.useCaseSensitivity()
|
|
283
|
+
return adaptableApi.predicateApi.useCaseSensitivity(column.columnId)
|
|
170
284
|
? !inputs
|
|
171
285
|
.map((i) => {
|
|
172
286
|
return i?.toLocaleLowerCase();
|
|
@@ -177,7 +291,7 @@ export const SystemPredicateDefs = [
|
|
|
177
291
|
if (column.dataType === 'textArray') {
|
|
178
292
|
const arrayValue = Array.isArray(value) ? value : [value];
|
|
179
293
|
return inputs.every((input) => {
|
|
180
|
-
return adaptableApi.predicateApi.useCaseSensitivity()
|
|
294
|
+
return adaptableApi.predicateApi.useCaseSensitivity(column.columnId)
|
|
181
295
|
? !arrayValue.map((v) => v?.toLocaleLowerCase()).includes(input?.toLocaleLowerCase())
|
|
182
296
|
: !arrayValue.includes(input);
|
|
183
297
|
});
|
|
@@ -333,11 +447,11 @@ export const SystemPredicateDefs = [
|
|
|
333
447
|
columnScope: { DataTypes: ['text'] },
|
|
334
448
|
moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
|
|
335
449
|
inputs: [{ type: 'text' }],
|
|
336
|
-
handler: ({ value, inputs, adaptableApi }) => {
|
|
450
|
+
handler: ({ value, inputs, adaptableApi, column }) => {
|
|
337
451
|
if (!value) {
|
|
338
452
|
return false;
|
|
339
453
|
}
|
|
340
|
-
const ignoreCase = !adaptableApi.predicateApi.
|
|
454
|
+
const ignoreCase = !adaptableApi.predicateApi.internalApi.shouldUseCaseSensitivePredicates(column);
|
|
341
455
|
const v = ignoreCase ? String(value).toLocaleLowerCase() : String(value);
|
|
342
456
|
const i = ignoreCase ? String(inputs[0]).toLocaleLowerCase() : String(inputs[0]);
|
|
343
457
|
return v == i;
|
|
@@ -352,11 +466,11 @@ export const SystemPredicateDefs = [
|
|
|
352
466
|
columnScope: { DataTypes: ['text'] },
|
|
353
467
|
moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
|
|
354
468
|
inputs: [{ type: 'text' }],
|
|
355
|
-
handler: ({ value, inputs, adaptableApi }) => {
|
|
469
|
+
handler: ({ value, inputs, adaptableApi, column }) => {
|
|
356
470
|
if (!value) {
|
|
357
471
|
return true;
|
|
358
472
|
}
|
|
359
|
-
const ignoreCase = !adaptableApi.predicateApi.
|
|
473
|
+
const ignoreCase = !adaptableApi.predicateApi.internalApi.shouldUseCaseSensitivePredicates(column);
|
|
360
474
|
const v = ignoreCase ? String(value).toLocaleLowerCase() : String(value);
|
|
361
475
|
const i = ignoreCase ? String(inputs[0]).toLocaleLowerCase() : String(inputs[0]);
|
|
362
476
|
return v != i;
|
|
@@ -371,11 +485,11 @@ export const SystemPredicateDefs = [
|
|
|
371
485
|
columnScope: { DataTypes: ['text'] },
|
|
372
486
|
moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
|
|
373
487
|
inputs: [{ type: 'text' }],
|
|
374
|
-
handler: ({ value, inputs, adaptableApi }) => {
|
|
488
|
+
handler: ({ value, inputs, adaptableApi, column }) => {
|
|
375
489
|
if (!value) {
|
|
376
490
|
return false;
|
|
377
491
|
}
|
|
378
|
-
const ignoreCase = !adaptableApi.predicateApi.
|
|
492
|
+
const ignoreCase = !adaptableApi.predicateApi.internalApi.shouldUseCaseSensitivePredicates(column);
|
|
379
493
|
const v = ignoreCase ? String(value).toLocaleLowerCase() : String(value);
|
|
380
494
|
const i = ignoreCase ? String(inputs[0]).toLocaleLowerCase() : String(inputs[0]);
|
|
381
495
|
return v.indexOf(i) !== -1;
|
|
@@ -389,11 +503,11 @@ export const SystemPredicateDefs = [
|
|
|
389
503
|
columnScope: { DataTypes: ['text'] },
|
|
390
504
|
moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
|
|
391
505
|
inputs: [{ type: 'text' }],
|
|
392
|
-
handler: ({ value, inputs, adaptableApi }) => {
|
|
506
|
+
handler: ({ value, inputs, adaptableApi, column }) => {
|
|
393
507
|
if (!value) {
|
|
394
508
|
return true;
|
|
395
509
|
}
|
|
396
|
-
const ignoreCase = !adaptableApi.predicateApi.
|
|
510
|
+
const ignoreCase = !adaptableApi.predicateApi.internalApi.shouldUseCaseSensitivePredicates(column);
|
|
397
511
|
const v = ignoreCase ? String(value).toLocaleLowerCase() : String(value);
|
|
398
512
|
const i = ignoreCase ? String(inputs[0]).toLocaleLowerCase() : String(inputs[0]);
|
|
399
513
|
return v.indexOf(i) === -1;
|
|
@@ -407,11 +521,11 @@ export const SystemPredicateDefs = [
|
|
|
407
521
|
columnScope: { DataTypes: ['text'] },
|
|
408
522
|
moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
|
|
409
523
|
inputs: [{ type: 'text' }],
|
|
410
|
-
handler: ({ value, inputs, adaptableApi }) => {
|
|
524
|
+
handler: ({ value, inputs, adaptableApi, column }) => {
|
|
411
525
|
if (!value) {
|
|
412
526
|
return false;
|
|
413
527
|
}
|
|
414
|
-
const ignoreCase = !adaptableApi.predicateApi.
|
|
528
|
+
const ignoreCase = !adaptableApi.predicateApi.internalApi.shouldUseCaseSensitivePredicates(column);
|
|
415
529
|
const v = ignoreCase ? String(value).toLocaleLowerCase() : String(value);
|
|
416
530
|
const i = ignoreCase ? String(inputs[0]).toLocaleLowerCase() : String(inputs[0]);
|
|
417
531
|
return v.startsWith(i);
|
|
@@ -425,11 +539,11 @@ export const SystemPredicateDefs = [
|
|
|
425
539
|
columnScope: { DataTypes: ['text'] },
|
|
426
540
|
moduleScope: ['columnFilter', 'alert', 'flashingcell', 'formatColumn', 'badgeStyle'],
|
|
427
541
|
inputs: [{ type: 'text' }],
|
|
428
|
-
handler: ({ value, inputs, adaptableApi }) => {
|
|
542
|
+
handler: ({ value, inputs, adaptableApi, column }) => {
|
|
429
543
|
if (!value) {
|
|
430
544
|
return false;
|
|
431
545
|
}
|
|
432
|
-
const ignoreCase = !adaptableApi.predicateApi.
|
|
546
|
+
const ignoreCase = !adaptableApi.predicateApi.internalApi.shouldUseCaseSensitivePredicates(column);
|
|
433
547
|
const v = ignoreCase ? String(value).toLocaleLowerCase() : String(value);
|
|
434
548
|
const i = ignoreCase ? String(inputs[0]).toLocaleLowerCase() : String(inputs[0]);
|
|
435
549
|
return v.endsWith(i);
|
|
@@ -64,6 +64,16 @@ export interface GridCellWithCount extends GridCell {
|
|
|
64
64
|
*/
|
|
65
65
|
visibleCount?: number;
|
|
66
66
|
}
|
|
67
|
+
export interface GridCellWithChildren extends GridCell {
|
|
68
|
+
/**
|
|
69
|
+
* Children of Cell
|
|
70
|
+
*/
|
|
71
|
+
children?: GridCellWithChildren[];
|
|
72
|
+
/**
|
|
73
|
+
* For the grouping scenario, how many leafs are there under this item
|
|
74
|
+
*/
|
|
75
|
+
leafChildrenCount?: number;
|
|
76
|
+
}
|
|
67
77
|
export interface UniqueGridCell<TData = any> {
|
|
68
78
|
/**
|
|
69
79
|
* Raw value of Cell
|
|
@@ -2,7 +2,7 @@ import * as ExportRedux from '../../Redux/ActionsReducers/ExportRedux';
|
|
|
2
2
|
import { ApiBase } from './ApiBase';
|
|
3
3
|
import * as ModuleConstants from '../../Utilities/Constants/ModuleConstants';
|
|
4
4
|
import { ExportInternalApi } from '../Internal/ExportInternalApi';
|
|
5
|
-
import { ALL_DATA_REPORT, CLIPBOARD_EXPORT_DESTINATION, DOWNLOAD_EXPORT_DESTINATION, EMPTY_STRING, SYSTEM_EXPORT_DESTINATIONS, SYSTEM_REPORT_FORMATS, SYSTEM_REPORT_NAMES,
|
|
5
|
+
import { ALL_DATA_REPORT, CLIPBOARD_EXPORT_DESTINATION, DOWNLOAD_EXPORT_DESTINATION, EMPTY_STRING, SYSTEM_EXPORT_DESTINATIONS, SYSTEM_REPORT_FORMATS, SYSTEM_REPORT_NAMES, } from '../../Utilities/Constants/GeneralConstants';
|
|
6
6
|
export class ExportApiImpl extends ApiBase {
|
|
7
7
|
constructor(_adaptable) {
|
|
8
8
|
super(_adaptable);
|
|
@@ -85,13 +85,7 @@ export class ExportApiImpl extends ApiBase {
|
|
|
85
85
|
currentReportFormat: this.getExportApi().getCurrentReportFormat(),
|
|
86
86
|
})
|
|
87
87
|
: systemExportDestinationsOption;
|
|
88
|
-
return systemExportDestinations
|
|
89
|
-
// VisualExcel format can't be exported to custom destinations
|
|
90
|
-
if (this.getExportApi().getCurrentReportFormat() === VISUAL_EXCEL_FORMAT_REPORT) {
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
return true;
|
|
94
|
-
});
|
|
88
|
+
return systemExportDestinations;
|
|
95
89
|
}
|
|
96
90
|
getAvailableCustomDestinations() {
|
|
97
91
|
const customDestinationsOption = this.getExportOptions().customDestinations;
|
|
@@ -3,6 +3,8 @@ import { PredicateApi } from '../PredicateApi';
|
|
|
3
3
|
import { AdaptableColumnPredicate, AdaptablePredicate, AdaptablePredicateDef, PredicateDefHandlerContext, PredicateModuleScope } from '../../types';
|
|
4
4
|
import { IAdaptable } from '../../AdaptableInterfaces/IAdaptable';
|
|
5
5
|
import { PredicateInternalApi } from '../Internal/PredicateInternalApi';
|
|
6
|
+
import { TreeSelectionState } from '@infinite-table/infinite-react';
|
|
7
|
+
export declare const getTreeSelectionStateForPredicateInputs: (inputs: any[], cache?: WeakMap<any[], TreeSelectionState>) => TreeSelectionState<any>;
|
|
6
8
|
export declare class PredicateApiImpl extends ApiBase implements PredicateApi {
|
|
7
9
|
internalApi: PredicateInternalApi;
|
|
8
10
|
constructor(_adaptable: IAdaptable);
|
|
@@ -22,5 +24,5 @@ export declare class PredicateApiImpl extends ApiBase implements PredicateApi {
|
|
|
22
24
|
handleColumnPredicates(predicates: AdaptableColumnPredicate[], context: Omit<PredicateDefHandlerContext, 'adaptableApi' | 'inputs'>, defaultReturn: boolean): boolean;
|
|
23
25
|
handlePredicate(predicate: AdaptablePredicate | undefined, context: Omit<PredicateDefHandlerContext, 'adaptableApi' | 'inputs'>, defaultReturn: boolean): boolean;
|
|
24
26
|
handlePredicates(predicates: AdaptablePredicate[], params: Omit<PredicateDefHandlerContext, 'adaptableApi' | 'inputs'>, defaultReturn: boolean): boolean;
|
|
25
|
-
useCaseSensitivity(): boolean;
|
|
27
|
+
useCaseSensitivity(columnId: string): boolean;
|
|
26
28
|
}
|
|
@@ -3,6 +3,24 @@ import ArrayExtensions from '../../Utilities/Extensions/ArrayExtensions';
|
|
|
3
3
|
import StringExtensions from '../../Utilities/Extensions/StringExtensions';
|
|
4
4
|
import { PredicateInternalApi } from '../Internal/PredicateInternalApi';
|
|
5
5
|
import { SystemPredicateDefs } from '../../AdaptableState/Common/AdaptablePredicate';
|
|
6
|
+
import { AG_GRID_GROUPED_COLUMN } from '../../Utilities/Constants/GeneralConstants';
|
|
7
|
+
import { TreeSelectionState } from '@infinite-table/infinite-react';
|
|
8
|
+
const treeSelectionStatesForPredicates = new WeakMap();
|
|
9
|
+
export const getTreeSelectionStateForPredicateInputs = (inputs, cache = treeSelectionStatesForPredicates) => {
|
|
10
|
+
const treeSelectionState = cache.get(inputs);
|
|
11
|
+
if (treeSelectionState) {
|
|
12
|
+
return treeSelectionState;
|
|
13
|
+
}
|
|
14
|
+
const newTreeSelectionState = new TreeSelectionState({
|
|
15
|
+
defaultSelection: false,
|
|
16
|
+
selectedPaths: inputs,
|
|
17
|
+
}, {
|
|
18
|
+
treePaths: inputs,
|
|
19
|
+
strictCheckPaths: false,
|
|
20
|
+
});
|
|
21
|
+
cache.set(inputs, newTreeSelectionState);
|
|
22
|
+
return newTreeSelectionState;
|
|
23
|
+
};
|
|
6
24
|
export class PredicateApiImpl extends ApiBase {
|
|
7
25
|
constructor(_adaptable) {
|
|
8
26
|
super(_adaptable);
|
|
@@ -125,10 +143,15 @@ export class PredicateApiImpl extends ApiBase {
|
|
|
125
143
|
if (predicateDef.inputs?.some((_, i) => predicate.Inputs?.[i] === undefined || predicate.Inputs?.[i] === '')) {
|
|
126
144
|
return defaultReturn;
|
|
127
145
|
}
|
|
146
|
+
let treeSelectionState;
|
|
147
|
+
if (context.column.columnId === AG_GRID_GROUPED_COLUMN && predicate.PredicateId === 'In') {
|
|
148
|
+
treeSelectionState = getTreeSelectionStateForPredicateInputs(predicate.Inputs);
|
|
149
|
+
}
|
|
128
150
|
try {
|
|
129
151
|
return predicateDef.handler({
|
|
130
152
|
adaptableApi: this.getAdaptableApi(),
|
|
131
153
|
inputs: predicate.Inputs,
|
|
154
|
+
treeSelectionState,
|
|
132
155
|
...context,
|
|
133
156
|
});
|
|
134
157
|
}
|
|
@@ -146,7 +169,7 @@ export class PredicateApiImpl extends ApiBase {
|
|
|
146
169
|
}
|
|
147
170
|
return predicates?.every((p) => this.handlePredicate(p, params, defaultReturn));
|
|
148
171
|
}
|
|
149
|
-
useCaseSensitivity() {
|
|
150
|
-
return this.
|
|
172
|
+
useCaseSensitivity(columnId) {
|
|
173
|
+
return this.internalApi.shouldUseCaseSensitivePredicates(columnId);
|
|
151
174
|
}
|
|
152
175
|
}
|
|
@@ -23,7 +23,7 @@ import { AdaptableFrameworkComponent } from '../../agGrid/AdaptableFrameworkComp
|
|
|
23
23
|
import { IMetamodelService } from '../../Utilities/Services/Interface/IMetamodelService';
|
|
24
24
|
import { IModuleCollection } from '../../Strategy/Interface/IModule';
|
|
25
25
|
import { AdaptableObjectTag, AdaptableObjectWithScope } from '../../AdaptableState/Common/AdaptableObject';
|
|
26
|
-
import { AdaptableForm, CellSummmaryInfo, FormContext, RowDataChangeTrigger, RowDataChangedInfo } from '../../../types';
|
|
26
|
+
import { AdaptableForm, CellSummmaryInfo, FormContext, RowDataChangeTrigger, RowDataChangedInfo, AdaptableColumn, AdaptableColumnContext } from '../../../types';
|
|
27
27
|
import { Fdc3Service } from '../../Utilities/Services/Fdc3Service';
|
|
28
28
|
import { AnnotationsService } from '../../Utilities/Services/AnnotationsService';
|
|
29
29
|
import { RowFormService } from '../../Utilities/Services/RowFormService';
|
|
@@ -122,6 +122,7 @@ export declare class AdaptableInternalApi extends ApiBase {
|
|
|
122
122
|
setValueUsingField(rowData: Record<string, any>, fieldName: string, newValue: any): Record<string, any>;
|
|
123
123
|
findAdaptableObjectsByLookupCriteria<T extends AdaptableObjectWithScope>({ scope, tag, ids }: AdaptableObjectLookupCriteria, specificAdaptableObjects: T[]): T[];
|
|
124
124
|
buildBaseContext(): BaseContext;
|
|
125
|
+
buildAdaptableColumnContext(column: AdaptableColumn<any> | string): AdaptableColumnContext;
|
|
125
126
|
setCellSummaryInfo(cellSummaryInfo: CellSummmaryInfo): void;
|
|
126
127
|
parseDateValue(dateValue: string | Date | number): Date | undefined;
|
|
127
128
|
}
|
|
@@ -437,6 +437,12 @@ export class AdaptableInternalApi extends ApiBase {
|
|
|
437
437
|
clientTimestamp: new Date(),
|
|
438
438
|
};
|
|
439
439
|
}
|
|
440
|
+
buildAdaptableColumnContext(column) {
|
|
441
|
+
return {
|
|
442
|
+
...this.buildBaseContext(),
|
|
443
|
+
column: typeof column === 'string' ? this.getColumnApi().getColumnWithColumnId(column) : column,
|
|
444
|
+
};
|
|
445
|
+
}
|
|
440
446
|
setCellSummaryInfo(cellSummaryInfo) {
|
|
441
447
|
this.dispatchAction(InternalRedux.SetCellSummaryInfo(cellSummaryInfo));
|
|
442
448
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ApiBase } from '../Implementation/ApiBase';
|
|
2
2
|
import { AdaptablePredicate, AdaptablePredicateDef } from '../../AdaptableState/Common/AdaptablePredicate';
|
|
3
3
|
import { SystemFilterPredicateId } from '../../AdaptableState/Common/ColumnFilter';
|
|
4
|
-
import { AdaptableColumnDataType } from '../../AdaptableState/Common/AdaptableColumn';
|
|
4
|
+
import { AdaptableColumn, AdaptableColumnDataType } from '../../AdaptableState/Common/AdaptableColumn';
|
|
5
5
|
import { ColumnScope } from '../../types';
|
|
6
6
|
export declare class PredicateInternalApi extends ApiBase {
|
|
7
7
|
IsInOrNotInPredicate(predicate: AdaptablePredicate): boolean;
|
|
@@ -10,6 +10,8 @@ export declare class PredicateInternalApi extends ApiBase {
|
|
|
10
10
|
* Get all Filter Predicate Definitions - System and Custom
|
|
11
11
|
*/
|
|
12
12
|
getFilterPredicateDefs(scope: ColumnScope): AdaptablePredicateDef[];
|
|
13
|
+
shouldUseCaseSensitivePredicates(column: string | AdaptableColumn): boolean;
|
|
14
|
+
shouldEvaluateInPredicateUsingTime(column: string | AdaptableColumn): boolean;
|
|
13
15
|
private getSystemFilterPredicateIds;
|
|
14
16
|
/**
|
|
15
17
|
* Get all Alert Predicate Definitions - System and Custom
|
|
@@ -12,6 +12,20 @@ export class PredicateInternalApi extends ApiBase {
|
|
|
12
12
|
getFilterPredicateDefs(scope) {
|
|
13
13
|
return this.mergeSystemAndCustomPredicates(this.getSystemFilterPredicateIds(scope)?.map((predicateId) => this.getPredicateApi().getPredicateDefById(predicateId)), this.getPredicateApi().getCustomPredicateDefs()).filter((predicateDef) => predicateDef.moduleScope.includes('columnFilter'));
|
|
14
14
|
}
|
|
15
|
+
shouldUseCaseSensitivePredicates(column) {
|
|
16
|
+
const caseSensitivePredicates = this.getPredicateOptions().caseSensitivePredicates;
|
|
17
|
+
if (typeof caseSensitivePredicates === 'function') {
|
|
18
|
+
return caseSensitivePredicates(this.getAdaptableInternalApi().buildAdaptableColumnContext(column));
|
|
19
|
+
}
|
|
20
|
+
return caseSensitivePredicates;
|
|
21
|
+
}
|
|
22
|
+
shouldEvaluateInPredicateUsingTime(column) {
|
|
23
|
+
const evaluateInPredicateUsingTime = this.getPredicateOptions().evaluateInPredicateUsingTime;
|
|
24
|
+
if (typeof evaluateInPredicateUsingTime === 'function') {
|
|
25
|
+
return evaluateInPredicateUsingTime(this.getAdaptableInternalApi().buildAdaptableColumnContext(column));
|
|
26
|
+
}
|
|
27
|
+
return evaluateInPredicateUsingTime;
|
|
28
|
+
}
|
|
15
29
|
getSystemFilterPredicateIds(scope) {
|
|
16
30
|
const systemFilterPredicates = this.getPredicateOptions().systemFilterPredicates;
|
|
17
31
|
if (typeof systemFilterPredicates === 'function') {
|
|
@@ -38,6 +38,7 @@ import * as InternalRedux from '../ActionsReducers/InternalRedux';
|
|
|
38
38
|
import * as TeamSharingRedux from '../ActionsReducers/TeamSharingRedux';
|
|
39
39
|
import * as ThemeRedux from '../ActionsReducers/ThemeRedux';
|
|
40
40
|
import * as ToolPanelRedux from '../ActionsReducers/ToolPanelRedux';
|
|
41
|
+
import { areAdaptableProfileTracksEnabled, getMarker } from '../../devTools';
|
|
41
42
|
import { isAdaptableSharedEntity, isCustomSharedEntity, } from '../../AdaptableState/TeamSharingState';
|
|
42
43
|
import { buildAdaptableStateFunctionConfig } from './buildAdaptableStateFunctionConfig';
|
|
43
44
|
const INIT_STATE = 'INIT_STATE';
|
|
@@ -227,17 +228,21 @@ export class AdaptableStore {
|
|
|
227
228
|
}
|
|
228
229
|
return finalState;
|
|
229
230
|
};
|
|
231
|
+
const devToolsActionMarkerMiddleware = createDevToolsActionMarkerMiddleware(adaptable);
|
|
230
232
|
const pluginsMiddleware = [];
|
|
231
233
|
adaptable.forPlugins((plugin) => {
|
|
232
234
|
if (plugin.reduxMiddleware) {
|
|
233
235
|
pluginsMiddleware.push(plugin.reduxMiddleware(adaptable));
|
|
234
236
|
}
|
|
235
237
|
});
|
|
238
|
+
const middlewares = [
|
|
239
|
+
devToolsActionMarkerMiddleware,
|
|
240
|
+
adaptableMiddleware(adaptable), // the main middleware that actually does stuff,
|
|
241
|
+
...pluginsMiddleware, // the plugins middleware
|
|
242
|
+
].filter(Boolean);
|
|
236
243
|
//TODO: need to check if we want the storage to be done before or after
|
|
237
244
|
//we enrich the state with the AB middleware
|
|
238
|
-
this.TheStore = Redux.createStore(persistedReducer, composeEnhancers(Redux.applyMiddleware(
|
|
239
|
-
...pluginsMiddleware // the plugins middleware
|
|
240
|
-
)));
|
|
245
|
+
this.TheStore = Redux.createStore(persistedReducer, composeEnhancers(Redux.applyMiddleware(...middlewares)));
|
|
241
246
|
this.storageEngine = storageEngine;
|
|
242
247
|
}
|
|
243
248
|
destroy() {
|
|
@@ -258,6 +263,109 @@ export class AdaptableStore {
|
|
|
258
263
|
return Promise.resolve(true);
|
|
259
264
|
}
|
|
260
265
|
}
|
|
266
|
+
function createDevToolsActionMarkerMiddleware(adaptable) {
|
|
267
|
+
const adaptableId = adaptable?.adaptableOptions?.adaptableId;
|
|
268
|
+
if (!adaptableId) {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
if (!areAdaptableProfileTracksEnabled(adaptableId)) {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
return (middlewareAPI) => (next) => (action) => {
|
|
275
|
+
if (!isTrackableReduxAction(action)) {
|
|
276
|
+
return next(action);
|
|
277
|
+
}
|
|
278
|
+
const previousState = middlewareAPI.getState();
|
|
279
|
+
const marker = getMarker(adaptableId).track.Redux.label.Action.start();
|
|
280
|
+
try {
|
|
281
|
+
return next(action);
|
|
282
|
+
}
|
|
283
|
+
finally {
|
|
284
|
+
const nextState = middlewareAPI.getState();
|
|
285
|
+
const changedKeys = detectChangedAdaptableStateKeys(previousState, nextState);
|
|
286
|
+
const details = buildDevToolsActionDetails(action, changedKeys);
|
|
287
|
+
marker.end({
|
|
288
|
+
label: action.type,
|
|
289
|
+
tooltip: changedKeys?.length ? `State changes: ${changedKeys.join(', ')}` : undefined,
|
|
290
|
+
details: details.length ? details : undefined,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
const MAX_MARKER_DETAILS = 6;
|
|
296
|
+
function buildDevToolsActionDetails(action, changedKeys) {
|
|
297
|
+
const details = [];
|
|
298
|
+
if (changedKeys && changedKeys.length > 0) {
|
|
299
|
+
const truncatedKeys = changedKeys.slice(0, MAX_MARKER_DETAILS);
|
|
300
|
+
const suffix = changedKeys.length > truncatedKeys.length
|
|
301
|
+
? ` +${changedKeys.length - truncatedKeys.length} more`
|
|
302
|
+
: '';
|
|
303
|
+
details.push({
|
|
304
|
+
name: 'State changes',
|
|
305
|
+
value: `${truncatedKeys.join(', ')}${suffix}`,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
if (isActionWithPayload(action)) {
|
|
309
|
+
const entries = Object.entries(action).filter(([key]) => key !== 'type');
|
|
310
|
+
for (const [key, value] of entries) {
|
|
311
|
+
if (details.length >= MAX_MARKER_DETAILS) {
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
details.push({
|
|
315
|
+
name: `action.${key}`,
|
|
316
|
+
value: coerceMarkerDetailValue(value),
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return details;
|
|
321
|
+
}
|
|
322
|
+
function detectChangedAdaptableStateKeys(previousState, nextState) {
|
|
323
|
+
if (!previousState || !nextState || previousState === nextState) {
|
|
324
|
+
return undefined;
|
|
325
|
+
}
|
|
326
|
+
const previous = previousState;
|
|
327
|
+
const next = nextState;
|
|
328
|
+
const keys = new Set([...Object.keys(previous), ...Object.keys(next)]);
|
|
329
|
+
const changed = [];
|
|
330
|
+
keys.forEach((key) => {
|
|
331
|
+
if (previous[key] !== next[key]) {
|
|
332
|
+
changed.push(key);
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
return changed.length > 0 ? changed : undefined;
|
|
336
|
+
}
|
|
337
|
+
function isTrackableReduxAction(action) {
|
|
338
|
+
return !!action && typeof action.type === 'string';
|
|
339
|
+
}
|
|
340
|
+
function isActionWithPayload(action) {
|
|
341
|
+
return !!action && typeof action === 'object';
|
|
342
|
+
}
|
|
343
|
+
function coerceMarkerDetailValue(value) {
|
|
344
|
+
if (value === null) {
|
|
345
|
+
return 'null';
|
|
346
|
+
}
|
|
347
|
+
if (value === undefined) {
|
|
348
|
+
return 'undefined';
|
|
349
|
+
}
|
|
350
|
+
const valueType = typeof value;
|
|
351
|
+
if (valueType === 'string' || valueType === 'number' || valueType === 'boolean') {
|
|
352
|
+
return value;
|
|
353
|
+
}
|
|
354
|
+
if (valueType === 'function') {
|
|
355
|
+
return '[function]';
|
|
356
|
+
}
|
|
357
|
+
try {
|
|
358
|
+
const json = JSON.stringify(value);
|
|
359
|
+
if (!json) {
|
|
360
|
+
return '[empty]';
|
|
361
|
+
}
|
|
362
|
+
const MAX_LENGTH = 200;
|
|
363
|
+
return json.length > MAX_LENGTH ? `${json.slice(0, MAX_LENGTH - 3)}...` : json;
|
|
364
|
+
}
|
|
365
|
+
catch (err) {
|
|
366
|
+
return '[unserializable]';
|
|
367
|
+
}
|
|
368
|
+
}
|
|
261
369
|
// this is the main function for dealing with Redux Actions which require additional functionality to be triggered.
|
|
262
370
|
// Please document each use case where we have to use the Store rather than a module or a popup screen
|
|
263
371
|
// This should ideally be the ONLY place where we LISTEN to store changes
|
|
@@ -88,8 +88,32 @@ export async function copyToClipboard(text) {
|
|
|
88
88
|
return true;
|
|
89
89
|
}
|
|
90
90
|
catch (ex) {
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
return copyToClipboardForOldBrowsers(text);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function copyToClipboardForOldBrowsers(text) {
|
|
95
|
+
if (document.queryCommandSupported && document.queryCommandSupported('copy')) {
|
|
96
|
+
let textarea = document.createElement('textarea');
|
|
97
|
+
textarea.textContent = text;
|
|
98
|
+
textarea.style.width = '1px';
|
|
99
|
+
textarea.style.height = '1px';
|
|
100
|
+
textarea.style.top = '0px';
|
|
101
|
+
textarea.style.left = '0px';
|
|
102
|
+
textarea.style.position = 'absolute';
|
|
103
|
+
textarea.style.opacity = '0.0';
|
|
104
|
+
document.body.appendChild(textarea);
|
|
105
|
+
textarea.select();
|
|
106
|
+
textarea.focus();
|
|
107
|
+
try {
|
|
108
|
+
return document.execCommand('copy'); // Security exception may be thrown by some browsers.
|
|
109
|
+
}
|
|
110
|
+
catch (ex) {
|
|
111
|
+
AdaptableLogger.consoleErrorBase('Copy to clipboard failed.', ex);
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
document.body.removeChild(textarea);
|
|
116
|
+
}
|
|
93
117
|
}
|
|
94
118
|
}
|
|
95
119
|
export function returnItemCount(items, itemName) {
|