@adaptabletools/adaptable 18.0.0-canary.28 → 18.0.0-canary.29

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.
Files changed (55) hide show
  1. package/base.css +3 -13
  2. package/base.css.map +1 -1
  3. package/index.css +3 -13
  4. package/index.css.map +1 -1
  5. package/package.json +1 -1
  6. package/src/AdaptableOptions/AdaptableFrameworkComponent.d.ts +3 -0
  7. package/src/AdaptableOptions/MenuOptions.d.ts +1 -1
  8. package/src/Api/GridApi.d.ts +4 -1
  9. package/src/Api/Implementation/ConfigApiImpl.js +0 -1
  10. package/src/Api/Implementation/GridApiImpl.d.ts +1 -1
  11. package/src/Api/Implementation/GridApiImpl.js +6 -1
  12. package/src/Api/Implementation/UserInterfaceApiImpl.d.ts +14 -5
  13. package/src/Api/Implementation/UserInterfaceApiImpl.js +26 -4
  14. package/src/Api/Internal/AdaptableInternalApi.d.ts +0 -1
  15. package/src/Api/Internal/AdaptableInternalApi.js +2 -6
  16. package/src/Api/Internal/FormatColumnInternalApi.js +6 -2
  17. package/src/Api/Internal/LayoutInternalApi.js +1 -1
  18. package/src/Api/UserInterfaceApi.d.ts +15 -2
  19. package/src/PredefinedConfig/Common/AdaptableIcon.d.ts +1 -1
  20. package/src/PredefinedConfig/Common/Menu.d.ts +1 -1
  21. package/src/PredefinedConfig/Common/Menu.js +22 -12
  22. package/src/PredefinedConfig/FormatColumnState.d.ts +4 -0
  23. package/src/PredefinedConfig/PopupState.d.ts +1 -2
  24. package/src/PredefinedConfig/StyledColumnState.d.ts +5 -0
  25. package/src/PredefinedConfig/SystemState.d.ts +4 -2
  26. package/src/Redux/ActionsReducers/PopupRedux.d.ts +5 -13
  27. package/src/Redux/ActionsReducers/PopupRedux.js +0 -19
  28. package/src/Redux/ActionsReducers/SystemRedux.d.ts +9 -3
  29. package/src/Redux/ActionsReducers/SystemRedux.js +8 -5
  30. package/src/Strategy/ExportModule.d.ts +0 -1
  31. package/src/Strategy/ExportModule.js +39 -28
  32. package/src/Strategy/LayoutModule.d.ts +1 -8
  33. package/src/Strategy/LayoutModule.js +3 -113
  34. package/src/Strategy/StyledColumnModule.js +5 -2
  35. package/src/Strategy/Utilities/FormatColumn/getFormatColumnSettingsViewItems.js +1 -0
  36. package/src/Utilities/Interface/MessagePopups.d.ts +0 -3
  37. package/src/Utilities/Services/RowSummaryService.d.ts +22 -0
  38. package/src/Utilities/Services/RowSummaryService.js +141 -0
  39. package/src/View/FormatColumn/Wizard/FormatColumnSettingsWizardSection.js +11 -2
  40. package/src/View/StyledColumn/Wizard/StyledColumnWizard.js +1 -1
  41. package/src/View/StyledColumn/Wizard/StyledColumnWizardSettingsSection.js +14 -10
  42. package/src/agGrid/AgGridColumnAdapter.js +19 -13
  43. package/src/agGrid/AgGridMenuAdapter.d.ts +5 -0
  44. package/src/agGrid/AgGridMenuAdapter.js +111 -57
  45. package/src/agGrid/BadgeRenderer.js +7 -1
  46. package/src/agGrid/PercentBarRenderer.js +3 -1
  47. package/src/components/CheckBox/index.js +1 -1
  48. package/src/components/ProgressIndicator/ProgressIndicator.js +15 -6
  49. package/src/components/icons/copy.d.ts +3 -0
  50. package/src/components/icons/copy.js +4 -0
  51. package/src/components/icons/index.js +2 -0
  52. package/src/env.js +2 -2
  53. package/src/metamodel/adaptable.metamodel.js +1 -1
  54. package/src/types.d.ts +1 -1
  55. package/tsconfig.esm.tsbuildinfo +1 -1
@@ -3,7 +3,7 @@ import * as ModuleConstants from '../Utilities/Constants/ModuleConstants';
3
3
  import { ExportDestination } from '../PredefinedConfig/Common/Enums';
4
4
  import { Helper } from '../Utilities/Helpers/Helper';
5
5
  import * as ExportRedux from '../Redux/ActionsReducers/ExportRedux';
6
- import { SELECTED_CELLS_REPORT, SELECTED_ROWS_REPORT, VISUAL_DATA_REPORT, } from '../Utilities/Constants/GeneralConstants';
6
+ import { ALL_DATA_REPORT, CURRENT_DATA_REPORT, SELECTED_CELLS_REPORT, SELECTED_ROWS_REPORT, VISUAL_DATA_REPORT, } from '../Utilities/Constants/GeneralConstants';
7
7
  import ArrayExtensions from '../Utilities/Extensions/ArrayExtensions';
8
8
  import StringExtensions from '../Utilities/Extensions/StringExtensions';
9
9
  import * as PopupRedux from '../Redux/ActionsReducers/PopupRedux';
@@ -14,7 +14,7 @@ import { getExportRowsViewItems } from './Utilities/Export/getExportRowsViewItem
14
14
  import { ReportExportDropdown } from '../View/Export/ReportExportDropdown';
15
15
  import { getObjectTagsViewItems } from './Utilities/getObjectTagsViewItems';
16
16
  import { ExportSelector } from '../View/Export/ExportSelector';
17
- import { SystemProgressIndicatorShow, SystemVisualExportBegin, SystemVisualExportEnd, } from '../Redux/ActionsReducers/SystemRedux';
17
+ import { SystemVisualExportBegin, SystemVisualExportEnd, } from '../Redux/ActionsReducers/SystemRedux';
18
18
  import { SHOW_EXPORT_TABLE } from '../View/Components/Popups/WindowPopups/windowFactory';
19
19
  import { createUuid } from '../PredefinedConfig/Uuid';
20
20
  import { waitForTimeout } from '../Utilities/waitForTimeout';
@@ -46,58 +46,69 @@ export class ExportModule extends AdaptableModuleBase {
46
46
  return;
47
47
  }
48
48
  let returnMenuItems = [];
49
- const canExportCells = menuContext.selectedCellInfo &&
49
+ const availableSystemReports = this.api.exportApi.getAvailableSystemReports();
50
+ if (availableSystemReports.includes(VISUAL_DATA_REPORT)) {
51
+ returnMenuItems.push(this.createMenuItemClickFunction('export-visual-data-excel', 'Excel', this.moduleInfo.Glyph, () => this.export(this.api.exportApi.getReportByName(VISUAL_DATA_REPORT), ExportDestination.Excel)));
52
+ }
53
+ if (availableSystemReports.includes(ALL_DATA_REPORT)) {
54
+ const allDataReport = this.api.exportApi.getReportByName(ALL_DATA_REPORT);
55
+ returnMenuItems.push(...this.buildReportMenuItems(allDataReport));
56
+ }
57
+ if (availableSystemReports.includes(CURRENT_DATA_REPORT)) {
58
+ const currentDataReport = this.api.exportApi.getReportByName(CURRENT_DATA_REPORT);
59
+ returnMenuItems.push(...this.buildReportMenuItems(currentDataReport));
60
+ }
61
+ const canExportCells = availableSystemReports.includes(SELECTED_CELLS_REPORT) &&
62
+ menuContext.selectedCellInfo &&
50
63
  ArrayExtensions.IsNotNullOrEmpty(menuContext.selectedCellInfo.columns) &&
51
64
  ArrayExtensions.IsNotNullOrEmpty(menuContext.selectedCellInfo.gridCells);
52
- const canExportRows = menuContext.selectedRowInfo &&
65
+ if (canExportCells) {
66
+ const selectedCellReport = this.api.exportApi.getReportByName(SELECTED_CELLS_REPORT);
67
+ returnMenuItems.push(...this.buildReportMenuItems(selectedCellReport));
68
+ }
69
+ const canExportRows = availableSystemReports.includes(SELECTED_ROWS_REPORT) &&
70
+ menuContext.selectedRowInfo &&
53
71
  ArrayExtensions.IsNotNullOrEmpty(menuContext.selectedRowInfo.gridRows) &&
54
72
  menuContext.gridCell &&
55
73
  menuContext.gridCell.primaryKeyValue &&
56
74
  menuContext.isSelectedRow;
57
- if (canExportCells) {
58
- const selectedCellReport = this.api.exportApi.getReportByName(SELECTED_CELLS_REPORT);
59
- returnMenuItems.push(...this.buildReportMenuItems(selectedCellReport, 'cells'));
60
- }
61
75
  if (canExportRows) {
62
76
  const selectedRowReport = this.api.exportApi.getReportByName(SELECTED_ROWS_REPORT);
63
- returnMenuItems.push(...this.buildReportMenuItems(selectedRowReport, 'rows'));
77
+ returnMenuItems.push(...this.buildReportMenuItems(selectedRowReport));
64
78
  }
65
79
  return returnMenuItems;
66
80
  }
67
- buildReportMenuItems(report, selectionType) {
81
+ buildReportMenuItems(report) {
82
+ // a bit convoluted, but ce la vie, that's what happens when you use enums instead of union types
83
+ // convert to lowercase and replace empty spaces with hyphens
84
+ const adjustName = (name = '') => {
85
+ const result = name.replace(/ /g, '-');
86
+ return result.toLowerCase();
87
+ };
88
+ const getMenuItemName = (reportName, destination) => {
89
+ return `export-${adjustName(reportName)}-${adjustName(destination)}`;
90
+ };
68
91
  const menuItems = [];
69
92
  for (const destination of this.api.exportApi.getAvailableExportDestinations()) {
70
- menuItems.push(this.createMenuItemClickFunction(this.getMenuName(destination, selectionType), destination, this.moduleInfo.Glyph, () => this.export(report, destination)));
93
+ menuItems.push(this.createMenuItemClickFunction(getMenuItemName(report.Name, destination), destination, this.moduleInfo.Glyph, () => this.export(report, destination)));
71
94
  }
72
95
  for (const customDestination of this.api.exportApi.getCustomDestinations()) {
73
- menuItems.push(this.createMenuItemClickFunction(`export-${selectionType}-custom-destination`, customDestination.name, this.moduleInfo.Glyph, () => this.export(report, customDestination.name)));
96
+ menuItems.push(this.createMenuItemClickFunction(getMenuItemName(report.Name, customDestination.name), customDestination.name, this.moduleInfo.Glyph, () => this.export(report, customDestination.name)));
74
97
  }
75
98
  return menuItems;
76
99
  }
77
- getMenuName(exportDestination, selectionType) {
78
- switch (exportDestination) {
79
- case ExportDestination.CSV:
80
- return `export-${selectionType}-csv`;
81
- case ExportDestination.Clipboard:
82
- return `export-${selectionType}-clipboard`;
83
- case ExportDestination.Excel:
84
- return `export-${selectionType}-excel`;
85
- case ExportDestination.JSON:
86
- return `export-${selectionType}-json`;
87
- case ExportDestination.Table:
88
- return `export-${selectionType}-table`;
89
- }
90
- }
91
100
  async export(report, exportDestination) {
92
101
  var _a;
93
102
  const cleanupExportProcess = () => {
94
103
  this.api.internalApi.dispatchReduxAction(SystemVisualExportEnd());
95
- this.api.internalApi.hideProgressIndicator();
104
+ this.api.userInterfaceApi.hideProgressIndicator();
96
105
  };
97
106
  if (report.Name === VISUAL_DATA_REPORT) {
98
107
  this.api.internalApi.dispatchReduxAction(SystemVisualExportBegin());
99
108
  }
100
- this.api.internalApi.dispatchReduxAction(SystemProgressIndicatorShow(`${report.Name} Export in progress...`));
109
+ this.api.userInterfaceApi.showProgressIndicator({
110
+ text: `${report.Name} Export in progress...`,
111
+ });
101
112
  try {
102
113
  // waitForTimeout required to give the ProgressIndicator rendering a head-start (see rAF in ProgressIndicator implementation)
103
114
  await waitForTimeout(16);
@@ -7,13 +7,11 @@ import { AdaptableColumn } from '../PredefinedConfig/Common/AdaptableColumn';
7
7
  import { AdaptableApi } from '../Api/AdaptableApi';
8
8
  import { AdaptableModuleView, IModule, TeamSharingReferences } from './Interface/IModule';
9
9
  import { AdaptableObject } from '../PredefinedConfig/Common/AdaptableObject';
10
- import { AggregatedScalarLiveValue } from '../Utilities/Services/AggregatedScalarLiveValue';
11
10
  export declare class LayoutModule extends AdaptableModuleBase implements IModule {
12
- cachedCellSummary: Map<string, AggregatedScalarLiveValue>;
13
11
  protected LayoutState: LayoutState;
12
+ private rowSummaryService;
14
13
  constructor(api: AdaptableApi);
15
14
  onAdaptableReady(): void;
16
- rowSummariesSubscriptions(): void;
17
15
  getModuleAdaptableObjects(): AdaptableObject[];
18
16
  getExplicitlyReferencedColumnIds(layout: Layout): string[];
19
17
  getTeamSharingReferences(adaptableObject: AdaptableObject): TeamSharingReferences;
@@ -45,9 +43,4 @@ export declare class LayoutModule extends AdaptableModuleBase implements IModule
45
43
  getViewProperties(): AdaptableModuleView;
46
44
  handleLayoutChange(): void;
47
45
  getReferencedNamedQueryNames(layout: Layout): string[];
48
- /**
49
- *
50
- * @param colId optional to evaluate only one column
51
- */
52
- private evaluateRowSummary;
53
46
  }
@@ -15,16 +15,14 @@ import { SHOW_PIVOT_COLUMN_DETAILS } from '../View/Components/Popups/WindowPopup
15
15
  import flattenDeep from 'lodash/flattenDeep';
16
16
  import StringExtensions from '../Utilities/Extensions/StringExtensions';
17
17
  import { getGridFilterViewItems } from '../View/Layout/Wizard/getGridFilterPreview';
18
- import { AggregatedScalarLiveValue } from '../Utilities/Services/AggregatedScalarLiveValue';
19
- import { SystemRowSummarySet } from '../Redux/ActionsReducers/SystemRedux';
20
- import { ROW_SUMMARY_ROW_ID, WEIGHTED_AVERAGE_AGGREATED_FUNCTION, } from '../PredefinedConfig/Common/RowSummary';
21
- import Helper from '../Utilities/Helpers/Helper';
18
+ import { RowSummaryService } from '../Utilities/Services/RowSummaryService';
22
19
  export class LayoutModule extends AdaptableModuleBase {
23
20
  constructor(api) {
24
21
  super(ModuleConstants.LayoutModuleId, ModuleConstants.LayoutFriendlyName, 'grid', 'LayoutPopup', 'Named sets of column visibility, order, groupings, aggregation, pivots etc.', api);
25
- this.cachedCellSummary = new Map();
22
+ this.rowSummaryService = new RowSummaryService(this.api);
26
23
  }
27
24
  onAdaptableReady() {
25
+ this.rowSummaryService.onAdapterReady();
28
26
  this.api.eventApi.on('LayoutChanged', (layoutChangedInfo) => {
29
27
  var _a;
30
28
  if (layoutChangedInfo.newLayoutState.CurrentLayout !==
@@ -36,49 +34,6 @@ export class LayoutModule extends AdaptableModuleBase {
36
34
  requestAnimationFrame(() => {
37
35
  this.api.layoutApi.internalApi.fireLayoutChangedEvent('ADAPTABLE_READY', null, this.api.layoutApi.getLayoutState());
38
36
  });
39
- this.rowSummariesSubscriptions();
40
- }
41
- rowSummariesSubscriptions() {
42
- if (this.api.isDestroyed()) {
43
- return;
44
- }
45
- // Currently not available for serverside model
46
- if (!this.api.layoutApi.internalApi.getLayoutSupportedFeatures().RowSummaries) {
47
- return;
48
- }
49
- // ROW SUMMARY
50
- this.evaluateRowSummary();
51
- this.api.eventApi.on('AdaptableStateReloaded', () => {
52
- this.evaluateRowSummary();
53
- });
54
- this.api.eventApi.on('GridDataChanged', (event) => {
55
- this.evaluateRowSummary();
56
- });
57
- this.api.eventApi.on('CellChanged', (event) => {
58
- const columnId = event.cellChange.column.columnId;
59
- this.evaluateRowSummary({
60
- columnId,
61
- });
62
- });
63
- this.api.eventApi.on('LayoutChanged', (event) => {
64
- // exclude filter events, those are handled in another event
65
- if (event.actionName.includes('FILTER')) {
66
- return;
67
- }
68
- setTimeout(() => {
69
- // the timeout is added so the grid has time to repond to the layout changed
70
- this.evaluateRowSummary();
71
- }, 16);
72
- });
73
- const adaptable = this.api.internalApi.getAdaptableInstance();
74
- adaptable._on('AdapTableFiltersApplied', () => {
75
- // we need to use this instead of layout changed
76
- // so the rows have time to update
77
- this.evaluateRowSummary();
78
- });
79
- adaptable._on('FirstDataRendered', () => {
80
- this.evaluateRowSummary();
81
- });
82
37
  }
83
38
  getModuleAdaptableObjects() {
84
39
  return this.api.layoutApi.getLayouts();
@@ -444,69 +399,4 @@ export class LayoutModule extends AdaptableModuleBase {
444
399
  }
445
400
  return this.api.namedQueryApi.internalApi.getReferencedNamedQueryNames(layout.GridFilter.Expression);
446
401
  }
447
- /**
448
- *
449
- * @param colId optional to evaluate only one column
450
- */
451
- evaluateRowSummary(reason) {
452
- var _a;
453
- if (this.api.isDestroyed()) {
454
- return;
455
- }
456
- const currentLayout = this.api.layoutApi.getCurrentLayout();
457
- const rowSummaries = (_a = this.api.layoutApi.getCurrentLayout().RowSummaries) !== null && _a !== void 0 ? _a : [];
458
- const rowSummariesResults = rowSummaries.map(({ ColumnsMap, Position }) => {
459
- return {
460
- Position,
461
- RowData: Object.entries(ColumnsMap !== null && ColumnsMap !== void 0 ? ColumnsMap : {}).reduce((acc, [columnId, expression]) => {
462
- const key = `${columnId}-${expression}`;
463
- let expressionLiveValue = this.cachedCellSummary.get(key);
464
- if (expressionLiveValue) {
465
- if (!reason) {
466
- // refresh all of them
467
- expressionLiveValue.refresh();
468
- }
469
- else if ('columnId' in reason && reason.columnId === columnId) {
470
- expressionLiveValue.refresh();
471
- }
472
- }
473
- if (!expressionLiveValue) {
474
- try {
475
- let aggregatedScalarExpression = `${expression}([${columnId}])`;
476
- if (aggregatedScalarExpression.includes(WEIGHTED_AVERAGE_AGGREATED_FUNCTION) &&
477
- currentLayout.AggregationColumns[columnId] &&
478
- typeof currentLayout.AggregationColumns[columnId] === 'object') {
479
- const weight = currentLayout.AggregationColumns[columnId]
480
- .weightedColumnId;
481
- if (weight) {
482
- aggregatedScalarExpression = `AVG([${columnId}], WEIGHT([${weight}]))`;
483
- }
484
- }
485
- expressionLiveValue = new AggregatedScalarLiveValue({
486
- aggregatedScalarExpression,
487
- }, ModuleConstants.LayoutModuleId, this.api, () => {
488
- return this.api.gridApi.getVisibleRowNodes();
489
- });
490
- }
491
- catch (e) {
492
- this.api.logError('Error evaluating row summary', e);
493
- }
494
- this.cachedCellSummary.set(key, expressionLiveValue);
495
- }
496
- let value = null;
497
- if (expressionLiveValue) {
498
- value = expressionLiveValue.getGlobalAggregatedValue();
499
- if (typeof value === 'number' && !isNaN(value)) {
500
- value = Helper.roundNumber(value, 2);
501
- }
502
- }
503
- acc[columnId] = value;
504
- return acc;
505
- }, {
506
- [ROW_SUMMARY_ROW_ID]: true,
507
- }),
508
- };
509
- });
510
- this.api.internalApi.dispatchReduxAction(SystemRowSummarySet(rowSummariesResults));
511
- }
512
402
  }
@@ -171,10 +171,13 @@ export class StyledColumnModule extends AdaptableModuleBase {
171
171
  },
172
172
  });
173
173
  }
174
- if (!styledColumn.BadgeStyle) {
174
+ if (styledColumn.BadgeStyle) {
175
175
  specificTypeItems.push({
176
176
  name: 'Settings',
177
- values: [`Include grouped rows: ${styledColumn.IncludeGroupedRows ? 'Yes' : 'No'}`],
177
+ values: [
178
+ `Include grouped rows: ${styledColumn.IncludeGroupedRows ? 'Yes' : 'No'}`,
179
+ `Include row summaries: ${styledColumn.IncludeRowSummaries ? 'Yes' : 'No'}`,
180
+ ],
178
181
  });
179
182
  }
180
183
  if (styledColumn.BadgeStyle) {
@@ -3,6 +3,7 @@ export const getFormatColumnSettingsViewItems = (formatColumn) => {
3
3
  const values = [
4
4
  `Cell alignment: ${(_a = formatColumn.CellAlignment) !== null && _a !== void 0 ? _a : 'default'}`,
5
5
  `Include grouped rows: ${formatColumn.IncludeGroupedRows ? 'Yes' : 'No'}`,
6
+ `Include row summaries: ${formatColumn.IncludeRowSummaries ? 'Yes' : 'No'}`,
6
7
  ].filter(Boolean);
7
8
  return {
8
9
  name: 'Settings',
@@ -32,9 +32,6 @@ export interface ScreenPopup {
32
32
  [key: string]: any;
33
33
  };
34
34
  }
35
- export interface LoadingPopup {
36
- ShowLoadingPopup: boolean;
37
- }
38
35
  export interface ConfirmationPopup {
39
36
  ShowConfirmationPopup: boolean;
40
37
  Header: string;
@@ -0,0 +1,22 @@
1
+ import { AdaptableApi, Layout } from '../../types';
2
+ import { AggregatedScalarLiveValue } from './AggregatedScalarLiveValue';
3
+ /**
4
+ * The logic is extracted here to make it easier to follow
5
+ */
6
+ export declare class RowSummaryService {
7
+ private api;
8
+ cachedCellSummary: Map<string, AggregatedScalarLiveValue>;
9
+ previousRowSummaries: any;
10
+ previousLayout: Layout | null;
11
+ debouncedEvaluateRowSummary: import("lodash").DebouncedFunc<(reason?: {
12
+ columnId: string;
13
+ }) => void>;
14
+ constructor(api: AdaptableApi);
15
+ onAdapterReady(): void;
16
+ rowSummariesSubscriptions(): void;
17
+ /**
18
+ *
19
+ * @param colId optional to evaluate only one column
20
+ */
21
+ private evaluateRowSummary;
22
+ }
@@ -0,0 +1,141 @@
1
+ import { isEqual } from 'lodash';
2
+ import { ROW_SUMMARY_ROW_ID, WEIGHTED_AVERAGE_AGGREATED_FUNCTION, } from '../../PredefinedConfig/Common/RowSummary';
3
+ import { SystemRowSummarySet } from '../../Redux/ActionsReducers/SystemRedux';
4
+ import * as ModuleConstants from '../../Utilities/Constants/ModuleConstants';
5
+ import Helper from '../Helpers/Helper';
6
+ import { AggregatedScalarLiveValue } from './AggregatedScalarLiveValue';
7
+ import { isObjectEmpty } from '../Extensions/ObjectExtensions';
8
+ import debounce from 'lodash/debounce';
9
+ /**
10
+ * The logic is extracted here to make it easier to follow
11
+ */
12
+ export class RowSummaryService {
13
+ constructor(api) {
14
+ this.api = api;
15
+ this.cachedCellSummary = new Map();
16
+ this.debouncedEvaluateRowSummary = debounce(this.evaluateRowSummary, 300);
17
+ }
18
+ onAdapterReady() {
19
+ this.rowSummariesSubscriptions();
20
+ }
21
+ rowSummariesSubscriptions() {
22
+ // return;
23
+ if (this.api.isDestroyed()) {
24
+ return;
25
+ }
26
+ // Currently not available for serverside model
27
+ if (!this.api.layoutApi.internalApi.getLayoutSupportedFeatures().RowSummaries) {
28
+ return;
29
+ }
30
+ this.debouncedEvaluateRowSummary();
31
+ this.api.eventApi.on('AdaptableStateReloaded', () => {
32
+ this.debouncedEvaluateRowSummary();
33
+ });
34
+ this.api.eventApi.on('GridDataChanged', (event) => {
35
+ this.debouncedEvaluateRowSummary();
36
+ });
37
+ this.api.eventApi.on('CellChanged', (event) => {
38
+ const columnId = event.cellChange.column.columnId;
39
+ this.debouncedEvaluateRowSummary({
40
+ columnId,
41
+ });
42
+ });
43
+ this.api.eventApi.on('LayoutChanged', (event) => {
44
+ // exclude filter events, those are handled in another event
45
+ if (event.actionName.includes('FILTER')) {
46
+ return;
47
+ }
48
+ setTimeout(() => {
49
+ // the timeout is added so the grid has time to repond to the layout changed
50
+ this.debouncedEvaluateRowSummary();
51
+ }, 16);
52
+ });
53
+ const adaptable = this.api.internalApi.getAdaptableInstance();
54
+ adaptable._on('AdapTableFiltersApplied', () => {
55
+ // we need to use this instead of layout changed
56
+ // so the rows have time to update
57
+ this.debouncedEvaluateRowSummary();
58
+ });
59
+ adaptable._on('FirstDataRendered', () => {
60
+ this.debouncedEvaluateRowSummary();
61
+ });
62
+ }
63
+ /**
64
+ *
65
+ * @param colId optional to evaluate only one column
66
+ */
67
+ evaluateRowSummary(reason) {
68
+ var _a;
69
+ if (this.api.isDestroyed()) {
70
+ return;
71
+ }
72
+ const currentLayout = this.api.layoutApi.getCurrentLayout();
73
+ let previousLayout = this.previousLayout;
74
+ // it is added here to be sure it is saved
75
+ this.previousLayout = currentLayout;
76
+ /**
77
+ * If the previous & current layout does not have row summaries, it is safe to exit
78
+ */
79
+ if (isObjectEmpty(currentLayout === null || currentLayout === void 0 ? void 0 : currentLayout.RowSummaries) && isObjectEmpty(previousLayout === null || previousLayout === void 0 ? void 0 : previousLayout.RowSummaries)) {
80
+ return;
81
+ }
82
+ const rowSummaries = (_a = this.api.layoutApi.getCurrentLayout().RowSummaries) !== null && _a !== void 0 ? _a : [];
83
+ const rowSummariesResults = rowSummaries.map(({ ColumnsMap, Position }) => {
84
+ return {
85
+ Position,
86
+ RowData: Object.entries(ColumnsMap !== null && ColumnsMap !== void 0 ? ColumnsMap : {}).reduce((acc, [columnId, expression]) => {
87
+ const key = `${columnId}-${expression}`;
88
+ let expressionLiveValue = this.cachedCellSummary.get(key);
89
+ if (expressionLiveValue) {
90
+ if (!reason) {
91
+ // refresh all of them
92
+ expressionLiveValue.refresh();
93
+ }
94
+ else if ('columnId' in reason && reason.columnId === columnId) {
95
+ expressionLiveValue.refresh();
96
+ }
97
+ }
98
+ if (!expressionLiveValue) {
99
+ try {
100
+ let aggregatedScalarExpression = `${expression}([${columnId}])`;
101
+ if (aggregatedScalarExpression.includes(WEIGHTED_AVERAGE_AGGREATED_FUNCTION) &&
102
+ currentLayout.AggregationColumns[columnId] &&
103
+ typeof currentLayout.AggregationColumns[columnId] === 'object') {
104
+ const weight = currentLayout.AggregationColumns[columnId]
105
+ .weightedColumnId;
106
+ if (weight) {
107
+ aggregatedScalarExpression = `AVG([${columnId}], WEIGHT([${weight}]))`;
108
+ }
109
+ }
110
+ expressionLiveValue = new AggregatedScalarLiveValue({
111
+ aggregatedScalarExpression,
112
+ }, ModuleConstants.LayoutModuleId, this.api, () => {
113
+ return this.api.gridApi.getVisibleRowNodes();
114
+ });
115
+ }
116
+ catch (e) {
117
+ this.api.logError('Error evaluating row summary', e);
118
+ }
119
+ this.cachedCellSummary.set(key, expressionLiveValue);
120
+ }
121
+ let value = null;
122
+ if (expressionLiveValue) {
123
+ value = expressionLiveValue.getGlobalAggregatedValue();
124
+ if (typeof value === 'number' && !isNaN(value)) {
125
+ value = Helper.roundNumber(value, 2);
126
+ }
127
+ }
128
+ acc[columnId] = value;
129
+ return acc;
130
+ }, {
131
+ [ROW_SUMMARY_ROW_ID]: true,
132
+ }),
133
+ };
134
+ });
135
+ if (this.previousRowSummaries && isEqual(rowSummariesResults, this.previousRowSummaries)) {
136
+ return;
137
+ }
138
+ this.api.internalApi.dispatchReduxAction(SystemRowSummarySet(rowSummariesResults));
139
+ this.previousRowSummaries = rowSummariesResults;
140
+ }
141
+ }
@@ -15,7 +15,10 @@ export const renderFormatColumnSettingsSummary = (data) => {
15
15
  React.createElement(Tag, null, (_a = data.CellAlignment) !== null && _a !== void 0 ? _a : 'default')),
16
16
  React.createElement(Text, { mt: 3 },
17
17
  "Include grouped rows ",
18
- React.createElement(Tag, null, data.IncludeGroupedRows ? 'yes' : 'no'))));
18
+ React.createElement(Tag, null, data.IncludeGroupedRows ? 'yes' : 'no')),
19
+ React.createElement(Text, { mt: 3 },
20
+ "Include row summaries ",
21
+ React.createElement(Tag, null, data.IncludeRowSummaries ? 'yes' : 'no'))));
19
22
  };
20
23
  export const FormatColumnSettingsWizardSection = (props) => {
21
24
  const { data } = useOnePageAdaptableWizardContext();
@@ -29,6 +32,9 @@ export const FormatColumnSettingsWizardSection = (props) => {
29
32
  const onIncludeGroupedRowsChanged = (IncludeGroupedRows) => {
30
33
  props.onChange(Object.assign(Object.assign({}, data), { IncludeGroupedRows }));
31
34
  };
35
+ const onIncludeRowSummariesChanged = (IncludeRowSummaries) => {
36
+ props.onChange(Object.assign(Object.assign({}, data), { IncludeRowSummaries }));
37
+ };
32
38
  return (React.createElement(Tabs, null,
33
39
  React.createElement(Tabs.Tab, null, "Settings"),
34
40
  React.createElement(Tabs.Content, null,
@@ -47,5 +53,8 @@ export const FormatColumnSettingsWizardSection = (props) => {
47
53
  : onCellAlignmentSelectChanged(null) }))),
48
54
  React.createElement(FormRow, { label: "Include Grouped Rows:" },
49
55
  React.createElement(Flex, { alignItems: "center", marginLeft: 2 },
50
- React.createElement(CheckBox, { "data-name": "include-grouped-rows-checkbox", checked: data.IncludeGroupedRows, onChange: onIncludeGroupedRowsChanged, mr: 2 }))))))));
56
+ React.createElement(CheckBox, { "data-name": "include-grouped-rows-checkbox", checked: data.IncludeGroupedRows, onChange: onIncludeGroupedRowsChanged, mr: 2 }))),
57
+ React.createElement(FormRow, { label: "Include Row Summaries:" },
58
+ React.createElement(Flex, { alignItems: "center", marginLeft: 2 },
59
+ React.createElement(CheckBox, { "data-name": "include-grouped-rows-checkbox", checked: data.IncludeRowSummaries, onChange: onIncludeRowSummariesChanged, mr: 2 }))))))));
51
60
  };
@@ -77,7 +77,7 @@ export const StyledColumnWizard = (props) => {
77
77
  React.createElement(StyledColumnWizardStyleSection, { onChange: setStyledColumn })));
78
78
  },
79
79
  title: 'Style',
80
- }, AdditionalSettingSection);
80
+ });
81
81
  }
82
82
  else if (styledColumn.BadgeStyle) {
83
83
  specificSteps.push({
@@ -1,26 +1,27 @@
1
1
  import * as React from 'react';
2
2
  import { Box, Flex, Text } from 'rebass';
3
- import FormLayout, { FormRow } from '../../../components/FormLayout';
4
3
  import { CheckBox } from '../../../components/CheckBox';
4
+ import FormLayout, { FormRow } from '../../../components/FormLayout';
5
5
  import { Tabs } from '../../../components/Tabs';
6
- import { useOnePageAdaptableWizardContext } from '../../Wizard/OnePageAdaptableWizard';
7
6
  import { Tag } from '../../../components/Tag';
8
- let alignmentOptions = [
9
- { value: 'Left', label: 'Left' },
10
- { value: 'Right', label: 'Right' },
11
- { value: 'Center', label: 'Center' },
12
- ];
7
+ import { useOnePageAdaptableWizardContext } from '../../Wizard/OnePageAdaptableWizard';
13
8
  export const renderStyledColumnWizardSettingsSummary = (data) => {
14
9
  return (React.createElement(Box, { padding: 2 },
15
10
  React.createElement(Text, { mt: 3 },
16
11
  "Include grouped rows ",
17
- React.createElement(Tag, null, data.IncludeGroupedRows ? 'yes' : 'no'))));
12
+ React.createElement(Tag, null, data.IncludeGroupedRows ? 'yes' : 'no')),
13
+ React.createElement(Text, { mt: 3 },
14
+ "Include row summaries ",
15
+ React.createElement(Tag, null, data.IncludeRowSummaries ? 'yes' : 'no'))));
18
16
  };
19
17
  export const StyledColumnWizardSettingsSection = (props) => {
20
- const { data, api } = useOnePageAdaptableWizardContext();
18
+ const { data } = useOnePageAdaptableWizardContext();
21
19
  const onIncludeGroupedRowsChanged = (IncludeGroupedRows) => {
22
20
  props.onChange(Object.assign(Object.assign({}, data), { IncludeGroupedRows }));
23
21
  };
22
+ const onIncludeRowSummariesChanged = (IncludeRowSummaries) => {
23
+ props.onChange(Object.assign(Object.assign({}, data), { IncludeRowSummaries }));
24
+ };
24
25
  return (React.createElement(Tabs, null,
25
26
  React.createElement(Tabs.Tab, null, "Settings"),
26
27
  React.createElement(Tabs.Content, null,
@@ -28,5 +29,8 @@ export const StyledColumnWizardSettingsSection = (props) => {
28
29
  React.createElement(FormLayout, null,
29
30
  React.createElement(FormRow, { label: "Include Grouped Rows:" },
30
31
  React.createElement(Flex, { alignItems: "center", marginLeft: 2 },
31
- React.createElement(CheckBox, { "data-name": "include-grouped-rows-checkbox", checked: data.IncludeGroupedRows, onChange: onIncludeGroupedRowsChanged, mr: 2 }))))))));
32
+ React.createElement(CheckBox, { "data-name": "include-grouped-rows-checkbox", checked: data.IncludeGroupedRows, onChange: onIncludeGroupedRowsChanged, mr: 2 }))),
33
+ React.createElement(FormRow, { label: "Include Row Summaries:" },
34
+ React.createElement(Flex, { alignItems: "center", marginLeft: 2 },
35
+ React.createElement(CheckBox, { "data-name": "include-grouped-rows-checkbox", checked: data.IncludeRowSummaries, onChange: onIncludeRowSummariesChanged, mr: 2 }))))))));
32
36
  };
@@ -5,7 +5,6 @@ import { FloatingFilterWrapperFactory } from './FloatingFilterWrapper';
5
5
  import { convertAdaptableStyleToCSS, getVariableColor, normalizeStyleForAgGrid, } from '../Utilities/Helpers/StyleHelper';
6
6
  import StringExtensions from '../Utilities/Extensions/StringExtensions';
7
7
  import { createBaseContext } from '../Utilities/ObjectFactory';
8
- import clamp from 'lodash/clamp';
9
8
  import tinycolor from 'tinycolor2';
10
9
  import UIHelper from '../View/UIHelper';
11
10
  import { getPercentBarRendererForColumn } from './PercentBarRenderer';
@@ -665,6 +664,7 @@ export class AgGridColumnAdapter {
665
664
  return Object.assign(Object.assign({}, this.getFormatColumnCellStyle(gridCell.column, activeFormatColumnsWithStyle, params)), styledColumnStyle);
666
665
  }
667
666
  getStyledColumnStyle(styledColumn, abColumn, params) {
667
+ var _a, _b;
668
668
  let style = {};
669
669
  const gradientStyle = styledColumn === null || styledColumn === void 0 ? void 0 : styledColumn.GradientStyle;
670
670
  if (params.value === undefined) {
@@ -672,18 +672,24 @@ export class AgGridColumnAdapter {
672
672
  }
673
673
  let colValue = params.value;
674
674
  if (this.adaptableApi.gridApi.isGroupRowNode(params.node)) {
675
- if (styledColumn.IncludeGroupedRows) {
676
- const minColumnValue = this.adaptableApi.styledColumnApi.internalApi.getMinValueForNumericColumn(abColumn);
677
- const maxColumnValue = this.adaptableApi.styledColumnApi.internalApi.getMaxValueForNumericColumn(abColumn);
678
- /**
679
- * Color should always be in bounds, it should not overflow.
680
- * If the value is out of range, it shoul set the maximum/minimum color.
681
- */
682
- colValue = clamp(params.value, minColumnValue, maxColumnValue);
683
- }
684
- else {
685
- return style;
686
- }
675
+ // We no longer support Grouped Rows
676
+ return style;
677
+ // if (styledColumn.IncludeGroupedRows) {
678
+ // const minColumnValue =
679
+ // this.adaptableApi.styledColumnApi.internalApi.getMinValueForNumericColumn(abColumn);
680
+ // const maxColumnValue =
681
+ // this.adaptableApi.styledColumnApi.internalApi.getMaxValueForNumericColumn(abColumn);
682
+ // /**
683
+ // * Color should always be in bounds, it should not overflow.
684
+ // * If the value is out of range, it shoul set the maximum/minimum color.
685
+ // */
686
+ // colValue = clamp(params.value, minColumnValue, maxColumnValue);
687
+ // } else {
688
+ // return style;
689
+ // }
690
+ }
691
+ if (((_b = (_a = params === null || params === void 0 ? void 0 : params.node) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b[ROW_SUMMARY_ROW_ID]) && !styledColumn.IncludeRowSummaries) {
692
+ return style;
687
693
  }
688
694
  if (gradientStyle) {
689
695
  const min = this.adaptableApi.styledColumnApi.internalApi.getNumericStyleMinValue(styledColumn, abColumn, params.node, colValue);
@@ -10,6 +10,7 @@ export declare class AgGridMenuAdapter {
10
10
  destroy(): void;
11
11
  buildColumnMenu(params: GetMainMenuItemsParams, originalGetMainMenuItems: GetMainMenuItems): (string | MenuItemDef)[];
12
12
  buildContextMenu(params: GetContextMenuItemsParams, originalGetContextMenuItems: GetContextMenuItems): (string | MenuItemDef)[];
13
+ private removeConsecutiveSeparators;
13
14
  private createColumnMenuContextObject;
14
15
  private createAdaptableContextMenuItems;
15
16
  private createContextMenuContextObject;
@@ -17,6 +18,10 @@ export declare class AgGridMenuAdapter {
17
18
  private mapCustomMenuItemToAgGridMenuDefinition;
18
19
  private mapUserMenuItemToAgGridMenuDefinition;
19
20
  private buildContextMenuDefaultStructure;
21
+ /**
22
+ * Hide menu group with no subitems or elevate single subitem to parent level
23
+ */
24
+ private normalizeMenuGroup;
20
25
  /**
21
26
  * Default strategy for menu items: return as is if there is only one item, otherwise group them under a parent item
22
27
  */