@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.
- package/base.css +3 -13
- package/base.css.map +1 -1
- package/index.css +3 -13
- package/index.css.map +1 -1
- package/package.json +1 -1
- package/src/AdaptableOptions/AdaptableFrameworkComponent.d.ts +3 -0
- package/src/AdaptableOptions/MenuOptions.d.ts +1 -1
- package/src/Api/GridApi.d.ts +4 -1
- package/src/Api/Implementation/ConfigApiImpl.js +0 -1
- package/src/Api/Implementation/GridApiImpl.d.ts +1 -1
- package/src/Api/Implementation/GridApiImpl.js +6 -1
- package/src/Api/Implementation/UserInterfaceApiImpl.d.ts +14 -5
- package/src/Api/Implementation/UserInterfaceApiImpl.js +26 -4
- package/src/Api/Internal/AdaptableInternalApi.d.ts +0 -1
- package/src/Api/Internal/AdaptableInternalApi.js +2 -6
- package/src/Api/Internal/FormatColumnInternalApi.js +6 -2
- package/src/Api/Internal/LayoutInternalApi.js +1 -1
- package/src/Api/UserInterfaceApi.d.ts +15 -2
- package/src/PredefinedConfig/Common/AdaptableIcon.d.ts +1 -1
- package/src/PredefinedConfig/Common/Menu.d.ts +1 -1
- package/src/PredefinedConfig/Common/Menu.js +22 -12
- package/src/PredefinedConfig/FormatColumnState.d.ts +4 -0
- package/src/PredefinedConfig/PopupState.d.ts +1 -2
- package/src/PredefinedConfig/StyledColumnState.d.ts +5 -0
- package/src/PredefinedConfig/SystemState.d.ts +4 -2
- package/src/Redux/ActionsReducers/PopupRedux.d.ts +5 -13
- package/src/Redux/ActionsReducers/PopupRedux.js +0 -19
- package/src/Redux/ActionsReducers/SystemRedux.d.ts +9 -3
- package/src/Redux/ActionsReducers/SystemRedux.js +8 -5
- package/src/Strategy/ExportModule.d.ts +0 -1
- package/src/Strategy/ExportModule.js +39 -28
- package/src/Strategy/LayoutModule.d.ts +1 -8
- package/src/Strategy/LayoutModule.js +3 -113
- package/src/Strategy/StyledColumnModule.js +5 -2
- package/src/Strategy/Utilities/FormatColumn/getFormatColumnSettingsViewItems.js +1 -0
- package/src/Utilities/Interface/MessagePopups.d.ts +0 -3
- package/src/Utilities/Services/RowSummaryService.d.ts +22 -0
- package/src/Utilities/Services/RowSummaryService.js +141 -0
- package/src/View/FormatColumn/Wizard/FormatColumnSettingsWizardSection.js +11 -2
- package/src/View/StyledColumn/Wizard/StyledColumnWizard.js +1 -1
- package/src/View/StyledColumn/Wizard/StyledColumnWizardSettingsSection.js +14 -10
- package/src/agGrid/AgGridColumnAdapter.js +19 -13
- package/src/agGrid/AgGridMenuAdapter.d.ts +5 -0
- package/src/agGrid/AgGridMenuAdapter.js +111 -57
- package/src/agGrid/BadgeRenderer.js +7 -1
- package/src/agGrid/PercentBarRenderer.js +3 -1
- package/src/components/CheckBox/index.js +1 -1
- package/src/components/ProgressIndicator/ProgressIndicator.js +15 -6
- package/src/components/icons/copy.d.ts +3 -0
- package/src/components/icons/copy.js +4 -0
- package/src/components/icons/index.js +2 -0
- package/src/env.js +2 -2
- package/src/metamodel/adaptable.metamodel.js +1 -1
- package/src/types.d.ts +1 -1
- 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 {
|
|
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
|
|
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
|
-
|
|
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
|
|
77
|
+
returnMenuItems.push(...this.buildReportMenuItems(selectedRowReport));
|
|
64
78
|
}
|
|
65
79
|
return returnMenuItems;
|
|
66
80
|
}
|
|
67
|
-
buildReportMenuItems(report
|
|
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(
|
|
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(
|
|
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.
|
|
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.
|
|
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 {
|
|
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.
|
|
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 (
|
|
174
|
+
if (styledColumn.BadgeStyle) {
|
|
175
175
|
specificTypeItems.push({
|
|
176
176
|
name: 'Settings',
|
|
177
|
-
values: [
|
|
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',
|
|
@@ -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
|
-
}
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
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
|
*/
|