@adaptabletools/adaptable 11.2.0 → 11.2.1-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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptabletools/adaptable",
3
- "version": "11.2.0",
3
+ "version": "11.2.1-canary.0",
4
4
  "description": "Powerful data-agnostic HTML5 datagrid add-on that sits on top of an underlying grid component and provides all the rich functionality that advanced users expect from their DataGrids and Data Tables",
5
5
  "keywords": [
6
6
  "web-components",
@@ -1,2 +1,2 @@
1
- declare const _default: 1652269439987;
1
+ declare const _default: 1652703967435;
2
2
  export default _default;
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = 1652269439987;
3
+ exports.default = 1652703967435;
@@ -7,10 +7,10 @@ export declare class AlertService implements IAlertService {
7
7
  private emitter;
8
8
  private reactiveAlertsMap;
9
9
  constructor(adaptableApi: AdaptableApi);
10
+ destroy(): void;
10
11
  onReactiveAlertTriggered: (callback: EmitterCallback) => (() => void);
11
12
  createReactiveAlert(alertDefinition: AlertDefinition): void;
12
13
  deleteReactiveAlert(alertDefinition: AlertDefinition): void;
13
- destroy(): void;
14
14
  private isValidExpression;
15
15
  private evaluateReactiveExpression;
16
16
  }
@@ -15,6 +15,13 @@ class AlertService {
15
15
  };
16
16
  this.emitter = new Emitter_1.default();
17
17
  }
18
+ destroy() {
19
+ this.emitter.destroy();
20
+ this.emitter = null;
21
+ this.reactiveAlertsMap.forEach((alertsSubscriptionInfo) => alertsSubscriptionInfo.subscription.unsubscribe());
22
+ this.reactiveAlertsMap.clear();
23
+ this.reactiveAlertsMap = null;
24
+ }
18
25
  createReactiveAlert(alertDefinition) {
19
26
  // if there is already a reactive alert for this definition, delete it (possible in case of editing definitions),
20
27
  this.deleteReactiveAlert(alertDefinition);
@@ -51,11 +58,6 @@ class AlertService {
51
58
  this.reactiveAlertsMap.delete(alertDefinition.Uuid);
52
59
  }
53
60
  }
54
- destroy() {
55
- this.emitter.destroy();
56
- this.emitter = null;
57
- this.reactiveAlertsMap.forEach((alertsSubscriptionInfo) => alertsSubscriptionInfo.subscription.unsubscribe());
58
- }
59
61
  isValidExpression(rule) {
60
62
  return rule.ObservableExpression
61
63
  ? this.adaptableApi.queryLanguageApi.isValidObservableExpression(rule.ObservableExpression, ModuleConstants_1.AlertModuleId, `Invalid Alert rule with observable expression `)
@@ -6,10 +6,10 @@ export declare class CalculatedColumnExpressionService implements ICalculatedCol
6
6
  private adaptableApi;
7
7
  private aggregatedScalarCalculatedColumnsMap;
8
8
  constructor(adaptableApi: AdaptableApi);
9
+ destroy(): void;
9
10
  getCalculatedColumnDataType(calculatedColumnQuery: AdaptableCalculatedColumnQuery): 'String' | 'Number' | 'Boolean' | 'Date';
10
11
  isCalculatedColumnQueryValid(calculatedColumnQuery: AdaptableCalculatedColumnQuery): boolean;
11
12
  evaluateCalculatedColumnQuery(calculatedColumn: CalculatedColumn, node: RowNode): any;
12
13
  createAggregatedScalarCalculatedColumn(calculatedColumn: CalculatedColumn): void;
13
14
  destroyAggregatedScalarCalculatedColumn(calculatedColumn: CalculatedColumn): void;
14
- destroy(): void;
15
15
  }
@@ -31,6 +31,11 @@ class CalculatedColumnExpressionService {
31
31
  }
32
32
  });
33
33
  }
34
+ destroy() {
35
+ [...this.aggregatedScalarCalculatedColumnsMap.values()].forEach((aggregatedScalarCalculatedColumn) => aggregatedScalarCalculatedColumn.destroy());
36
+ this.aggregatedScalarCalculatedColumnsMap.clear();
37
+ this.aggregatedScalarCalculatedColumnsMap = null;
38
+ }
34
39
  getCalculatedColumnDataType(calculatedColumnQuery) {
35
40
  try {
36
41
  if (calculatedColumnQuery.AggregatedScalarExpression) {
@@ -120,11 +125,10 @@ class CalculatedColumnExpressionService {
120
125
  }
121
126
  }
122
127
  destroyAggregatedScalarCalculatedColumn(calculatedColumn) {
128
+ var _a;
129
+ (_a = this.aggregatedScalarCalculatedColumnsMap.get(calculatedColumn.Uuid)) === null || _a === void 0 ? void 0 : _a.destroy();
123
130
  this.aggregatedScalarCalculatedColumnsMap.delete(calculatedColumn.Uuid);
124
131
  }
125
- destroy() {
126
- // TO DO
127
- }
128
132
  }
129
133
  exports.CalculatedColumnExpressionService = CalculatedColumnExpressionService;
130
134
  class AggregatedScalarCalculatedColumn {
@@ -136,6 +140,12 @@ class AggregatedScalarCalculatedColumn {
136
140
  // currently we support only one reducer
137
141
  this.aggregationReducerName = Object.keys(expressionEvaluation.aggregationParams.reducers)[0];
138
142
  }
143
+ destroy() {
144
+ this.expressionEvaluation = null;
145
+ this.calculatedColumn = null;
146
+ this.adaptableApi = null;
147
+ this.aggregationResult = null;
148
+ }
139
149
  getAggregatedColumnValue(rowNode) {
140
150
  const aggregationValue = this.getAggregationValue(rowNode);
141
151
  if (this.expressionEvaluation.rowValueGetter) {
@@ -6,17 +6,17 @@ import { Observable } from 'rxjs';
6
6
  export declare class DataService implements IDataService {
7
7
  private adaptable;
8
8
  private emitter;
9
- private readonly dataChangeLogSubject$;
9
+ private dataChangeLogSubject$;
10
10
  dataChangeLog$: Observable<CellDataChangedInfo>;
11
11
  private undoChangeLog;
12
12
  private undoChangeTimers;
13
13
  constructor(adaptable: IAdaptable);
14
+ destroy(): void;
14
15
  on: (eventName: string, callback: EmitterCallback) => (() => void);
15
16
  emit: (eventName: string, data?: any) => Promise<any>;
16
17
  CreateDataChangedEvent(cellDataChangedInfo: CellDataChangedInfo): void;
17
18
  logUndoChange(change: CellDataChangedInfo): void;
18
19
  extractUndoChange(change: CellDataChangedInfo): CellDataChangedInfo | undefined;
19
- destroy(): void;
20
20
  private getUndoChangeKey;
21
21
  private logDataChange;
22
22
  private extractDataChangeLogEntry;
@@ -20,6 +20,17 @@ class DataService {
20
20
  this.undoChangeLog = new Map();
21
21
  this.undoChangeTimers = new Map();
22
22
  }
23
+ destroy() {
24
+ this.emitter.destroy();
25
+ this.emitter = null;
26
+ this.dataChangeLogSubject$.complete();
27
+ this.dataChangeLogSubject$ = null;
28
+ this.dataChangeLog$ = null;
29
+ this.undoChangeLog.clear();
30
+ this.undoChangeLog = null;
31
+ this.undoChangeTimers.clear();
32
+ this.undoChangeTimers = null;
33
+ }
23
34
  CreateDataChangedEvent(cellDataChangedInfo) {
24
35
  if (cellDataChangedInfo.newValue != cellDataChangedInfo.oldValue) {
25
36
  this.emitter.emitSync('CellDataChanged', cellDataChangedInfo);
@@ -57,10 +68,6 @@ class DataService {
57
68
  }
58
69
  return result;
59
70
  }
60
- destroy() {
61
- this.emitter.destroy();
62
- this.emitter = null;
63
- }
64
71
  getUndoChangeKey(primaryKeyValue, columnId, previousValue, newValue) {
65
72
  return JSON.stringify({
66
73
  primaryKeyValue,
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const ArrayExtensions_1 = require("../Extensions/ArrayExtensions");
6
6
  const StringExtensions_1 = tslib_1.__importDefault(require("../Extensions/StringExtensions"));
7
7
  const ModuleConstants_1 = require("../Constants/ModuleConstants");
8
+ const ObjectFactory_1 = tslib_1.__importDefault(require("../ObjectFactory"));
8
9
  class ValidationService {
9
10
  constructor(adaptableApi) {
10
11
  this.adaptableApi = adaptableApi;
@@ -51,6 +52,10 @@ class ValidationService {
51
52
  cellDataChangedInfo: cellDataChangedInfo,
52
53
  };
53
54
  this.adaptableApi.alertApi.publishAlertFiredEvent(alert);
55
+ failedRules.forEach((alertDefinition) => {
56
+ const alert = ObjectFactory_1.default.CreateCellChangedAlert(cellDataChangedInfo.column.friendlyName, this.adaptableApi.alertApi.getAlertDescription(alertDefinition, cellDataChangedInfo), alertDefinition, cellDataChangedInfo);
57
+ this.adaptableApi.alertApi.displayAlert(alert);
58
+ });
54
59
  return false;
55
60
  }
56
61
  return true;
@@ -103,7 +103,7 @@ export declare class Adaptable implements IAdaptable {
103
103
  */
104
104
  static initInternal(adaptableOptions: AdaptableOptions, runtimeConfig?: RuntimeConfig): Promise<AdaptableApi>;
105
105
  private static collectInstance;
106
- private static forEachAdaptable;
106
+ static forEachAdaptable(fn: (adaptable: Adaptable) => void): void;
107
107
  private static dismissInstance;
108
108
  constructor();
109
109
  init(adaptableOptions: AdaptableOptions, runtimeConfig?: RuntimeConfig, _staticInit?: boolean): Promise<AdaptableApi>;
@@ -84,6 +84,43 @@ const assignColId = (colDef) => {
84
84
  const RowNodeProto = all_modules_1.RowNode.prototype;
85
85
  const RowNode_dispatchLocalEvent = RowNodeProto.dispatchLocalEvent;
86
86
  const GridApi_setColumnDefs = all_modules_1.GridApi.prototype.setColumnDefs;
87
+ /**
88
+ * AgGrid does not expose Events.EVENT_ROW_DATA_CHANGED
89
+ * so we have to override `dispatchLocalEvent`
90
+ * and hook our own functionality into it
91
+ */
92
+ RowNodeProto.dispatchLocalEvent = function (event) {
93
+ const node = event.node;
94
+ const result = RowNode_dispatchLocalEvent.apply(this, arguments);
95
+ const extractGridApiFromRowNode = (rowNode) => {
96
+ var _a, _b;
97
+ // starting with AG Grid 26.1.0 the gridApi is wrapped in a Beans property
98
+ const rowNodeApi = (_b = (_a = rowNode) === null || _a === void 0 ? void 0 : _a.beans) === null || _b === void 0 ? void 0 : _b.gridApi;
99
+ if (!rowNodeApi) {
100
+ LoggingHelper_1.LogAdaptableWarning(`No GridAPI found in passed RowNode, this should never happen!`, rowNode);
101
+ }
102
+ return rowNodeApi;
103
+ };
104
+ // we don't know from which instance of aggrid this is coming,
105
+ // as this fn is shared by all instances
106
+ if (node) {
107
+ Adaptable.forEachAdaptable((adaptable) => {
108
+ if (extractGridApiFromRowNode(node) !== adaptable.gridOptions.api) {
109
+ // the event is coming from another aggrid instance
110
+ // so IGNORE IT
111
+ return;
112
+ }
113
+ // we're on the correct instance, so do this
114
+ //@ts-ignore
115
+ const fn = adaptable.rowListeners ? adaptable.rowListeners[event.type] : null;
116
+ if (fn) {
117
+ console.log('fire event', event);
118
+ fn(event);
119
+ }
120
+ });
121
+ }
122
+ return result;
123
+ };
87
124
  /**
88
125
  * Since column definitions can be nested and have groups
89
126
  * we use this forEachColumn function to call the passed-in `fn`
@@ -704,6 +741,7 @@ class Adaptable {
704
741
  this._emit('GridFiltered');
705
742
  this.setSelectedCells();
706
743
  this.setSelectedRows();
744
+ this.updateColumnFilterActiveState();
707
745
  }
708
746
  isGroupRowNode(rowNode) {
709
747
  if (!rowNode) {
@@ -2365,16 +2403,27 @@ class Adaptable {
2365
2403
  this.gridOptions = null;
2366
2404
  this.adaptableOptions = null;
2367
2405
  (_b = this.CalculatedColumnExpressionService) === null || _b === void 0 ? void 0 : _b.destroy();
2406
+ this.CalculatedColumnExpressionService = null;
2368
2407
  (_c = this.DataService) === null || _c === void 0 ? void 0 : _c.destroy();
2408
+ this.DataService = null;
2369
2409
  (_d = this.EntitlementService) === null || _d === void 0 ? void 0 : _d.destroy();
2410
+ this.EntitlementService = null;
2370
2411
  (_e = this.ReportService) === null || _e === void 0 ? void 0 : _e.destroy();
2412
+ this.ReportService = null;
2371
2413
  (_f = this.ModuleService) === null || _f === void 0 ? void 0 : _f.destroy();
2414
+ this.ModuleService = null;
2372
2415
  (_g = this.ValidationService) === null || _g === void 0 ? void 0 : _g.destroy();
2416
+ this.ValidationService = null;
2373
2417
  (_h = this.QueryLanguageService) === null || _h === void 0 ? void 0 : _h.destroy();
2418
+ this.QueryLanguageService = null;
2374
2419
  (_j = this.AlertService) === null || _j === void 0 ? void 0 : _j.destroy();
2420
+ this.AlertService = null;
2375
2421
  (_k = this.TeamSharingService) === null || _k === void 0 ? void 0 : _k.destroy();
2422
+ this.TeamSharingService = null;
2376
2423
  (_l = this.MetamodelService) === null || _l === void 0 ? void 0 : _l.destroy();
2424
+ this.MetamodelService = null;
2377
2425
  (_m = this.LicenseService) === null || _m === void 0 ? void 0 : _m.destroy();
2426
+ this.LicenseService = null;
2378
2427
  this.isDestroyed = true;
2379
2428
  }
2380
2429
  // really really need to do this properly but as a temp fix lets create a default style for when no data
@@ -2659,59 +2708,15 @@ class Adaptable {
2659
2708
  }
2660
2709
  },
2661
2710
  };
2662
- /**
2663
- * AgGrid does not expose Events.EVENT_ROW_DATA_CHANGED
2664
- * so we have to override `dispatchLocalEvent`
2665
- * and hook our own functionality into it
2666
- */
2667
- RowNodeProto.dispatchLocalEvent = function (event) {
2668
- const node = event.node;
2669
- const result = RowNode_dispatchLocalEvent.apply(this, arguments);
2670
- const extractGridApiFromRowNode = (rowNode) => {
2671
- var _a, _b;
2672
- // starting with AG Grid 26.1.0 the gridApi is wrapped in a Beans property
2673
- const rowNodeApi = (_b = (_a = rowNode) === null || _a === void 0 ? void 0 : _a.beans) === null || _b === void 0 ? void 0 : _b.gridApi;
2674
- if (!rowNodeApi) {
2675
- LoggingHelper_1.LogAdaptableWarning(`No GridAPI found in passed RowNode, this should never happen!`, rowNode);
2676
- }
2677
- return rowNodeApi;
2678
- };
2679
- // we don't know from which instance of aggrid this is coming,
2680
- // as this fn is shared by all instances
2681
- if (node) {
2682
- Adaptable.forEachAdaptable((adaptable) => {
2683
- if (extractGridApiFromRowNode(node) !== adaptable.gridOptions.api) {
2684
- // the event is coming from another aggrid instance
2685
- // so IGNORE IT
2686
- return;
2687
- }
2688
- // we're on the correct instance, so do this
2689
- const fn = adaptable.rowListeners ? adaptable.rowListeners[event.type] : null;
2690
- if (fn) {
2691
- fn(event);
2692
- }
2693
- });
2694
- }
2695
- return result;
2696
- };
2697
2711
  // We plug our filter mechanism and if there is already something like external widgets... we save ref to the function
2698
2712
  const original_isExternalFilterPresent = this.gridOptions.isExternalFilterPresent;
2699
2713
  this.gridOptions.isExternalFilterPresent = (params) => {
2714
+ if (this.isDestroyed) {
2715
+ return true;
2716
+ }
2700
2717
  const columnFilters = this.api.filterApi.getAllColumnFilter();
2701
2718
  const isFilterActive = ArrayExtensions_1.ArrayExtensions.IsNotNullOrEmpty(columnFilters);
2702
2719
  const isQueryActive = StringExtensions_1.StringExtensions.IsNotNullOrEmpty(this.api.queryApi.getCurrentQuery());
2703
- /**
2704
- * Changing the column filterState sync breaks the rendering of the custom filter component.
2705
- * I think that changing the column definition while ag-grid determines if a column is filtered
2706
- * breaks the logic of the custom component.
2707
- *
2708
- * Result:
2709
- * - custom filters in sate
2710
- * - refresh page, the ag-grid filter is rendered instead of adaptable custom-filter-component.
2711
- */
2712
- requestAnimationFrame(() => {
2713
- this.updateColumnFilterActiveState();
2714
- });
2715
2720
  return (isFilterActive ||
2716
2721
  isQueryActive ||
2717
2722
  // it means that originaldoesExternalFilterPass will be called so we reinit that collection
@@ -2721,6 +2726,9 @@ class Adaptable {
2721
2726
  const evaluateQueryOnClient = this.api.internalApi.runModuleInAdaptableQL('Query');
2722
2727
  const evaluateFilterOnClient = this.api.internalApi.runModuleInAdaptableQL('Filter');
2723
2728
  this.gridOptions.doesExternalFilterPass = (node) => {
2729
+ if (this.isDestroyed) {
2730
+ return true;
2731
+ }
2724
2732
  // first we assess Query (if its running locally)
2725
2733
  if (evaluateQueryOnClient && !this.isGroupRowNode(node)) {
2726
2734
  const currentQuery = this.api.queryApi.getCurrentQuery();
@@ -2769,22 +2777,32 @@ class Adaptable {
2769
2777
  updateColumnFilterActiveState() {
2770
2778
  const columnFilters = this.api.filterApi.getAllColumnFilter();
2771
2779
  const isFilterActive = ArrayExtensions_1.ArrayExtensions.IsNotNullOrEmpty(columnFilters);
2780
+ const columnsWithActiveFilters = {};
2772
2781
  if (isFilterActive) {
2773
2782
  // used in particular at init time to show the filter icon correctly
2774
2783
  for (const colFilter of columnFilters) {
2775
2784
  const agGridCol = this.gridOptions.columnApi.getColumn(colFilter.ColumnId);
2776
- if (agGridCol && !agGridCol.isFilterActive()) {
2777
- agGridCol.setFilterActive(true);
2785
+ if (agGridCol) {
2786
+ columnsWithActiveFilters[agGridCol.getColId()] = true;
2787
+ if (!agGridCol.isFilterActive()) {
2788
+ agGridCol.setFilterActive(true);
2789
+ }
2778
2790
  }
2779
2791
  }
2780
2792
  }
2781
- else {
2782
- (this.gridOptions.columnApi.getAllColumns() || []).forEach((col) => {
2783
- if (col.isFilterActive()) {
2784
- col.setFilterActive(false);
2785
- }
2786
- });
2787
- }
2793
+ const agFilterModel = this.gridOptions.api.getFilterModel();
2794
+ (this.gridOptions.columnApi.getAllColumns() || []).forEach((col) => {
2795
+ /**
2796
+ * When ag-grid filters are used active state should not be removed for all columns.
2797
+ * Need to check if the column has a filter model.
2798
+ */
2799
+ const isColumnInFilterModel = agFilterModel && agFilterModel[col.getColId()];
2800
+ if (!isColumnInFilterModel &&
2801
+ !columnsWithActiveFilters[col.getColId()] &&
2802
+ col.isFilterActive()) {
2803
+ col.setFilterActive(false);
2804
+ }
2805
+ });
2788
2806
  }
2789
2807
  buildStandaloneColumnHeader(adaptableColumn) {
2790
2808
  return this.agGridMenuHelper.buildStandaloneColumnHeader(adaptableColumn);
@@ -2855,7 +2873,15 @@ class Adaptable {
2855
2873
  this.gridOptionsPropertyCache.set(userKey, value);
2856
2874
  }
2857
2875
  const userValue = this.gridOptionsPropertyCache.get(userKey);
2858
- const adaptableValue = propertyGetter(userValue);
2876
+ const adaptableValue = (...args) => {
2877
+ if (this.isDestroyed) {
2878
+ return;
2879
+ }
2880
+ if (propertyGetter) {
2881
+ return propertyGetter(userValue)(...args);
2882
+ }
2883
+ return undefined;
2884
+ };
2859
2885
  if (adaptableValue != null) {
2860
2886
  this.gridOptionsPropertyCache.set(adaptableKey, adaptableValue);
2861
2887
  }
@@ -3212,7 +3238,14 @@ class Adaptable {
3212
3238
  if (cellDataChangedInfo.oldValue === cellDataChangedInfo.newValue) {
3213
3239
  return true;
3214
3240
  }
3215
- if (!this.ValidationService.performValidation(cellDataChangedInfo)) {
3241
+ /**
3242
+ * Validate on the future row, with the new value.
3243
+ * structuredClone fails, it contains functions.
3244
+ */
3245
+ const newRow = Object.assign(Object.assign({}, params.node), { data: Object.assign({}, params.node.data) });
3246
+ newRow.data[field] = params.newValue;
3247
+ const cellDataChangeInfoForSyncValidation = Object.assign(Object.assign({}, cellDataChangedInfo), { rowNode: newRow });
3248
+ if (!this.ValidationService.performValidation(cellDataChangeInfoForSyncValidation)) {
3216
3249
  return false;
3217
3250
  }
3218
3251
  const onServerValidationCompleted = () => { };
package/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- declare const _default: "11.2.0";
1
+ declare const _default: "11.2.1-canary.0";
2
2
  export default _default;
package/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = '11.2.0'; // PLEASE DONT UPDATE THIS!!! - will be updated at build time with the correct version
3
+ exports.default = '11.2.1-canary.0'; // PLEASE DONT UPDATE THIS!!! - will be updated at build time with the correct version