@adaptabletools/adaptable 18.0.0-canary.3 → 18.0.0-canary.5
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/agGrid.d.ts +4 -21
- package/agGrid.js +9 -26
- package/base.css +4 -1
- package/base.css.map +1 -1
- package/index.css +79 -68
- package/index.css.map +1 -1
- package/package.json +3 -4
- package/src/AdaptableInterfaces/IAdaptable.d.ts +55 -109
- package/src/AdaptableOptions/AdaptableOptions.d.ts +11 -5
- package/src/AdaptableOptions/ColumnFilterOptions.d.ts +4 -4
- package/src/AdaptableOptions/{CommentsOptions.d.ts → CommentOptions.d.ts} +5 -5
- package/src/AdaptableOptions/MenuOptions.d.ts +1 -1
- package/src/AdaptableOptions/MenuOptions.js +1 -5
- package/src/AdaptableOptions/{NotesOptions.d.ts → NoteOptions.d.ts} +1 -1
- package/src/AdaptableOptions/UserInterfaceOptions.d.ts +17 -0
- package/src/Api/AdaptableApi.d.ts +5 -0
- package/src/Api/BulkUpdateApi.d.ts +0 -5
- package/src/Api/Events/AdaptableReady.d.ts +3 -3
- package/src/Api/Events/GridDataChanged.d.ts +4 -4
- package/src/Api/GridApi.d.ts +14 -13
- package/src/Api/Implementation/ActionColumnApiImpl.d.ts +2 -0
- package/src/Api/Implementation/ActionColumnApiImpl.js +33 -0
- package/src/Api/Implementation/AdaptableApiImpl.d.ts +1 -0
- package/src/Api/Implementation/AdaptableApiImpl.js +3 -0
- package/src/Api/Implementation/ApiBase.d.ts +2 -1
- package/src/Api/Implementation/ApiBase.js +4 -1
- package/src/Api/Implementation/BulkUpdateApiImpl.d.ts +0 -1
- package/src/Api/Implementation/BulkUpdateApiImpl.js +0 -4
- package/src/Api/Implementation/CommentsApiImpl.js +2 -1
- package/src/Api/Implementation/ConfigApiImpl.js +8 -3
- package/src/Api/Implementation/GridApiImpl.d.ts +3 -3
- package/src/Api/Implementation/GridApiImpl.js +20 -14
- package/src/Api/Implementation/LayoutApiImpl.d.ts +4 -0
- package/src/Api/Implementation/LayoutApiImpl.js +14 -0
- package/src/Api/Implementation/NotesApiImpl.d.ts +2 -4
- package/src/Api/Implementation/NotesApiImpl.js +4 -8
- package/src/Api/Implementation/OptionsApiImpl.d.ts +1 -1
- package/src/Api/Implementation/OptionsApiImpl.js +2 -2
- package/src/Api/Implementation/StatusBarApiImpl.d.ts +0 -1
- package/src/Api/Implementation/StatusBarApiImpl.js +0 -3
- package/src/Api/Implementation/ToolPanelApiImpl.js +6 -6
- package/src/Api/Internal/ActionRowInternalApi.d.ts +5 -1
- package/src/Api/Internal/ActionRowInternalApi.js +106 -0
- package/src/Api/Internal/AdaptableInternalApi.d.ts +3 -4
- package/src/Api/Internal/AdaptableInternalApi.js +10 -8
- package/src/Api/Internal/CalculatedColumnInternalApi.d.ts +2 -0
- package/src/Api/Internal/CalculatedColumnInternalApi.js +70 -0
- package/src/Api/Internal/ColumnFilterInternalApi.d.ts +1 -0
- package/src/Api/Internal/ColumnFilterInternalApi.js +11 -1
- package/src/Api/Internal/ColumnInternalApi.d.ts +4 -1
- package/src/Api/Internal/ColumnInternalApi.js +12 -0
- package/src/Api/Internal/CustomSortInternalApi.d.ts +3 -2
- package/src/Api/Internal/CustomSortInternalApi.js +32 -1
- package/src/Api/Internal/DataSetInternalApi.js +1 -1
- package/src/Api/Internal/FreeTextColumnInternalApi.d.ts +2 -0
- package/src/Api/Internal/FreeTextColumnInternalApi.js +59 -0
- package/src/Api/Internal/GridFilterInternalApi.js +1 -1
- package/src/Api/Internal/GridInternalApi.d.ts +21 -3
- package/src/Api/Internal/GridInternalApi.js +126 -7
- package/src/Api/Internal/TeamSharingInternalApi.js +1 -1
- package/src/Api/InteropioPluginApi.d.ts +2 -2
- package/src/Api/LayoutApi.d.ts +8 -0
- package/src/Api/OptionsApi.d.ts +1 -1
- package/src/EnvVars.d.ts +3 -0
- package/src/EnvVars.js +4 -0
- package/src/PredefinedConfig/Common/AggregationColumns.d.ts +1 -0
- package/src/PredefinedConfig/Common/AggregationColumns.js +3 -0
- package/src/PredefinedConfig/NotesState.d.ts +10 -20
- package/src/PredefinedConfig/PredefinedConfig.d.ts +1 -1
- package/src/Redux/ActionsReducers/NotesRedux.d.ts +3 -4
- package/src/Redux/ActionsReducers/NotesRedux.js +8 -7
- package/src/Redux/Store/AdaptableStore.d.ts +4 -6
- package/src/Redux/Store/AdaptableStore.js +22 -50
- package/src/Redux/Store/Interface/IAdaptableStore.d.ts +7 -1
- package/src/Strategy/AdaptableModuleBase.d.ts +2 -3
- package/src/Strategy/AdaptableModuleBase.js +4 -7
- package/src/Strategy/AlertModule.d.ts +1 -2
- package/src/Strategy/AlertModule.js +2 -55
- package/src/Strategy/CalculatedColumnModule.d.ts +2 -3
- package/src/Strategy/CalculatedColumnModule.js +5 -25
- package/src/Strategy/ChartingModule.d.ts +0 -1
- package/src/Strategy/ChartingModule.js +2 -22
- package/src/Strategy/ColumnFilterModule.d.ts +1 -2
- package/src/Strategy/ColumnFilterModule.js +1 -64
- package/src/Strategy/CommentsModule.d.ts +1 -0
- package/src/Strategy/CommentsModule.js +2 -1
- package/src/Strategy/CustomSortModule.js +1 -1
- package/src/Strategy/DashboardModule.d.ts +1 -2
- package/src/Strategy/DashboardModule.js +1 -8
- package/src/Strategy/DataChangeHistoryModule.d.ts +1 -0
- package/src/Strategy/DataChangeHistoryModule.js +3 -1
- package/src/Strategy/DataSetModule.d.ts +1 -1
- package/src/Strategy/DataSetModule.js +1 -1
- package/src/Strategy/FlashingCellModule.d.ts +1 -2
- package/src/Strategy/FlashingCellModule.js +2 -15
- package/src/Strategy/FormatColumnModule.d.ts +0 -2
- package/src/Strategy/FormatColumnModule.js +0 -47
- package/src/Strategy/FreeTextColumnModule.d.ts +0 -1
- package/src/Strategy/FreeTextColumnModule.js +0 -30
- package/src/Strategy/GridFilterModule.d.ts +0 -1
- package/src/Strategy/GridFilterModule.js +0 -37
- package/src/Strategy/Interface/IModule.d.ts +0 -1
- package/src/Strategy/LayoutModule.d.ts +1 -3
- package/src/Strategy/LayoutModule.js +6 -50
- package/src/Strategy/NamedQueryModule.d.ts +0 -1
- package/src/Strategy/NamedQueryModule.js +0 -19
- package/src/Strategy/PlusMinusModule.d.ts +1 -1
- package/src/Strategy/PlusMinusModule.js +1 -1
- package/src/Strategy/ScheduleModule.d.ts +1 -1
- package/src/Strategy/ScheduleModule.js +1 -1
- package/src/Strategy/ShortcutModule.d.ts +1 -1
- package/src/Strategy/ShortcutModule.js +1 -1
- package/src/Strategy/StyledColumnModule.d.ts +0 -1
- package/src/Strategy/StyledColumnModule.js +0 -21
- package/src/Strategy/TeamSharingModule.d.ts +1 -0
- package/src/Strategy/TeamSharingModule.js +5 -5
- package/src/Strategy/ToolPanelModule.d.ts +0 -1
- package/src/Strategy/ToolPanelModule.js +0 -23
- package/src/Utilities/Constants/DocumentationLinkConstants.js +1 -1
- package/src/Utilities/Constants/GeneralConstants.d.ts +1 -0
- package/src/Utilities/Constants/GeneralConstants.js +1 -0
- package/src/Utilities/Defaults/DefaultSettingsPanel.js +5 -4
- package/src/Utilities/Helpers/AdaptableHelper.d.ts +0 -3
- package/src/Utilities/Helpers/AdaptableHelper.js +0 -58
- package/src/Utilities/Helpers/Helper.d.ts +2 -0
- package/src/Utilities/Helpers/Helper.js +4 -0
- package/src/Utilities/Services/AggregatedScalarLiveValue.js +3 -1
- package/src/Utilities/Services/CellPopupService.js +0 -1
- package/src/Utilities/Services/LicenseService/index.d.ts +3 -0
- package/src/Utilities/Services/LicenseService/index.js +10 -3
- package/src/Utilities/Services/MetamodelService.d.ts +1 -1
- package/src/Utilities/Services/MetamodelService.js +6 -3
- package/src/Utilities/Services/RowEditService.d.ts +3 -2
- package/src/Utilities/Services/RowEditService.js +3 -1
- package/src/View/AdaptableView.js +0 -2
- package/src/View/AdaptableWizardView/AdaptableConfigurationDialog/ConfigurationWizard.js +2 -2
- package/src/View/BulkUpdate/BulkUpdatePopup.js +1 -1
- package/src/View/CalculatedColumn/utils.d.ts +1 -1
- package/src/View/CellSummary/CellSummaryPopup.js +1 -1
- package/src/View/Comments/CommentsPopup.js +12 -8
- package/src/View/Components/Popups/AdaptableLoadingScreen.d.ts +6 -5
- package/src/View/Components/Popups/AdaptableLoadingScreen.js +19 -9
- package/src/View/Components/Popups/GridCellPopup/GridCellPopup.js +1 -1
- package/src/View/Components/Popups/WindowPopups/windowFactory.d.ts +1 -0
- package/src/View/Components/Popups/WindowPopups/windowFactory.js +3 -0
- package/src/View/Components/Selectors/PermittedValuesSelector.js +1 -1
- package/src/View/CustomSort/CustomSortSummary.js +1 -1
- package/src/View/DataChangeHistory/DataChangeHistoryGrid.js +1 -1
- package/src/View/GridFilter/GridFilterViewPanel.js +6 -2
- package/src/View/GridInfo/GridInfoPopup/GridInfoPopup.js +2 -3
- package/src/View/Layout/TransposedPopup.d.ts +3 -0
- package/src/View/Layout/TransposedPopup.js +193 -0
- package/src/View/Layout/Wizard/LayoutWizard.js +1 -1
- package/src/View/Notes/NotesPopup.js +9 -11
- package/src/View/Theme/ThemeSelector.js +3 -3
- package/src/agGrid/ActionColumnRenderer.js +4 -4
- package/src/agGrid/Adaptable.d.ts +3 -455
- package/src/agGrid/Adaptable.js +8 -5292
- package/src/agGrid/AdaptableAgGrid.d.ts +336 -0
- package/src/agGrid/AdaptableAgGrid.js +3780 -0
- package/src/agGrid/AdaptableLogger.js +77 -11
- package/src/agGrid/AgGridAdapter.d.ts +54 -0
- package/src/agGrid/AgGridAdapter.js +549 -0
- package/src/agGrid/AgGridColumnAdapter.d.ts +56 -0
- package/src/agGrid/AgGridColumnAdapter.js +813 -0
- package/src/agGrid/AgGridMenuAdapter.d.ts +28 -0
- package/src/agGrid/AgGridMenuAdapter.js +271 -0
- package/src/agGrid/AgGridOptionsService.d.ts +11 -0
- package/src/agGrid/AgGridOptionsService.js +50 -0
- package/src/agGrid/BadgeRenderer.js +1 -1
- package/src/agGrid/CheckboxRenderer.js +1 -1
- package/src/agGrid/FilterWrapper.d.ts +2 -2
- package/src/agGrid/FilterWrapper.js +1 -1
- package/src/agGrid/attachAddaptableColumnTypes.d.ts +12 -12
- package/src/agGrid/defaultAdaptableOptions.d.ts +3 -0
- package/src/{Utilities/Defaults/DefaultAdaptableOptions.js → agGrid/defaultAdaptableOptions.js} +70 -9
- package/src/agGrid/editors/AdaptableDateEditor/index.js +2 -2
- package/src/agGrid/editors/AdaptableNumberEditor/index.js +2 -2
- package/src/components/Datepicker/index.d.ts +1 -1
- package/src/components/InfiniteTable/index.js +2 -2
- package/src/components/Modal/index.d.ts +1 -0
- package/src/components/Modal/index.js +4 -3
- package/src/components/Select/Select.d.ts +2 -0
- package/src/components/Select/Select.js +2 -2
- package/src/env.js +2 -2
- package/src/metamodel/adaptable.metamodel.d.ts +39 -11
- package/src/metamodel/adaptable.metamodel.js +73 -32
- package/src/migration/AdaptableUpgradeHelper.d.ts +38 -0
- package/src/migration/AdaptableUpgradeHelper.js +48 -0
- package/src/migration/VersionUpgrade.d.ts +8 -0
- package/src/migration/VersionUpgrade.js +11 -0
- package/src/migration/VersionUpgrade17.d.ts +18 -0
- package/src/migration/VersionUpgrade17.js +342 -0
- package/src/migration/VersionUpgrade18.d.ts +5 -0
- package/src/migration/VersionUpgrade18.js +6 -0
- package/src/types.d.ts +7 -3
- package/tsconfig.esm.tsbuildinfo +1 -1
- package/src/Utilities/Defaults/DefaultAdaptableOptions.d.ts +0 -2
- package/src/Utilities/Services/Interface/IRowEditService.d.ts +0 -3
- package/src/Utilities/Services/Interface/IRowEditService.js +0 -1
- package/src/agGrid/agGridHelper.d.ts +0 -57
- package/src/agGrid/agGridHelper.js +0 -686
- package/src/agGrid/agGridMenuHelper.d.ts +0 -46
- package/src/agGrid/agGridMenuHelper.js +0 -668
- /package/src/AdaptableOptions/{CommentsOptions.js → CommentOptions.js} +0 -0
- /package/src/AdaptableOptions/{NotesOptions.js → NoteOptions.js} +0 -0
|
@@ -0,0 +1,3780 @@
|
|
|
1
|
+
import throttle from 'lodash/throttle';
|
|
2
|
+
import debounce from 'lodash/debounce';
|
|
3
|
+
import { createGrid, Events, ModuleNames, RowNode, } from '@ag-grid-community/core';
|
|
4
|
+
import { AdaptableLogger } from './AdaptableLogger';
|
|
5
|
+
import { PrimaryKeyDocsLink } from '../Utilities/Constants/DocumentationLinkConstants';
|
|
6
|
+
import StringExtensions from '../Utilities/Extensions/StringExtensions';
|
|
7
|
+
import Emitter from '../Utilities/Emitter';
|
|
8
|
+
import { applyDefaultAdaptableOptions } from './defaultAdaptableOptions';
|
|
9
|
+
import { AgGridAdapter } from './AgGridAdapter';
|
|
10
|
+
import * as GeneralConstants from '../Utilities/Constants/GeneralConstants';
|
|
11
|
+
import { AB_FDC3_COLUMN, AB_SPECIAL_COLUMN, AUTOGENERATED_PK_COLUMN, BLANK_DISTINCT_COLUMN_VALUE, DARK_THEME, DEFAULT_LAYOUT, GROUP_PATH_SEPARATOR, HALF_SECOND, LIGHT_THEME, } from '../Utilities/Constants/GeneralConstants';
|
|
12
|
+
import { DataService } from '../Utilities/Services/DataService';
|
|
13
|
+
import { AdaptableStore } from '../Redux/Store/AdaptableStore';
|
|
14
|
+
import { AdaptableApiImpl } from '../Api/Implementation/AdaptableApiImpl';
|
|
15
|
+
import { Fdc3Service } from '../Utilities/Services/Fdc3Service';
|
|
16
|
+
import { CellPopupService } from '../Utilities/Services/CellPopupService';
|
|
17
|
+
import { ChartingService } from '../Utilities/Services/ChartingService';
|
|
18
|
+
import { ThemeService } from '../Utilities/Services/ThemeService';
|
|
19
|
+
import { ValidationService } from '../Utilities/Services/ValidationService';
|
|
20
|
+
import { ReportService } from '../Utilities/Services/ReportService';
|
|
21
|
+
import { ModuleService } from '../Utilities/Services/ModuleService';
|
|
22
|
+
import { CalculatedColumnExpressionService } from '../Utilities/Services/CalculatedColumnExpressionService';
|
|
23
|
+
import { EntitlementService } from '../Utilities/Services/EntitlementService';
|
|
24
|
+
import { QueryLanguageService } from '../Utilities/Services/QueryLanguageService';
|
|
25
|
+
import { AlertService } from '../Utilities/Services/AlertService';
|
|
26
|
+
import { TeamSharingService } from '../Utilities/Services/TeamSharingService';
|
|
27
|
+
import { MetamodelService } from '../Utilities/Services/MetamodelService';
|
|
28
|
+
import { LicenseService } from '../Utilities/Services/LicenseService';
|
|
29
|
+
import { ALL_TOOL_PANELS } from '../PredefinedConfig/Common/Types';
|
|
30
|
+
import * as ModuleConstants from '../Utilities/Constants/ModuleConstants';
|
|
31
|
+
import { GridFilterModuleId } from '../Utilities/Constants/ModuleConstants';
|
|
32
|
+
import { DashboardModule } from '../Strategy/DashboardModule';
|
|
33
|
+
import { AlertModule } from '../Strategy/AlertModule';
|
|
34
|
+
import { FlashingCellModule } from '../Strategy/FlashingCellModule';
|
|
35
|
+
import { BulkUpdateModule } from '../Strategy/BulkUpdateModule';
|
|
36
|
+
import { CalculatedColumnModule } from '../Strategy/CalculatedColumnModule';
|
|
37
|
+
import { CellSummaryModule } from '../Strategy/CellSummaryModule';
|
|
38
|
+
import { CustomSortModule } from '../Strategy/CustomSortModule';
|
|
39
|
+
import { DataChangeHistoryModule } from '../Strategy/DataChangeHistoryModule';
|
|
40
|
+
import { DataImportModule } from '../Strategy/DataImportModule';
|
|
41
|
+
import { DataSetModule } from '../Strategy/DataSetModule';
|
|
42
|
+
import { ExportModule } from '../Strategy/ExportModule';
|
|
43
|
+
import { ColumnFilterModule } from '../Strategy/ColumnFilterModule';
|
|
44
|
+
import { FormatColumnModule } from '../Strategy/FormatColumnModule';
|
|
45
|
+
import { FreeTextColumnModule } from '../Strategy/FreeTextColumnModule';
|
|
46
|
+
import { LayoutModule } from '../Strategy/LayoutModule';
|
|
47
|
+
import { PlusMinusModule } from '../Strategy/PlusMinusModule';
|
|
48
|
+
import { QuickSearchModule } from '../Strategy/QuickSearchModule';
|
|
49
|
+
import { ScheduleModule } from '../Strategy/ScheduleModule';
|
|
50
|
+
import { SmartEditModule } from '../Strategy/SmartEditModule';
|
|
51
|
+
import { ShortcutModule } from '../Strategy/ShortcutModule';
|
|
52
|
+
import { StateManagementModule } from '../Strategy/StateManagementModule';
|
|
53
|
+
import { TeamSharingModule } from '../Strategy/TeamSharingModule';
|
|
54
|
+
import { ToolPanelModule } from '../Strategy/ToolPanelModule';
|
|
55
|
+
import { SystemStatusModule } from '../Strategy/SystemStatusModule';
|
|
56
|
+
import { ThemeModule } from '../Strategy/ThemeModule';
|
|
57
|
+
import { GridInfoModule } from '../Strategy/GridInfoModule';
|
|
58
|
+
import { ColumnInfoModule } from '../Strategy/ColumnInfoModule';
|
|
59
|
+
import { SettingsPanelModule } from '../Strategy/SettingsPanelModule';
|
|
60
|
+
import { StatusBarModule } from '../Strategy/StatusBarModule';
|
|
61
|
+
import { ChartingModule } from '../Strategy/ChartingModule';
|
|
62
|
+
import { NotesModule } from '../Strategy/NotesModule';
|
|
63
|
+
import { StyledColumnModule } from '../Strategy/StyledColumnModule';
|
|
64
|
+
import { Fdc3Module } from '../Strategy/Fdc3Module';
|
|
65
|
+
import { GridFilterModule } from '../Strategy/GridFilterModule';
|
|
66
|
+
import { NamedQueryModule } from '../Strategy/NamedQueryModule';
|
|
67
|
+
import { CommentsModule } from '../Strategy/CommentsModule';
|
|
68
|
+
import { AdaptableNumberEditor, ReactAdaptableNumberEditor } from './editors/AdaptableNumberEditor';
|
|
69
|
+
import { AdaptableDateEditor, ReactAdaptableDateEditor } from './editors/AdaptableDateEditor';
|
|
70
|
+
import { Helper } from '../Utilities/Helpers/Helper';
|
|
71
|
+
import { createUuid } from '../components/utils/uuid';
|
|
72
|
+
import UIHelper from '../View/UIHelper';
|
|
73
|
+
import { getAdaptableToolPanelAgGridComponent } from '../View/Components/ToolPanel/AdaptableToolPanel';
|
|
74
|
+
import { ADAPTABLE_STATUS_PANEL } from '../PredefinedConfig/StatusBarState';
|
|
75
|
+
import { createAgStatusPanelComponent } from './createAgStatusPanelComponent';
|
|
76
|
+
import { AdaptableStatusBar } from '../View/StatusBar/AdaptableStatusBar';
|
|
77
|
+
import ArrayExtensions from '../Utilities/Extensions/ArrayExtensions';
|
|
78
|
+
import { AgGridMenuAdapter } from './AgGridMenuAdapter';
|
|
79
|
+
import { AdaptableApp } from '../View/AdaptableView';
|
|
80
|
+
import { renderReactRoot as defaultRenderReactRoot } from '../renderReactRoot';
|
|
81
|
+
import { AgGridOptionsService } from './AgGridOptionsService';
|
|
82
|
+
import { parseDateValue } from '../Utilities/Helpers/DateHelper';
|
|
83
|
+
import { AgGridColumnAdapter } from './AgGridColumnAdapter';
|
|
84
|
+
import uniqBy from 'lodash/uniqBy';
|
|
85
|
+
import getScrollbarSize from '../Utilities/getScrollbarSize';
|
|
86
|
+
import { isWeightedAverageAggregation, WEIGHTED_AVERAGE_AGG_FN_NAME, } from '../PredefinedConfig/Common/AggregationColumns';
|
|
87
|
+
import lodashIsEqual from 'lodash/isEqual';
|
|
88
|
+
import { RowEditService } from '../Utilities/Services/RowEditService';
|
|
89
|
+
import { weightedAverage } from './weightedAverage';
|
|
90
|
+
import { sortWithOrderArray } from '../Utilities/sortWithOrder';
|
|
91
|
+
import { FilterOnDataChangeOptions } from '../PredefinedConfig/Common/Enums';
|
|
92
|
+
import ObjectFactory from '../Utilities/ObjectFactory';
|
|
93
|
+
import { ADAPTABLE_PUBLISH_TIMESTAMP } from '../EnvVars';
|
|
94
|
+
import { AdaptableUpgradeHelper } from '../migration/AdaptableUpgradeHelper';
|
|
95
|
+
import { ensurePortalElement } from '../components/Modal';
|
|
96
|
+
import { AdaptableLoadingScreen } from '../View/Components/Popups/AdaptableLoadingScreen';
|
|
97
|
+
import { createElement } from 'react';
|
|
98
|
+
const RowNodeProto = RowNode.prototype;
|
|
99
|
+
const RowNode_dispatchLocalEvent = RowNodeProto.dispatchLocalEvent;
|
|
100
|
+
/**
|
|
101
|
+
* AgGrid does not expose 'cellChanged' and 'dataChanged'
|
|
102
|
+
* so we have to override `dispatchLocalEvent`
|
|
103
|
+
* and hook our own functionality into it
|
|
104
|
+
*/
|
|
105
|
+
RowNodeProto.dispatchLocalEvent = function (event) {
|
|
106
|
+
const node = event.node;
|
|
107
|
+
const result = RowNode_dispatchLocalEvent.apply(this, arguments);
|
|
108
|
+
const extractGridApiFromRowNode = (rowNode) => {
|
|
109
|
+
var _a;
|
|
110
|
+
// starting with AG Grid 26.1.0 the gridApi is wrapped in a Beans property
|
|
111
|
+
const rowNodeApi = (_a = rowNode === null || rowNode === void 0 ? void 0 : rowNode.beans) === null || _a === void 0 ? void 0 : _a.gridApi;
|
|
112
|
+
if (!rowNodeApi) {
|
|
113
|
+
AdaptableLogger.consoleErrorBase(`No GridAPI found in passed RowNode, this should never happen!`, rowNode);
|
|
114
|
+
}
|
|
115
|
+
return rowNodeApi;
|
|
116
|
+
};
|
|
117
|
+
// we don't know from which instance of aggrid this is coming,
|
|
118
|
+
// as this fn is shared by all instances
|
|
119
|
+
if (node) {
|
|
120
|
+
AdaptableAgGrid.forEachAdaptable((adaptable) => {
|
|
121
|
+
var _a;
|
|
122
|
+
if (extractGridApiFromRowNode(node) !== ((_a = adaptable.agGridAdapter) === null || _a === void 0 ? void 0 : _a.getAgGridApi(true))) {
|
|
123
|
+
// the event is coming from another aggrid instance
|
|
124
|
+
// so IGNORE IT
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
// we're on the correct instance, so do this
|
|
128
|
+
//@ts-ignore
|
|
129
|
+
const fn = adaptable.rowListeners ? adaptable.rowListeners[event.type] : null;
|
|
130
|
+
if (fn) {
|
|
131
|
+
fn(event);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
};
|
|
137
|
+
const adaptableInstances = {};
|
|
138
|
+
const publishTimestamp = Number(ADAPTABLE_PUBLISH_TIMESTAMP);
|
|
139
|
+
export class AdaptableAgGrid {
|
|
140
|
+
constructor() {
|
|
141
|
+
this.columnMinMaxValuesCache = {};
|
|
142
|
+
this.renderReactRoot = (node, container) => defaultRenderReactRoot(node, container);
|
|
143
|
+
/**
|
|
144
|
+
* Temporary, these are MIGRATION technical debts, and should be removed as soon as possible
|
|
145
|
+
*/
|
|
146
|
+
this.adaptableStatusPanelKeys = [];
|
|
147
|
+
// only for our private / internal events used within Adaptable
|
|
148
|
+
// public events are emitted through the EventApi
|
|
149
|
+
this._emit = (eventName, data) => {
|
|
150
|
+
if (this.emitter) {
|
|
151
|
+
return this.emitter.emit(eventName, data);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
this._emitSync = (eventName, data) => {
|
|
155
|
+
if (this.emitter) {
|
|
156
|
+
return this.emitter.emitSync(eventName, data);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
this._on = (eventName, callback) => {
|
|
160
|
+
if (!this.emitter) {
|
|
161
|
+
return () => { };
|
|
162
|
+
}
|
|
163
|
+
return this.emitter.on(eventName, callback);
|
|
164
|
+
};
|
|
165
|
+
this._onIncludeFired = (eventName, callback) => {
|
|
166
|
+
if (!this.emitter) {
|
|
167
|
+
return () => { };
|
|
168
|
+
}
|
|
169
|
+
return this.emitter.onIncludeFired(eventName, callback);
|
|
170
|
+
};
|
|
171
|
+
this.lifecycleState = 'initial';
|
|
172
|
+
this.emitter = new Emitter();
|
|
173
|
+
this.agGridOptionsService = new AgGridOptionsService(this);
|
|
174
|
+
this.agGridAdapter = new AgGridAdapter(this);
|
|
175
|
+
this.agGridMenuAdapter = new AgGridMenuAdapter(this);
|
|
176
|
+
this.agGridColumnAdapter = new AgGridColumnAdapter(this);
|
|
177
|
+
this.DataService = new DataService(this);
|
|
178
|
+
}
|
|
179
|
+
static forEachAdaptable(fn) {
|
|
180
|
+
Object.keys(adaptableInstances).forEach((key) => {
|
|
181
|
+
fn(adaptableInstances[key]);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
static collectInstance(adaptable, adaptableId) {
|
|
185
|
+
adaptable._id = adaptableId;
|
|
186
|
+
adaptableInstances[adaptable._id] = adaptable;
|
|
187
|
+
}
|
|
188
|
+
static dismissInstance(adaptable) {
|
|
189
|
+
delete adaptableInstances[adaptable._id];
|
|
190
|
+
}
|
|
191
|
+
get isReady() {
|
|
192
|
+
return this.lifecycleState === 'ready';
|
|
193
|
+
}
|
|
194
|
+
get isDestroyed() {
|
|
195
|
+
return this.lifecycleState === 'preDestroyed';
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Internal initializer for Adaptable, directly called by the React and Angular Adaptable wrappers
|
|
199
|
+
* @private
|
|
200
|
+
*/
|
|
201
|
+
static async _initInternal(config) {
|
|
202
|
+
let promise = null;
|
|
203
|
+
if (Array.isArray(config.adaptableOptions.plugins)) {
|
|
204
|
+
const agGridOptions = {
|
|
205
|
+
gridOptions: config.gridOptions,
|
|
206
|
+
modules: config.modules,
|
|
207
|
+
};
|
|
208
|
+
for (let plugin of config.adaptableOptions.plugins) {
|
|
209
|
+
promise =
|
|
210
|
+
promise && promise.then
|
|
211
|
+
? promise.then(() => {
|
|
212
|
+
return plugin.beforeInit(config.adaptableOptions, agGridOptions);
|
|
213
|
+
})
|
|
214
|
+
: plugin.beforeInit(config.adaptableOptions, agGridOptions);
|
|
215
|
+
}
|
|
216
|
+
// if gridOptions changed, we need to update the runtimeConfig
|
|
217
|
+
if (agGridOptions.gridOptions !== config.gridOptions) {
|
|
218
|
+
// This allows plugins to modify
|
|
219
|
+
// FIXME AFL MIG: clarify if this is still needed (for NoCode Plugin?)
|
|
220
|
+
// it looks like a code smell, ideally we should get rid of it
|
|
221
|
+
config.gridOptions = agGridOptions.gridOptions;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const doInit = (adaptableInstance) => {
|
|
225
|
+
return adaptableInstance._initAdaptableAgGrid(config).then((api) => {
|
|
226
|
+
if (Array.isArray(config.adaptableOptions.plugins)) {
|
|
227
|
+
config.adaptableOptions.plugins.forEach((plugin) => {
|
|
228
|
+
plugin.afterInit(adaptableInstance);
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
return api;
|
|
232
|
+
});
|
|
233
|
+
};
|
|
234
|
+
if (promise && promise.then) {
|
|
235
|
+
return promise.then(() => {
|
|
236
|
+
const adaptableInstance = new AdaptableAgGrid();
|
|
237
|
+
return doInit(adaptableInstance);
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
const adaptableInstance = new AdaptableAgGrid();
|
|
242
|
+
return doInit(adaptableInstance);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
normaliseLayoutState(state, config) {
|
|
246
|
+
var _a, _b, _c;
|
|
247
|
+
if (this.shouldCreateDefaultLayout(state, this.adaptableOptions)) {
|
|
248
|
+
const defaultLayout = this.createDefaultLayout(state, config.gridOptions.columnDefs);
|
|
249
|
+
const layoutState = state.Layout || {};
|
|
250
|
+
const availableLayouts = layoutState.Layouts || [];
|
|
251
|
+
availableLayouts.push(defaultLayout);
|
|
252
|
+
layoutState.Layouts = availableLayouts;
|
|
253
|
+
layoutState.CurrentLayout = defaultLayout.Name;
|
|
254
|
+
state.Layout = layoutState;
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
const layoutState = state.Layout;
|
|
258
|
+
// ensure CurrentLayout is valid
|
|
259
|
+
if (!layoutState.CurrentLayout ||
|
|
260
|
+
!layoutState.Layouts.find((l) => l.Name === layoutState.CurrentLayout)) {
|
|
261
|
+
layoutState.CurrentLayout = (_b = (_a = layoutState.Layouts) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.Name;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// for the initial state, we need to dynamically add the ActionRowColumn (if necessary)
|
|
265
|
+
// for subsequent layout changes, the `Adaptable.setLayout()` method handles this
|
|
266
|
+
// this is a serious code smell, hopefully we will delete `setLayout()` at some point
|
|
267
|
+
const actionRowColDefs = this.api.actionRowApi.internalApi.getColDefsForActionRowColumns();
|
|
268
|
+
actionRowColDefs.forEach((actionRowColDef) => {
|
|
269
|
+
const currentLayout = state.Layout.Layouts.find((l) => l.Name === state.Layout.CurrentLayout);
|
|
270
|
+
if (currentLayout && !currentLayout.Columns.includes(actionRowColDef.colId)) {
|
|
271
|
+
currentLayout.Columns.push(actionRowColDef.colId);
|
|
272
|
+
currentLayout.PinnedColumnsMap = currentLayout.PinnedColumnsMap || {};
|
|
273
|
+
currentLayout.PinnedColumnsMap[actionRowColDef.colId] = actionRowColDef.pinned;
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
/**
|
|
277
|
+
* Viewport mode does not support a few
|
|
278
|
+
* features instead of complicating the
|
|
279
|
+
* logic where layout is applied, it is easier and
|
|
280
|
+
* less error prone to just remove it.
|
|
281
|
+
*/
|
|
282
|
+
if (config.gridOptions.rowModelType === 'viewport') {
|
|
283
|
+
(_c = state.Layout.Layouts) === null || _c === void 0 ? void 0 : _c.forEach((layout) => {
|
|
284
|
+
if (layout.RowGroupedColumns) {
|
|
285
|
+
delete layout.RowGroupedColumns;
|
|
286
|
+
}
|
|
287
|
+
if (layout.AggregationColumns) {
|
|
288
|
+
delete layout.AggregationColumns;
|
|
289
|
+
}
|
|
290
|
+
if (layout.PivotColumns) {
|
|
291
|
+
delete layout.PivotColumns;
|
|
292
|
+
delete layout.EnablePivot;
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
return state;
|
|
297
|
+
}
|
|
298
|
+
normaliseToolPanelState(state) {
|
|
299
|
+
var _a, _b, _c;
|
|
300
|
+
if ((_a = state === null || state === void 0 ? void 0 : state.ToolPanel) === null || _a === void 0 ? void 0 : _a.ToolPanels) {
|
|
301
|
+
return state;
|
|
302
|
+
}
|
|
303
|
+
// no predefined config provided, we will display all the panels collapsed (custom & module)
|
|
304
|
+
const defaultToolPanels = [];
|
|
305
|
+
(_c = (_b = this.adaptableOptions.toolPanelOptions) === null || _b === void 0 ? void 0 : _b.customToolPanels) === null || _c === void 0 ? void 0 : _c.forEach((customToolPanel) => defaultToolPanels.push({ Name: customToolPanel.name }));
|
|
306
|
+
ALL_TOOL_PANELS.forEach((moduleToolPanel) => defaultToolPanels.push({ Name: moduleToolPanel }));
|
|
307
|
+
const toolPanelState = state.ToolPanel || {};
|
|
308
|
+
toolPanelState.ToolPanels = defaultToolPanels;
|
|
309
|
+
state.ToolPanel = toolPanelState;
|
|
310
|
+
return state;
|
|
311
|
+
}
|
|
312
|
+
async _initAdaptableAgGrid(config) {
|
|
313
|
+
var _a, _b;
|
|
314
|
+
// Phase 1: Preprocess Adaptable Options
|
|
315
|
+
this.lifecycleState = 'preprocessOptions';
|
|
316
|
+
this._rawAdaptableOptions = config.adaptableOptions;
|
|
317
|
+
if (StringExtensions.IsNullOrEmptyOrWhiteSpace(this._rawAdaptableOptions.adaptableId)) {
|
|
318
|
+
AdaptableLogger.consoleErrorBase(`'AdaptableOptions.adaptableId' is a required property and cannot be empty or null`);
|
|
319
|
+
this._rawAdaptableOptions.adaptableId = `AdapTable_${Date.now()}`;
|
|
320
|
+
}
|
|
321
|
+
this.logger = (_a = this.logger) !== null && _a !== void 0 ? _a : new AdaptableLogger(this._rawAdaptableOptions.adaptableId);
|
|
322
|
+
const perfInitAdaptableAgGrid = this.logger.beginPerf(`Adaptable._initAdaptableAgGrid()`);
|
|
323
|
+
AdaptableAgGrid.collectInstance(this, this._rawAdaptableOptions.adaptableId);
|
|
324
|
+
this.variant = config.variant;
|
|
325
|
+
this.initWithLazyData =
|
|
326
|
+
config.gridOptions.rowData == undefined || config.gridOptions.rowData.length === 0;
|
|
327
|
+
this.hasAutogeneratedPrimaryKey = !!this._rawAdaptableOptions.autogeneratePrimaryKey;
|
|
328
|
+
this.adaptableOptions = applyDefaultAdaptableOptions(this._rawAdaptableOptions);
|
|
329
|
+
this.adaptableOptions = this.normalizeAdaptableOptions(this.adaptableOptions);
|
|
330
|
+
const { showLoadingScreen, loadingScreenDelay, loadingScreenText, loadingScreenTitle } = this.adaptableOptions.userInterfaceOptions;
|
|
331
|
+
if (showLoadingScreen) {
|
|
332
|
+
const portalElement = ensurePortalElement();
|
|
333
|
+
if (portalElement) {
|
|
334
|
+
this.unmountLoadingScreen = this.renderReactRoot(createElement(AdaptableLoadingScreen, {
|
|
335
|
+
showLoadingScreen,
|
|
336
|
+
loadingScreenDelay,
|
|
337
|
+
loadingScreenText,
|
|
338
|
+
loadingScreenTitle,
|
|
339
|
+
}), portalElement);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
this.forPlugins((plugin) => plugin.afterInitOptions(this, this.adaptableOptions));
|
|
343
|
+
this.api = new AdaptableApiImpl(this);
|
|
344
|
+
this.forPlugins((plugin) => plugin.afterInitApi(this, this.api));
|
|
345
|
+
this.lifecycleState = 'initAdaptableState';
|
|
346
|
+
// just in case Adaptable was destroyed while loading the store (which is an async operation)
|
|
347
|
+
if (this.isDestroyed) {
|
|
348
|
+
return Promise.reject('Adaptable was destroyed while loading the store.');
|
|
349
|
+
// FIXME AFL MIG: is this enough?! talk with the team
|
|
350
|
+
}
|
|
351
|
+
this.initServices();
|
|
352
|
+
this.forPlugins((plugin) => plugin.afterInitServices(this));
|
|
353
|
+
this.adaptableModules = this.initModules();
|
|
354
|
+
this.forPlugins((plugin) => plugin.afterInitModules(this, this.adaptableModules));
|
|
355
|
+
const perfLoadStore = this.logger.beginPerf(`loadStore()`);
|
|
356
|
+
this.adaptableStore = this.initAdaptableStore();
|
|
357
|
+
await this.adaptableStore.loadStore({
|
|
358
|
+
adaptable: this,
|
|
359
|
+
adaptableStateKey: this.adaptableOptions.adaptableStateKey,
|
|
360
|
+
/**
|
|
361
|
+
* This method is called after the store is loaded;
|
|
362
|
+
* it allows to modify the state before it is used by the application
|
|
363
|
+
* e.g. adding default Layout, migrating deprecated state, etc.
|
|
364
|
+
*/
|
|
365
|
+
postLoadHook: (state) => {
|
|
366
|
+
if (this.adaptableOptions.autoMigrateState) {
|
|
367
|
+
state = AdaptableUpgradeHelper.migrateAdaptableState(state, {
|
|
368
|
+
// version 16 actually includes all versions up until 16
|
|
369
|
+
fromVersion: 16,
|
|
370
|
+
logger: this.logger,
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
state = this.normaliseLayoutState(state, config);
|
|
374
|
+
state = this.normaliseToolPanelState(state);
|
|
375
|
+
return state;
|
|
376
|
+
},
|
|
377
|
+
});
|
|
378
|
+
perfLoadStore.end();
|
|
379
|
+
// just in case Adaptable was destroyed while loading the store (which is an async operation)
|
|
380
|
+
if (this.isDestroyed) {
|
|
381
|
+
return Promise.reject('Adaptable was destroyed while loading the store.');
|
|
382
|
+
// FIXME AFL MIG: is this enough?! talk with the team
|
|
383
|
+
}
|
|
384
|
+
this.forPlugins((plugin) => plugin.afterInitServices(this));
|
|
385
|
+
this.forPlugins((plugin) => plugin.afterInitModules(this, this.adaptableModules));
|
|
386
|
+
/**
|
|
387
|
+
* At this point it's mandatory to have the ALL the Adaptable blocks initialized:
|
|
388
|
+
* Store, APIs, Services, Modules
|
|
389
|
+
*/
|
|
390
|
+
this.lifecycleState = 'setupAgGrid';
|
|
391
|
+
const gridOptions = config.gridOptions;
|
|
392
|
+
// Needed here because special column defs are required for deriving the adaptable column state
|
|
393
|
+
const columnDefs = this.getAllColumnDefinitions(gridOptions.columnDefs || []);
|
|
394
|
+
gridOptions.columnDefs = columnDefs;
|
|
395
|
+
this.setInitialGridOptions(gridOptions, config.variant);
|
|
396
|
+
gridOptions.initialState = this.mapAdaptableStateToAgGridState(this.adaptableStore.TheStore.getState(), gridOptions.columnDefs);
|
|
397
|
+
this.lifecycleState = 'initAgGrid';
|
|
398
|
+
this.agGridAdapter.initialGridOptions = gridOptions;
|
|
399
|
+
const perfInitAgGrid = this.logger.beginPerf(`initAgGrid()`);
|
|
400
|
+
const agGridApi = await this.initializeAgGrid(gridOptions, config.modules, config.renderAgGridFrameworkComponent);
|
|
401
|
+
(_b = this.unmountLoadingScreen) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
402
|
+
perfInitAgGrid.end();
|
|
403
|
+
if (agGridApi === false) {
|
|
404
|
+
this.logger.consoleError(`Adaptable failed to initialize AG Grid!`);
|
|
405
|
+
return Promise.reject('Adaptable failed to initialize AG Grid!');
|
|
406
|
+
}
|
|
407
|
+
this.agGridAdapter.setAgGridApi(agGridApi);
|
|
408
|
+
this.logger.info(`Registered AG Grid modules: `, this.agGridAdapter.getRegisteredModuleNames().sort());
|
|
409
|
+
/**
|
|
410
|
+
* At this point AG Grid is initialized!
|
|
411
|
+
*/
|
|
412
|
+
this.updateColumnModelAndRefreshGrid();
|
|
413
|
+
this.api.themeApi.applyCurrentTheme();
|
|
414
|
+
this.validatePrimaryKey();
|
|
415
|
+
this.embedColumnMenu = this.agGridAdapter.isModulePresent(ModuleNames.MenuModule);
|
|
416
|
+
this.api.internalApi.setTreeMode(this.agGridAdapter.initialGridOptions.treeData);
|
|
417
|
+
// TODO AFL MIG: we could just patch the defautl Layout on init? instead
|
|
418
|
+
this.checkShouldClearExistingFiltersOrSearches();
|
|
419
|
+
this.applyColumnFiltering();
|
|
420
|
+
this.addGridEventListeners();
|
|
421
|
+
this.temporaryAdaptableStateUpdates();
|
|
422
|
+
// do this now so it sets module entitlements
|
|
423
|
+
this.EntitlementService.setModulesEntitlements();
|
|
424
|
+
// create the module menu (for use in the dashboard and the toolpanel)
|
|
425
|
+
// TODO see #create-create-module-menu - make sure it's the same here and there
|
|
426
|
+
this.ModuleService.createModuleMenus();
|
|
427
|
+
// update initial mode of DataChangeHistory
|
|
428
|
+
this.api.internalApi.initializeDataChangeHistory();
|
|
429
|
+
const adaptableContainerElem = this.getAdaptableContainerElement();
|
|
430
|
+
if (adaptableContainerElem != null) {
|
|
431
|
+
adaptableContainerElem.innerHTML = '';
|
|
432
|
+
this.unmountReactRoot = this.renderReactRoot(AdaptableApp({ Adaptable: this }), adaptableContainerElem);
|
|
433
|
+
}
|
|
434
|
+
this.lifecycleState = 'ready';
|
|
435
|
+
this.forPlugins((plugin) => plugin.onAdaptableReady(this, this.adaptableOptions));
|
|
436
|
+
this.api.eventApi.emit('AdaptableReady', {
|
|
437
|
+
adaptableApi: this.api,
|
|
438
|
+
agGridApi: this.agGridAdapter.getAgGridApi(),
|
|
439
|
+
});
|
|
440
|
+
this.api.userInterfaceApi.hideLoadingScreen();
|
|
441
|
+
perfInitAdaptableAgGrid.end();
|
|
442
|
+
return Promise.resolve(this.api);
|
|
443
|
+
}
|
|
444
|
+
applyColumnFiltering() {
|
|
445
|
+
if (this.api.columnFilterApi.isQuickFilterAvailable()) {
|
|
446
|
+
if (this.api.columnFilterApi.isQuickFilterVisible()) {
|
|
447
|
+
this.showQuickFilter();
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
this.hideQuickFilter();
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
this.applyGridFiltering();
|
|
454
|
+
this.agGridAdapter.updateColumnFilterActiveState();
|
|
455
|
+
}
|
|
456
|
+
applyGridFiltering() {
|
|
457
|
+
this.agGridAdapter.getAgGridApi().onFilterChanged();
|
|
458
|
+
this._emit('AdapTableFiltersApplied');
|
|
459
|
+
this.refreshSelectedCellsState();
|
|
460
|
+
this.refreshSelectedRowsState();
|
|
461
|
+
}
|
|
462
|
+
// refreshAgGridWithAdaptableState() {
|
|
463
|
+
// this.refreshColDefs();
|
|
464
|
+
// this.api.themeApi.applyCurrentTheme();
|
|
465
|
+
// this.api.internalApi.setTreeMode(this.agGridAdapter.initialGridOptions.treeData);
|
|
466
|
+
// this.checkShouldClearExistingFiltersOrSearches();
|
|
467
|
+
// this.applyColumnFiltering();
|
|
468
|
+
// }
|
|
469
|
+
refreshColDefs() {
|
|
470
|
+
const freshColDefs = this.getAllColumnDefinitions();
|
|
471
|
+
this.agGridAdapter.setGridOption('columnDefs', freshColDefs);
|
|
472
|
+
}
|
|
473
|
+
showQuickFilter() {
|
|
474
|
+
const height = this.api.optionsApi.getColumnFilterOptions().quickFilterOptions.quickFilterHeight;
|
|
475
|
+
this.agGridAdapter.getAgGridApi().setGridOption('floatingFiltersHeight', height);
|
|
476
|
+
}
|
|
477
|
+
hideQuickFilter() {
|
|
478
|
+
this.agGridAdapter.getAgGridApi().setGridOption('floatingFiltersHeight', 0);
|
|
479
|
+
}
|
|
480
|
+
normalizeAdaptableOptions(adaptableOptions) {
|
|
481
|
+
if (this.hasAutogeneratedPrimaryKey) {
|
|
482
|
+
this.logger
|
|
483
|
+
.warn(`Autogenerated primary key (adaptableOptions.autogeneratedPrimaryKey = TRUE) should be used only as a last resort,
|
|
484
|
+
when no unique column is available, as it limits some Adaptable functionalities!
|
|
485
|
+
|
|
486
|
+
For more details see: ${PrimaryKeyDocsLink}`);
|
|
487
|
+
this.adaptableOptions.primaryKey = AUTOGENERATED_PK_COLUMN;
|
|
488
|
+
return this.adaptableOptions;
|
|
489
|
+
}
|
|
490
|
+
if (StringExtensions.IsNullOrEmpty(adaptableOptions.primaryKey)) {
|
|
491
|
+
this.logger.consoleError(`AdaptableOptions.primaryKey is required and cannot be empty or null!
|
|
492
|
+
As a fallback, you can set adaptableOptions.autogeneratedPrimaryKey = TRUE
|
|
493
|
+
|
|
494
|
+
For more details see: ${PrimaryKeyDocsLink}`);
|
|
495
|
+
}
|
|
496
|
+
return adaptableOptions;
|
|
497
|
+
}
|
|
498
|
+
setInitialGridOptions(gridOptions, variant) {
|
|
499
|
+
/**
|
|
500
|
+
* set Adaptable instance on the AG Grid context
|
|
501
|
+
*/
|
|
502
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'context', (original_context) => {
|
|
503
|
+
const userContext = original_context || {};
|
|
504
|
+
return Object.assign(Object.assign({}, userContext), { __adaptable: this });
|
|
505
|
+
});
|
|
506
|
+
/**
|
|
507
|
+
* `gridId`
|
|
508
|
+
*/
|
|
509
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'gridId', (original_gridId) => {
|
|
510
|
+
return original_gridId || this.adaptableOptions.adaptableId;
|
|
511
|
+
});
|
|
512
|
+
/**
|
|
513
|
+
* `getRowId`
|
|
514
|
+
*/
|
|
515
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'getRowId', (original_getRowId) => {
|
|
516
|
+
if (original_getRowId) {
|
|
517
|
+
return original_getRowId;
|
|
518
|
+
}
|
|
519
|
+
const primaryKey = this.adaptableOptions.primaryKey;
|
|
520
|
+
if (StringExtensions.IsNullOrEmpty(primaryKey)) {
|
|
521
|
+
// if no valid PK then do nothing
|
|
522
|
+
return original_getRowId;
|
|
523
|
+
}
|
|
524
|
+
if (this.hasAutogeneratedPrimaryKey) {
|
|
525
|
+
return (params) => {
|
|
526
|
+
// if the PK value is autogenerated, we need to make sure that the rowData has a valid PK value
|
|
527
|
+
// this should be taken care of in the Adaptable.[loadDataSource/setDataSource/updateRows]() methods, but the users will always make silly decisions
|
|
528
|
+
// so just to be safe we'll check here and add a PK value is missing
|
|
529
|
+
// thus adding a side-effect in a getter, but what can we do against it?! :)
|
|
530
|
+
if (Helper.objectNotExists(params.data[primaryKey])) {
|
|
531
|
+
params.data[primaryKey] = createUuid();
|
|
532
|
+
}
|
|
533
|
+
return params.data[primaryKey];
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
return (params) => {
|
|
537
|
+
var _a;
|
|
538
|
+
if (params.data[primaryKey]) {
|
|
539
|
+
return params.data[primaryKey];
|
|
540
|
+
}
|
|
541
|
+
// row does not have primary key => might be a group row
|
|
542
|
+
const parentKeys = (_a = params.parentKeys) !== null && _a !== void 0 ? _a : [];
|
|
543
|
+
const values = Object.values(params.data);
|
|
544
|
+
if (values.length) {
|
|
545
|
+
const id = [...parentKeys, values[0]].join('/');
|
|
546
|
+
return id;
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
});
|
|
550
|
+
/**
|
|
551
|
+
* `suppressAggFuncInHeader`
|
|
552
|
+
*/
|
|
553
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'suppressAggFuncInHeader', (original_suppressAggFuncInHeader) => {
|
|
554
|
+
const currentLayout = this.api.layoutApi.getCurrentLayout();
|
|
555
|
+
if (!currentLayout) {
|
|
556
|
+
return original_suppressAggFuncInHeader;
|
|
557
|
+
}
|
|
558
|
+
return currentLayout.SuppressAggFuncInHeader;
|
|
559
|
+
});
|
|
560
|
+
/**
|
|
561
|
+
* `aggFuncs`
|
|
562
|
+
*/
|
|
563
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'aggFuncs', (original_aggFuncs) => {
|
|
564
|
+
const aggregationFunctions = original_aggFuncs || {};
|
|
565
|
+
aggregationFunctions[WEIGHTED_AVERAGE_AGG_FN_NAME] = (params) => {
|
|
566
|
+
const columnId = params.column.getColId();
|
|
567
|
+
const adaptableAggFunc = this.getActiveAdaptableAggFuncForCol(columnId);
|
|
568
|
+
if (!adaptableAggFunc) {
|
|
569
|
+
return undefined;
|
|
570
|
+
}
|
|
571
|
+
if (adaptableAggFunc.type === 'weightedAverage') {
|
|
572
|
+
return weightedAverage(params, params.colDef.colId, adaptableAggFunc.weightedColumnId);
|
|
573
|
+
}
|
|
574
|
+
return undefined;
|
|
575
|
+
};
|
|
576
|
+
return aggregationFunctions;
|
|
577
|
+
});
|
|
578
|
+
/**
|
|
579
|
+
* `allowContextMenuWithControlKey`
|
|
580
|
+
*/
|
|
581
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'allowContextMenuWithControlKey', (original_allowContextMenuWithControlKey) => {
|
|
582
|
+
return original_allowContextMenuWithControlKey === undefined
|
|
583
|
+
? true
|
|
584
|
+
: original_allowContextMenuWithControlKey;
|
|
585
|
+
});
|
|
586
|
+
/**
|
|
587
|
+
* `isExternalFilterPresent`
|
|
588
|
+
*/
|
|
589
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'isExternalFilterPresent', (original_isExternalFilterPresent) => {
|
|
590
|
+
return (params) => {
|
|
591
|
+
if (this.isDestroyed) {
|
|
592
|
+
return true;
|
|
593
|
+
}
|
|
594
|
+
const columnFilters = this.api.columnFilterApi.getActiveColumnFilters();
|
|
595
|
+
const isColumnFiltersActive = ArrayExtensions.IsNotNullOrEmpty(columnFilters);
|
|
596
|
+
const isGridFilterActive = StringExtensions.IsNotNullOrEmpty(this.api.gridFilterApi.getCurrentGridFilterExpression());
|
|
597
|
+
return (isColumnFiltersActive ||
|
|
598
|
+
isGridFilterActive ||
|
|
599
|
+
// it means that userPropertyValue will be called so we re-init that collection
|
|
600
|
+
(original_isExternalFilterPresent ? original_isExternalFilterPresent(params) : false));
|
|
601
|
+
};
|
|
602
|
+
});
|
|
603
|
+
/**
|
|
604
|
+
* `doesExternalFilterPass`
|
|
605
|
+
*/
|
|
606
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'doesExternalFilterPass', (original_doesExternalFilterPass) => {
|
|
607
|
+
return (node) => {
|
|
608
|
+
if (this.isDestroyed) {
|
|
609
|
+
return true;
|
|
610
|
+
}
|
|
611
|
+
// first we assess a Grid Filter (if its running locally)
|
|
612
|
+
if (!this.isGroupRowNode(node)) {
|
|
613
|
+
const currentGridFilter = this.api.gridFilterApi.getCurrentGridFilterExpression();
|
|
614
|
+
if (currentGridFilter) {
|
|
615
|
+
const evaluateGridFilterOnClient = this.api.expressionApi.internalApi.evaluateExpressionInAdaptableQL('GridFilter', undefined, currentGridFilter);
|
|
616
|
+
if (evaluateGridFilterOnClient) {
|
|
617
|
+
const isCurrentGridFilterValid = this.api.expressionApi.isValidBooleanExpression(currentGridFilter, GridFilterModuleId, `Invalid Grid Filter '${currentGridFilter}'`);
|
|
618
|
+
if (!isCurrentGridFilterValid ||
|
|
619
|
+
!this.api.internalApi
|
|
620
|
+
.getQueryLanguageService()
|
|
621
|
+
.evaluateBooleanExpression(currentGridFilter, GridFilterModuleId, node)) {
|
|
622
|
+
return false;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
const columnFilters = this.api.columnFilterApi.getActiveColumnFilters();
|
|
628
|
+
try {
|
|
629
|
+
if (columnFilters.length > 0) {
|
|
630
|
+
for (const columnFilter of columnFilters) {
|
|
631
|
+
const evaluateFilterOnClient = this.api.expressionApi.internalApi.evaluatePredicatesInAdaptableQL('ColumnFilter', columnFilter, [columnFilter.Predicate]);
|
|
632
|
+
if (evaluateFilterOnClient) {
|
|
633
|
+
// we then assess filters (if running locally)
|
|
634
|
+
if (!this.api.columnFilterApi.internalApi.evaluateColumnFilter(columnFilter, node)) {
|
|
635
|
+
return false;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
catch (ex) {
|
|
642
|
+
this.logger.error(ex);
|
|
643
|
+
return false;
|
|
644
|
+
}
|
|
645
|
+
return original_doesExternalFilterPass ? original_doesExternalFilterPass(node) : true;
|
|
646
|
+
};
|
|
647
|
+
});
|
|
648
|
+
/**
|
|
649
|
+
* `getMainMenuItems`
|
|
650
|
+
*/
|
|
651
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'getMainMenuItems', (original_getMainMenuItems) => {
|
|
652
|
+
return (params) => {
|
|
653
|
+
// couldnt find a way to listen for menu close. There is a Menu Item Select, but you can also close menu from filter and clicking outside menu....
|
|
654
|
+
return this.agGridMenuAdapter.buildColumnMenu(params, original_getMainMenuItems);
|
|
655
|
+
};
|
|
656
|
+
});
|
|
657
|
+
/**
|
|
658
|
+
* `getContextMenuItems`
|
|
659
|
+
*/
|
|
660
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'getContextMenuItems', (original_getContextMenuItems) => {
|
|
661
|
+
return (params) => {
|
|
662
|
+
return this.agGridMenuAdapter.buildContextMenu(params, original_getContextMenuItems);
|
|
663
|
+
};
|
|
664
|
+
});
|
|
665
|
+
/**
|
|
666
|
+
* `initialGroupOrderComparator
|
|
667
|
+
*/
|
|
668
|
+
// Build the default group sort comparator - will get custom sort values (but not functions) in real time
|
|
669
|
+
// TODO: if a custom 'aggFunc' property is defined (see setupColumnAggFunc()), it won't be evaluated
|
|
670
|
+
if (this.adaptableOptions.groupingOptions.autoOrderGroupedColumns) {
|
|
671
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'initialGroupOrderComparator', (original_initialGroupOrderComparator) => {
|
|
672
|
+
if (original_initialGroupOrderComparator) {
|
|
673
|
+
return original_initialGroupOrderComparator;
|
|
674
|
+
}
|
|
675
|
+
return (params) => {
|
|
676
|
+
const { nodeA, nodeB } = params;
|
|
677
|
+
const firstGroupedColumnId = this.agGridAdapter.getFirstGroupedColumn();
|
|
678
|
+
if (firstGroupedColumnId) {
|
|
679
|
+
const definedColumnComparator = this.api.columnApi.internalApi.getActiveColumnComparator(firstGroupedColumnId, this.api.customSortApi.getCustomSortForColumn(firstGroupedColumnId), this.api.customSortApi.internalApi.getCustomSortComparer(firstGroupedColumnId));
|
|
680
|
+
if (definedColumnComparator) {
|
|
681
|
+
return definedColumnComparator(nodeA.key, nodeB.key);
|
|
682
|
+
}
|
|
683
|
+
const sortOder = this.api.layoutApi.getCurrentLayoutColumnSort(firstGroupedColumnId);
|
|
684
|
+
if (sortOder === 'Desc') {
|
|
685
|
+
return nodeA.key > nodeB.key ? -1 : 1;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
// if no comparator available, just sort alphanumerically
|
|
689
|
+
if (nodeA.key == nodeB.key) {
|
|
690
|
+
return 0;
|
|
691
|
+
}
|
|
692
|
+
return nodeA.key < nodeB.key ? -1 : 1;
|
|
693
|
+
};
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* `components`
|
|
698
|
+
*/
|
|
699
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'components', (original_components) => {
|
|
700
|
+
const AdaptableToolPanel = getAdaptableToolPanelAgGridComponent(this);
|
|
701
|
+
const components = original_components || {};
|
|
702
|
+
const adaptableComponents = Object.assign(Object.assign({}, components), { AdaptableToolPanel });
|
|
703
|
+
return adaptableComponents;
|
|
704
|
+
});
|
|
705
|
+
if (variant === 'react') {
|
|
706
|
+
// TODO very soon we have to transition to reactiveCustomComponents in React
|
|
707
|
+
// but for now, if we simply set it to true, it will break our editors, etc
|
|
708
|
+
// this.agGridOptionsService.setGridOptionsProperty(
|
|
709
|
+
// gridOptions,
|
|
710
|
+
// 'reactiveCustomComponents',
|
|
711
|
+
// () => true
|
|
712
|
+
// );
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* `sidebar`
|
|
716
|
+
*/
|
|
717
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'sideBar', (original_sideBar) => {
|
|
718
|
+
var _a, _b;
|
|
719
|
+
if (!original_sideBar) {
|
|
720
|
+
// lucky us, no sideBar is defined, so we don't have to do anything
|
|
721
|
+
return original_sideBar;
|
|
722
|
+
}
|
|
723
|
+
const isAdaptableToolPanelHidden = this.EntitlementService.isModuleHiddenEntitlement('ToolPanel');
|
|
724
|
+
const adaptableToolPanelDef = {
|
|
725
|
+
id: GeneralConstants.ADAPTABLE_TOOLPANEL_ID,
|
|
726
|
+
toolPanel: GeneralConstants.ADAPTABLE_TOOLPANEL_COMPONENT,
|
|
727
|
+
labelDefault: GeneralConstants.ADAPTABLE,
|
|
728
|
+
labelKey: 'adaptable',
|
|
729
|
+
iconKey: 'menu',
|
|
730
|
+
width: UIHelper.getAdaptableToolPanelWidth(),
|
|
731
|
+
minWidth: UIHelper.getAdaptableToolPanelWidth(),
|
|
732
|
+
// maxWidth = undefined,
|
|
733
|
+
};
|
|
734
|
+
const mapToolPanelDefs = (toolPanelDefs = []) => {
|
|
735
|
+
// if it's an alias for the adaptable tool panel, map it to a ToolPanelDef, otherwise return it as it is
|
|
736
|
+
return toolPanelDefs.map((toolPanelDef) => toolPanelDef === GeneralConstants.ADAPTABLE_TOOLPANEL_ID
|
|
737
|
+
? adaptableToolPanelDef
|
|
738
|
+
: toolPanelDef);
|
|
739
|
+
};
|
|
740
|
+
const isSideBarDefObject = (sidebarDef) => {
|
|
741
|
+
return Array.isArray(sidebarDef === null || sidebarDef === void 0 ? void 0 : sidebarDef.toolPanels);
|
|
742
|
+
};
|
|
743
|
+
let result;
|
|
744
|
+
if (original_sideBar === true) {
|
|
745
|
+
// create all tool panels with default settings
|
|
746
|
+
const toolPanels = [];
|
|
747
|
+
toolPanels.push(GeneralConstants.AGGRID_TOOLPANEL_FILTERS);
|
|
748
|
+
toolPanels.push(GeneralConstants.AGGRID_TOOLPANEL_COLUMNS);
|
|
749
|
+
if (!isAdaptableToolPanelHidden) {
|
|
750
|
+
toolPanels.push(adaptableToolPanelDef);
|
|
751
|
+
}
|
|
752
|
+
result = {
|
|
753
|
+
toolPanels: toolPanels,
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
// if there is only one tool panel, and it's the adaptable one => we have to handle it
|
|
757
|
+
else if (typeof original_sideBar === 'string') {
|
|
758
|
+
if (gridOptions.sideBar === GeneralConstants.ADAPTABLE_TOOLPANEL_ID) {
|
|
759
|
+
if (!isAdaptableToolPanelHidden)
|
|
760
|
+
result = {
|
|
761
|
+
toolPanels: [adaptableToolPanelDef],
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
else {
|
|
765
|
+
result = original_sideBar;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
// if it's an array, process the tool panel definitions
|
|
769
|
+
else if (Array.isArray(original_sideBar)) {
|
|
770
|
+
if (!original_sideBar.includes(GeneralConstants.ADAPTABLE_TOOLPANEL_ID) ||
|
|
771
|
+
isAdaptableToolPanelHidden) {
|
|
772
|
+
result = original_sideBar;
|
|
773
|
+
}
|
|
774
|
+
// if it's an array, process the tool panel definitions
|
|
775
|
+
const sidebarDef = {};
|
|
776
|
+
sidebarDef.toolPanels = mapToolPanelDefs(original_sideBar);
|
|
777
|
+
result = sidebarDef;
|
|
778
|
+
}
|
|
779
|
+
// if it's fully-fledged SideBarDef, process its tool panel definitions
|
|
780
|
+
else if (isSideBarDefObject(original_sideBar)) {
|
|
781
|
+
if ((_a = original_sideBar.toolPanels) === null || _a === void 0 ? void 0 : _a.some((toolpanelDef) => typeof toolpanelDef !== 'string' &&
|
|
782
|
+
toolpanelDef.id === GeneralConstants.ADAPTABLE_TOOLPANEL_ID &&
|
|
783
|
+
!isAdaptableToolPanelHidden)) {
|
|
784
|
+
// if there is an Adaptable SideBarDef, don't touch it as it may contain user-defined properties
|
|
785
|
+
result = original_sideBar;
|
|
786
|
+
}
|
|
787
|
+
else {
|
|
788
|
+
result = Object.assign(Object.assign({}, original_sideBar), { toolPanels: mapToolPanelDefs(original_sideBar.toolPanels) });
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
this.hasAdaptableToolPanel =
|
|
792
|
+
isSideBarDefObject(result) &&
|
|
793
|
+
((_b = result.toolPanels) === null || _b === void 0 ? void 0 : _b.some((toolPanelDef) => typeof toolPanelDef !== 'string' &&
|
|
794
|
+
toolPanelDef.id === GeneralConstants.ADAPTABLE_TOOLPANEL_ID));
|
|
795
|
+
return result;
|
|
796
|
+
});
|
|
797
|
+
/**
|
|
798
|
+
* `statusBar`
|
|
799
|
+
*/
|
|
800
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'statusBar', (original_statusBar) => {
|
|
801
|
+
var _a, _b;
|
|
802
|
+
const statusPanels = (_b = ((_a = original_statusBar === null || original_statusBar === void 0 ? void 0 : original_statusBar.statusPanels) !== null && _a !== void 0 ? _a : [])) === null || _b === void 0 ? void 0 : _b.map((statusPanel) => {
|
|
803
|
+
if (statusPanel.statusPanel === ADAPTABLE_STATUS_PANEL) {
|
|
804
|
+
this.adaptableStatusPanelKeys.push(statusPanel.key);
|
|
805
|
+
const context = {
|
|
806
|
+
Key: statusPanel.key,
|
|
807
|
+
};
|
|
808
|
+
return Object.assign(Object.assign({}, statusPanel), { statusPanel: createAgStatusPanelComponent(AdaptableStatusBar, this, context) });
|
|
809
|
+
}
|
|
810
|
+
return statusPanel;
|
|
811
|
+
});
|
|
812
|
+
return Object.assign(Object.assign({}, original_statusBar), { statusPanels });
|
|
813
|
+
});
|
|
814
|
+
/**
|
|
815
|
+
* `getRowStyle`
|
|
816
|
+
*/
|
|
817
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'getRowStyle', (original_getRowStyle) => {
|
|
818
|
+
return (params) => {
|
|
819
|
+
const result = Object.assign(Object.assign(Object.assign({}, original_getRowStyle === null || original_getRowStyle === void 0 ? void 0 : original_getRowStyle(params)), this.api.gridApi.internalApi.getRowHighlightStyle(params)), this.api.gridApi.internalApi.getAlertRowStyle(params));
|
|
820
|
+
return result;
|
|
821
|
+
};
|
|
822
|
+
});
|
|
823
|
+
/**
|
|
824
|
+
* `getRowClass`
|
|
825
|
+
*/
|
|
826
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'getRowClass', (original_getRowClass) => {
|
|
827
|
+
return (params) => {
|
|
828
|
+
const alertHighlightClassName = this.api.gridApi.internalApi.getAlertRowClass(params);
|
|
829
|
+
const highlightClassName = this.api.gridApi.internalApi.getRowHighlightClass(params);
|
|
830
|
+
const returnValue = [
|
|
831
|
+
typeof original_getRowClass === 'function'
|
|
832
|
+
? original_getRowClass(params)
|
|
833
|
+
: original_getRowClass,
|
|
834
|
+
highlightClassName,
|
|
835
|
+
alertHighlightClassName,
|
|
836
|
+
]
|
|
837
|
+
// we flatten it because 'original_getRowClass' might return a string[]
|
|
838
|
+
.flat()
|
|
839
|
+
.filter((x) => !!x);
|
|
840
|
+
return (returnValue === null || returnValue === void 0 ? void 0 : returnValue.length) ? returnValue : undefined;
|
|
841
|
+
};
|
|
842
|
+
});
|
|
843
|
+
/**
|
|
844
|
+
* `columnTypes`
|
|
845
|
+
*/
|
|
846
|
+
// this will have to go/be heavily extended with https://github.com/AdaptableTools/adaptable/issues/2230
|
|
847
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'columnTypes', (original_columnTypes) => {
|
|
848
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
849
|
+
const providedColumnTypes = original_columnTypes || {};
|
|
850
|
+
const gridOptionsColumnTypes = gridOptions.columnTypes || {};
|
|
851
|
+
const patchedColumnTypes = Object.assign(providedColumnTypes, {
|
|
852
|
+
[AB_SPECIAL_COLUMN]: {},
|
|
853
|
+
[AB_FDC3_COLUMN]: {},
|
|
854
|
+
abColDefNumber: (_a = gridOptionsColumnTypes.abColDefNumber) !== null && _a !== void 0 ? _a : {},
|
|
855
|
+
abColDefString: (_b = gridOptionsColumnTypes.abColDefString) !== null && _b !== void 0 ? _b : {},
|
|
856
|
+
abColDefBoolean: (_c = gridOptionsColumnTypes.abColDefBoolean) !== null && _c !== void 0 ? _c : {},
|
|
857
|
+
abColDefDate: (_d = gridOptionsColumnTypes.abColDefDate) !== null && _d !== void 0 ? _d : {},
|
|
858
|
+
abColDefObject: (_e = gridOptionsColumnTypes.abColDefObject) !== null && _e !== void 0 ? _e : {},
|
|
859
|
+
abColDefCustom: (_f = gridOptionsColumnTypes.abColDefCustom) !== null && _f !== void 0 ? _f : {},
|
|
860
|
+
abColDefStringArray: (_g = gridOptionsColumnTypes.abColDefStringArray) !== null && _g !== void 0 ? _g : {},
|
|
861
|
+
abColDefNumberArray: (_h = gridOptionsColumnTypes.abColDefNumberArray) !== null && _h !== void 0 ? _h : {},
|
|
862
|
+
abColDefTupleNumberArray: (_j = gridOptionsColumnTypes.abColDefTupleNumberArray) !== null && _j !== void 0 ? _j : {},
|
|
863
|
+
abColDefObjectNumberArray: (_k = gridOptionsColumnTypes.abColDefObjectNumberArray) !== null && _k !== void 0 ? _k : {},
|
|
864
|
+
});
|
|
865
|
+
if (patchedColumnTypes.abColDefNumber.cellEditor == undefined) {
|
|
866
|
+
patchedColumnTypes.abColDefNumber.cellEditor =
|
|
867
|
+
this.variant === 'react' ? ReactAdaptableNumberEditor : AdaptableNumberEditor;
|
|
868
|
+
}
|
|
869
|
+
if (patchedColumnTypes.abColDefDate.cellEditor == undefined) {
|
|
870
|
+
patchedColumnTypes.abColDefDate.cellEditor =
|
|
871
|
+
this.variant === 'react' ? ReactAdaptableDateEditor : AdaptableDateEditor;
|
|
872
|
+
}
|
|
873
|
+
return patchedColumnTypes;
|
|
874
|
+
});
|
|
875
|
+
/**
|
|
876
|
+
* `dataTypeDefinitions`
|
|
877
|
+
*/
|
|
878
|
+
this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'dataTypeDefinitions', () => {
|
|
879
|
+
// temporary workaround until https://github.com/AdaptableTools/adaptable/issues/2230
|
|
880
|
+
const revertedDateTypeDefinitions = {
|
|
881
|
+
date: {
|
|
882
|
+
baseDataType: 'date',
|
|
883
|
+
extendsDataType: 'date',
|
|
884
|
+
valueParser: null,
|
|
885
|
+
valueFormatter: null,
|
|
886
|
+
suppressDefaultProperties: true,
|
|
887
|
+
},
|
|
888
|
+
dateString: {
|
|
889
|
+
baseDataType: 'dateString',
|
|
890
|
+
extendsDataType: 'dateString',
|
|
891
|
+
valueParser: null,
|
|
892
|
+
valueFormatter: null,
|
|
893
|
+
suppressDefaultProperties: true,
|
|
894
|
+
},
|
|
895
|
+
};
|
|
896
|
+
return revertedDateTypeDefinitions;
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Either initializes the AG Grid instance or delegates it to the framework wrappers (React/Anglar)
|
|
901
|
+
*/
|
|
902
|
+
async initializeAgGrid(gridOptions, modules, renderAgGridFrameworkComponent) {
|
|
903
|
+
if (renderAgGridFrameworkComponent) {
|
|
904
|
+
const result = await renderAgGridFrameworkComponent(gridOptions);
|
|
905
|
+
if (result === false) {
|
|
906
|
+
return false;
|
|
907
|
+
}
|
|
908
|
+
const agGridApi = result;
|
|
909
|
+
// framework wrapper may pass the rowData as a prop
|
|
910
|
+
const rowData = agGridApi.getGridOption('rowData');
|
|
911
|
+
this.initWithLazyData = rowData == undefined || rowData.length === 0;
|
|
912
|
+
this.logger.info('initWithLazyData = TRUE');
|
|
913
|
+
if (!this.getAgGridContainerElement()) {
|
|
914
|
+
// initialize the agGridContainerElement from the AgGrid instance
|
|
915
|
+
// @ts-ignore
|
|
916
|
+
const gridRoot = agGridApi.ctrlsService.gridBodyCtrl.eGridBody;
|
|
917
|
+
const gridContainer = gridRoot === null || gridRoot === void 0 ? void 0 : gridRoot.closest('[class*="ag-theme"]');
|
|
918
|
+
if (!gridContainer) {
|
|
919
|
+
this.logger.consoleError('No AG Grid container element found in the DOM. Please provide a valid container element in `ContainerOptions.agGridContainer`');
|
|
920
|
+
}
|
|
921
|
+
this.DANGER_USE_GETTER_agGridContainerElement = gridContainer;
|
|
922
|
+
}
|
|
923
|
+
return agGridApi;
|
|
924
|
+
}
|
|
925
|
+
const agGridContainer = this.getAgGridContainerElement();
|
|
926
|
+
if (!agGridContainer) {
|
|
927
|
+
this.logger.consoleError('No AG Grid container element found in the DOM. Please provide a valid container element in `ContainerOptions.agGridContainer`');
|
|
928
|
+
return Promise.resolve(false);
|
|
929
|
+
}
|
|
930
|
+
let gridParams;
|
|
931
|
+
if (modules === null || modules === void 0 ? void 0 : modules.length) {
|
|
932
|
+
gridParams = { modules };
|
|
933
|
+
}
|
|
934
|
+
const agGridApi = createGrid(agGridContainer, gridOptions, gridParams);
|
|
935
|
+
return agGridApi;
|
|
936
|
+
}
|
|
937
|
+
getAllColumnDefinitions(agGridColDefs) {
|
|
938
|
+
const allColDefs = this.enhanceColDefsWithSpecialColumns(agGridColDefs !== null && agGridColDefs !== void 0 ? agGridColDefs : this.agGridAdapter.getAgGridApi().getColumnDefs());
|
|
939
|
+
this.agGridAdapter.assignColumnIdsToColDefs(allColDefs);
|
|
940
|
+
return allColDefs;
|
|
941
|
+
}
|
|
942
|
+
getSpecialColDefs() {
|
|
943
|
+
return [
|
|
944
|
+
...this.api.calculatedColumnApi.internalApi.getColDefsForCalculatedColumns(),
|
|
945
|
+
...this.api.actionColumnApi.getColDefsForActionColumns(),
|
|
946
|
+
...this.api.freeTextColumnApi.internalApi.getColDefsForFreeTextColumns(),
|
|
947
|
+
...this.api.actionRowApi.internalApi.getColDefsForActionRowColumns(),
|
|
948
|
+
...this.api.fdc3Api.internalApi.getFdc3ActionColDefs(),
|
|
949
|
+
];
|
|
950
|
+
}
|
|
951
|
+
enhanceColDefsWithSpecialColumns(agGridColDefs) {
|
|
952
|
+
const specialColDefs = this.getSpecialColDefs();
|
|
953
|
+
const isSpecialColDef = (colDef) => {
|
|
954
|
+
const { type } = colDef;
|
|
955
|
+
if (type === AB_SPECIAL_COLUMN || (Array.isArray(type) && type.includes(AB_SPECIAL_COLUMN))) {
|
|
956
|
+
return true;
|
|
957
|
+
}
|
|
958
|
+
return false;
|
|
959
|
+
};
|
|
960
|
+
const isColGroupDef = (columnDefinition) => {
|
|
961
|
+
// @ts-ignore
|
|
962
|
+
return columnDefinition['children'] != null;
|
|
963
|
+
};
|
|
964
|
+
const processedSpecialColDefIds = [];
|
|
965
|
+
const mapColDefs = (colDefs) => {
|
|
966
|
+
return colDefs.map((colDef) => {
|
|
967
|
+
if (isColGroupDef(colDef)) {
|
|
968
|
+
// if it's a group column, recursively map its children
|
|
969
|
+
colDef.children = mapColDefs(colDef.children);
|
|
970
|
+
return colDef;
|
|
971
|
+
}
|
|
972
|
+
else {
|
|
973
|
+
if (!isSpecialColDef(colDef)) {
|
|
974
|
+
// if it's not a special column, return it as is
|
|
975
|
+
return colDef;
|
|
976
|
+
}
|
|
977
|
+
const newlyCreatedSpecialColDef = specialColDefs.find((specialColDef) => specialColDef.colId === colDef.colId);
|
|
978
|
+
if (newlyCreatedSpecialColDef) {
|
|
979
|
+
// if it's a special column and we have a special col def for it, return the special col def
|
|
980
|
+
processedSpecialColDefIds.push(colDef.colId);
|
|
981
|
+
// merge the user defined colDef with the special col def
|
|
982
|
+
// this way the user may provide some custom settings for the special col def (tooltip, etc)
|
|
983
|
+
const mergedColDef = Object.assign(Object.assign({}, colDef), newlyCreatedSpecialColDef);
|
|
984
|
+
return mergedColDef;
|
|
985
|
+
}
|
|
986
|
+
else {
|
|
987
|
+
// otherwise, return the original col def
|
|
988
|
+
return colDef;
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
});
|
|
992
|
+
};
|
|
993
|
+
let resultColDefs = mapColDefs(agGridColDefs);
|
|
994
|
+
// check if there are any special colDefs that were not processed
|
|
995
|
+
// in that case, add them to the end of the colDefs
|
|
996
|
+
specialColDefs.forEach((specialColDef) => {
|
|
997
|
+
if (!processedSpecialColDefIds.includes(specialColDef.colId)) {
|
|
998
|
+
resultColDefs.push(specialColDef);
|
|
999
|
+
}
|
|
1000
|
+
});
|
|
1001
|
+
// remove special column that are no longer defined
|
|
1002
|
+
resultColDefs = resultColDefs.filter((colDef) => {
|
|
1003
|
+
if (isSpecialColDef(colDef)) {
|
|
1004
|
+
// must be in specialColDefs
|
|
1005
|
+
return specialColDefs.some((specialColDef) => specialColDef.colId === colDef.colId);
|
|
1006
|
+
}
|
|
1007
|
+
return true;
|
|
1008
|
+
});
|
|
1009
|
+
return resultColDefs;
|
|
1010
|
+
}
|
|
1011
|
+
useRowNodeLookUp() {
|
|
1012
|
+
return this.agGridAdapter.initialGridOptions.getRowId != undefined;
|
|
1013
|
+
}
|
|
1014
|
+
getAgGridContainerElement() {
|
|
1015
|
+
if (!this.DANGER_USE_GETTER_agGridContainerElement) {
|
|
1016
|
+
this.DANGER_USE_GETTER_agGridContainerElement =
|
|
1017
|
+
typeof this.adaptableOptions.containerOptions.agGridContainer === 'string'
|
|
1018
|
+
? document.getElementById(this.adaptableOptions.containerOptions.agGridContainer)
|
|
1019
|
+
: this.adaptableOptions.containerOptions.agGridContainer;
|
|
1020
|
+
}
|
|
1021
|
+
return this.DANGER_USE_GETTER_agGridContainerElement;
|
|
1022
|
+
}
|
|
1023
|
+
getAdaptableContainerElement() {
|
|
1024
|
+
if (!this.DANGER_USE_GETTER_adaptableContainerElement) {
|
|
1025
|
+
this.DANGER_USE_GETTER_adaptableContainerElement =
|
|
1026
|
+
typeof this.adaptableOptions.containerOptions.adaptableContainer === 'string'
|
|
1027
|
+
? document.getElementById(this.adaptableOptions.containerOptions.adaptableContainer)
|
|
1028
|
+
: this.adaptableOptions.containerOptions.adaptableContainer;
|
|
1029
|
+
}
|
|
1030
|
+
return this.DANGER_USE_GETTER_adaptableContainerElement;
|
|
1031
|
+
}
|
|
1032
|
+
// This method returns selected cells ONLY (if selection mode is cells or multiple cells).
|
|
1033
|
+
// If the selection mode is row it will returns nothing - use the setSelectedRows() method
|
|
1034
|
+
refreshSelectedCellsState() {
|
|
1035
|
+
var _a;
|
|
1036
|
+
const isRangeSelectionModuleRegistered = this.agGridAdapter.isModulePresent(ModuleNames.RangeSelectionModule);
|
|
1037
|
+
if (!isRangeSelectionModuleRegistered ||
|
|
1038
|
+
!((_a = this.agGridAdapter.getLiveGridOptions()) === null || _a === void 0 ? void 0 : _a.enableRangeSelection) === true) {
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
const selectedCellInfo = this.agGridAdapter.deriveSelectedCellInfoFromAgGrid();
|
|
1042
|
+
this.api.gridApi.internalApi.setSelectedCells(selectedCellInfo);
|
|
1043
|
+
this._emit('CellsSelected');
|
|
1044
|
+
let cellSelectionChangedInfo = Object.assign(Object.assign({}, this.api.internalApi.buildBaseContext()), { selectedCellInfo: this.api.gridApi.getGridState().SelectedCellInfo });
|
|
1045
|
+
this.api.eventApi.emit('CellSelectionChanged', cellSelectionChangedInfo);
|
|
1046
|
+
return selectedCellInfo;
|
|
1047
|
+
}
|
|
1048
|
+
refreshSelectedRowsState() {
|
|
1049
|
+
if (!this.isGridSelectable()) {
|
|
1050
|
+
return undefined;
|
|
1051
|
+
}
|
|
1052
|
+
const selectedRowInfo = this.agGridAdapter.deriveSelectedRowInfoFromAgGrid();
|
|
1053
|
+
this.api.gridApi.internalApi.setSelectedRows(selectedRowInfo);
|
|
1054
|
+
const rowSelectionChangedInfo = Object.assign(Object.assign({}, this.api.internalApi.buildBaseContext()), { selectedRowInfo: this.api.gridApi.getGridState().SelectedRowInfo });
|
|
1055
|
+
this.api.eventApi.emit('RowSelectionChanged', rowSelectionChangedInfo);
|
|
1056
|
+
return selectedRowInfo;
|
|
1057
|
+
}
|
|
1058
|
+
isGridSelectable() {
|
|
1059
|
+
return (this.agGridAdapter.initialGridOptions.rowSelection === 'single' ||
|
|
1060
|
+
this.agGridAdapter.initialGridOptions.rowSelection === 'multiple');
|
|
1061
|
+
}
|
|
1062
|
+
initAdaptableStore() {
|
|
1063
|
+
const perfNewAdaptableStore = this.logger.beginPerf(`initAdaptableStore()`);
|
|
1064
|
+
const adaptableStore = new AdaptableStore(this);
|
|
1065
|
+
adaptableStore.onAny((eventName, data) => {
|
|
1066
|
+
this.performAudit(data.action, data.state, data.newState);
|
|
1067
|
+
this.forPlugins((plugin) => plugin.onStoreEvent(eventName, data, this.adaptableStore));
|
|
1068
|
+
});
|
|
1069
|
+
perfNewAdaptableStore.end();
|
|
1070
|
+
return adaptableStore;
|
|
1071
|
+
}
|
|
1072
|
+
mapAdaptableStateToAgGridState(adaptableState, agGridColDefs) {
|
|
1073
|
+
var _a, _b, _c;
|
|
1074
|
+
const agGridState = {};
|
|
1075
|
+
const currentLayoutName = (_a = adaptableState.Layout) === null || _a === void 0 ? void 0 : _a.CurrentLayout;
|
|
1076
|
+
const currentLayout = currentLayoutName &&
|
|
1077
|
+
((_c = (_b = adaptableState.Layout) === null || _b === void 0 ? void 0 : _b.Layouts) === null || _c === void 0 ? void 0 : _c.find((l) => l.Name === currentLayoutName));
|
|
1078
|
+
if (!currentLayout) {
|
|
1079
|
+
return agGridState;
|
|
1080
|
+
}
|
|
1081
|
+
const allAgGridColDefIds = agGridColDefs.map((colDef) => colDef.colId);
|
|
1082
|
+
const getColDef = (colId) => agGridColDefs.find((colDef) => colDef.colId == colId);
|
|
1083
|
+
agGridState.columnVisibility = {
|
|
1084
|
+
hiddenColIds: allAgGridColDefIds.filter((colDefId) => { var _a; return !((_a = currentLayout.Columns) === null || _a === void 0 ? void 0 : _a.includes(colDefId)); }),
|
|
1085
|
+
};
|
|
1086
|
+
agGridState.columnOrder = {
|
|
1087
|
+
orderedColIds: sortWithOrderArray(allAgGridColDefIds, currentLayout.Columns || [], {
|
|
1088
|
+
sortUnorderedItems: false,
|
|
1089
|
+
}),
|
|
1090
|
+
};
|
|
1091
|
+
if (currentLayout.ColumnWidthMap) {
|
|
1092
|
+
agGridState.columnSizing = {
|
|
1093
|
+
columnSizingModel: Object.keys(currentLayout.ColumnWidthMap).map((colId) => {
|
|
1094
|
+
const width = currentLayout.ColumnWidthMap[colId];
|
|
1095
|
+
return {
|
|
1096
|
+
colId,
|
|
1097
|
+
width,
|
|
1098
|
+
};
|
|
1099
|
+
}),
|
|
1100
|
+
};
|
|
1101
|
+
}
|
|
1102
|
+
if (currentLayout.ColumnSorts) {
|
|
1103
|
+
agGridState.sort = {
|
|
1104
|
+
sortModel: currentLayout.ColumnSorts.map((columnSort) => {
|
|
1105
|
+
return {
|
|
1106
|
+
colId: columnSort.ColumnId,
|
|
1107
|
+
sort: columnSort.SortOrder === 'Asc' ? 'asc' : 'desc',
|
|
1108
|
+
};
|
|
1109
|
+
}),
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1112
|
+
if (currentLayout.RowGroupedColumns) {
|
|
1113
|
+
agGridState.rowGroup = {
|
|
1114
|
+
groupColIds: currentLayout.RowGroupedColumns,
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
if (currentLayout.AggregationColumns) {
|
|
1118
|
+
agGridState.aggregation = {
|
|
1119
|
+
aggregationModel: Object.keys(currentLayout.AggregationColumns).map((colId) => {
|
|
1120
|
+
let aggFunc = currentLayout.AggregationColumns[colId];
|
|
1121
|
+
if (aggFunc === true) {
|
|
1122
|
+
const colDef = getColDef(colId);
|
|
1123
|
+
// fallback to SUM if no defaultAggFunc is defined
|
|
1124
|
+
aggFunc = (colDef === null || colDef === void 0 ? void 0 : colDef.defaultAggFunc) || 'sum';
|
|
1125
|
+
}
|
|
1126
|
+
if (isWeightedAverageAggregation(aggFunc)) {
|
|
1127
|
+
aggFunc = WEIGHTED_AVERAGE_AGG_FN_NAME;
|
|
1128
|
+
}
|
|
1129
|
+
return {
|
|
1130
|
+
colId,
|
|
1131
|
+
aggFunc,
|
|
1132
|
+
};
|
|
1133
|
+
}),
|
|
1134
|
+
};
|
|
1135
|
+
}
|
|
1136
|
+
if (currentLayout.PivotColumns || currentLayout.EnablePivot) {
|
|
1137
|
+
agGridState.pivot = {
|
|
1138
|
+
pivotMode: currentLayout.EnablePivot,
|
|
1139
|
+
pivotColIds: currentLayout.PivotColumns || [],
|
|
1140
|
+
};
|
|
1141
|
+
}
|
|
1142
|
+
if (currentLayout.PinnedColumnsMap) {
|
|
1143
|
+
const columnPinning = {
|
|
1144
|
+
leftColIds: [],
|
|
1145
|
+
rightColIds: [],
|
|
1146
|
+
};
|
|
1147
|
+
Object.keys(currentLayout.PinnedColumnsMap).forEach((colId) => {
|
|
1148
|
+
const pinned = currentLayout.PinnedColumnsMap[colId];
|
|
1149
|
+
if (pinned === 'left') {
|
|
1150
|
+
columnPinning.leftColIds.push(colId);
|
|
1151
|
+
}
|
|
1152
|
+
else if (pinned === 'right') {
|
|
1153
|
+
columnPinning.rightColIds.push(colId);
|
|
1154
|
+
}
|
|
1155
|
+
});
|
|
1156
|
+
agGridState.columnPinning = columnPinning;
|
|
1157
|
+
}
|
|
1158
|
+
return agGridState;
|
|
1159
|
+
}
|
|
1160
|
+
addGridEventListeners() {
|
|
1161
|
+
/**
|
|
1162
|
+
* Intercept DOM events and emit them as Adaptable events
|
|
1163
|
+
*/
|
|
1164
|
+
const gridContainerElement = this.getAgGridContainerElement();
|
|
1165
|
+
if (gridContainerElement) {
|
|
1166
|
+
gridContainerElement.addEventListener('keydown', (this.agGridListenerKeydown = (event) => this._emit('KeyDown', event)),
|
|
1167
|
+
// This is needed to be able to prevent the editor to be opened
|
|
1168
|
+
// in bubling phase the opening is not prevented with ag-grid v30
|
|
1169
|
+
true);
|
|
1170
|
+
gridContainerElement.addEventListener('mouseenter', (this.agGridListenerMouseEnter = (event) => {
|
|
1171
|
+
this._emit('MouseEnter', event);
|
|
1172
|
+
}), true);
|
|
1173
|
+
gridContainerElement.addEventListener('mouseleave', (this.agGridListenerMouseLeave = (event) => this._emit('MouseLeave', event)));
|
|
1174
|
+
}
|
|
1175
|
+
this.throttleFilterOnEditDataChange = throttle(
|
|
1176
|
+
// the extra function is to make sure we have a reference to ag-grid-api
|
|
1177
|
+
() => { var _a; return (_a = this.agGridAdapter.getAgGridApi()) === null || _a === void 0 ? void 0 : _a.onFilterChanged(); }, this.adaptableOptions.columnFilterOptions.filterActionOnUserDataChange.throttleDelay, {
|
|
1178
|
+
trailing: true,
|
|
1179
|
+
leading: false,
|
|
1180
|
+
});
|
|
1181
|
+
this.throttleFilterOnTickingDataChange = throttle(() => { var _a; return (_a = this.agGridAdapter.getAgGridApi()) === null || _a === void 0 ? void 0 : _a.onFilterChanged(); }, this.adaptableOptions.columnFilterOptions.filterActionOnExternalDataChange.throttleDelay, {
|
|
1182
|
+
trailing: true,
|
|
1183
|
+
leading: false,
|
|
1184
|
+
});
|
|
1185
|
+
/**
|
|
1186
|
+
* Use Case: AG Grid columns have changed
|
|
1187
|
+
* Action: Set Columns in store and filter grid
|
|
1188
|
+
*/
|
|
1189
|
+
this.debouncedSetColumnIntoStore = debounce(() => {
|
|
1190
|
+
if (!this.isReady) {
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
this.deriveAdaptableColumnStateFromAgGrid();
|
|
1194
|
+
}, HALF_SECOND);
|
|
1195
|
+
const columnEventsThatTriggersStateChange = [
|
|
1196
|
+
Events.EVENT_COLUMN_MOVED,
|
|
1197
|
+
Events.EVENT_GRID_COLUMNS_CHANGED,
|
|
1198
|
+
Events.EVENT_COLUMN_EVERYTHING_CHANGED,
|
|
1199
|
+
Events.EVENT_DISPLAYED_COLUMNS_CHANGED,
|
|
1200
|
+
Events.EVENT_COLUMN_VISIBLE,
|
|
1201
|
+
Events.EVENT_NEW_COLUMNS_LOADED,
|
|
1202
|
+
];
|
|
1203
|
+
this.agGridAdapter.getAgGridApi().addGlobalListener((this.listenerGlobalColumnEventsThatTriggerStateChange = (type) => {
|
|
1204
|
+
if (columnEventsThatTriggersStateChange.indexOf(type) > -1) {
|
|
1205
|
+
this.debouncedSetColumnIntoStore();
|
|
1206
|
+
}
|
|
1207
|
+
}));
|
|
1208
|
+
/**
|
|
1209
|
+
* Use Case: User has started inline editing but its distabled in Action Row Options
|
|
1210
|
+
* Action: Stop editing
|
|
1211
|
+
*/
|
|
1212
|
+
this.agGridAdapter.getAgGridApi().addEventListener(Events.EVENT_CELL_EDITING_STARTED, (this.listenerCellEditingStarted = () => {
|
|
1213
|
+
var _a;
|
|
1214
|
+
if ((_a = this.adaptableOptions.actionRowOptions) === null || _a === void 0 ? void 0 : _a.disableInlineEditing)
|
|
1215
|
+
this.agGridAdapter.getAgGridApi().stopEditing();
|
|
1216
|
+
}));
|
|
1217
|
+
/**
|
|
1218
|
+
* Use Case: initial data has been displayed in grid
|
|
1219
|
+
* Action1: Set the Layout
|
|
1220
|
+
* Action2: Ensure that we have set column data types
|
|
1221
|
+
* Note: Deals with scenario where the data is provided to AdapTable after grid has been setup
|
|
1222
|
+
*/
|
|
1223
|
+
this.agGridAdapter.getAgGridApi().addEventListener(Events.EVENT_FIRST_DATA_RENDERED, (this.listenerFirstDataRendered = () => {
|
|
1224
|
+
if (this.initWithLazyData) {
|
|
1225
|
+
this.updateColumnModelAndRefreshGrid();
|
|
1226
|
+
this.api.calculatedColumnApi.refreshAggregatedCalculatedColumns();
|
|
1227
|
+
}
|
|
1228
|
+
}));
|
|
1229
|
+
/**
|
|
1230
|
+
* Use Case: Entered or Left Pivot Mode
|
|
1231
|
+
* Action 1: Autosize pivot columns when entering pivot mode (if autosize pivot in Layout is true)
|
|
1232
|
+
* Action 2: Set pivot mode on / off in api as necessary
|
|
1233
|
+
*/
|
|
1234
|
+
this.agGridAdapter.getAgGridApi().addEventListener(Events.EVENT_COLUMN_PIVOT_MODE_CHANGED, (this.listenerPivotModeChanged = (params) => {
|
|
1235
|
+
if (params.type == 'columnPivotModeChanged' &&
|
|
1236
|
+
params.columnApi != null &&
|
|
1237
|
+
params.columnApi.columnController != null &&
|
|
1238
|
+
params.columnApi.columnController.pivotMode == true) {
|
|
1239
|
+
if (this.adaptableOptions.layoutOptions.autoSizeColumnsInPivotLayout == true) {
|
|
1240
|
+
this.agGridAdapter.getAgGridApi().autoSizeAllColumns();
|
|
1241
|
+
}
|
|
1242
|
+
this.api.internalApi.setPivotModeOn();
|
|
1243
|
+
}
|
|
1244
|
+
else {
|
|
1245
|
+
this.api.internalApi.setPivotModeOff();
|
|
1246
|
+
}
|
|
1247
|
+
}));
|
|
1248
|
+
/**
|
|
1249
|
+
* Use Case: A pivot column has changed
|
|
1250
|
+
* Action: Autosize pivot columns (if autosize pivot in Layout is true)
|
|
1251
|
+
*/
|
|
1252
|
+
this.agGridAdapter.getAgGridApi().addEventListener(Events.EVENT_COLUMN_PIVOT_CHANGED, (this.listenerPivotChanged = (params) => {
|
|
1253
|
+
if (params.type == 'columnPivotChanged' &&
|
|
1254
|
+
params.columnApi != null &&
|
|
1255
|
+
params.columnApi.columnController != null &&
|
|
1256
|
+
params.columnApi.columnController.pivotMode == true) {
|
|
1257
|
+
if (this.adaptableOptions.layoutOptions.autoSizeColumnsInPivotLayout == true) {
|
|
1258
|
+
this.agGridAdapter.getAgGridApi().autoSizeAllColumns();
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
}));
|
|
1262
|
+
/**
|
|
1263
|
+
* Use Case: Things have changed in the grid that require the Layout to be saved
|
|
1264
|
+
* Action: Save the Layout (on a debounce)
|
|
1265
|
+
*/
|
|
1266
|
+
const columnEventsThatTriggersAutoLayoutSave = [
|
|
1267
|
+
Events.EVENT_COLUMN_PINNED,
|
|
1268
|
+
Events.EVENT_COLUMN_PIVOT_CHANGED,
|
|
1269
|
+
Events.EVENT_COLUMN_PIVOT_MODE_CHANGED,
|
|
1270
|
+
Events.EVENT_DISPLAYED_COLUMNS_CHANGED,
|
|
1271
|
+
Events.EVENT_SORT_CHANGED,
|
|
1272
|
+
Events.EVENT_COLUMN_ROW_GROUP_CHANGED,
|
|
1273
|
+
Events.EVENT_COLUMN_VALUE_CHANGED,
|
|
1274
|
+
];
|
|
1275
|
+
// ADD filter event
|
|
1276
|
+
this.agGridAdapter.getAgGridApi().addGlobalListener((this.listenerGlobalColumnEventsThatTriggerAutoLayoutSave = (type) => {
|
|
1277
|
+
if (columnEventsThatTriggersAutoLayoutSave.indexOf(type) > -1) {
|
|
1278
|
+
this.debouncedSaveGridLayout();
|
|
1279
|
+
}
|
|
1280
|
+
}));
|
|
1281
|
+
/**
|
|
1282
|
+
* Save Layout if Display Row Groups is "dynamic
|
|
1283
|
+
*/
|
|
1284
|
+
this.debouncedSaveGridLayout = debounce(() => {
|
|
1285
|
+
if (!this.isReady) {
|
|
1286
|
+
return;
|
|
1287
|
+
}
|
|
1288
|
+
this.updateLayoutFromGrid();
|
|
1289
|
+
}, HALF_SECOND);
|
|
1290
|
+
const rowGroupEventsThatTriggersAutoLayoutSave = [
|
|
1291
|
+
Events.EVENT_ROW_GROUP_OPENED,
|
|
1292
|
+
Events.EVENT_EXPAND_COLLAPSE_ALL,
|
|
1293
|
+
];
|
|
1294
|
+
this.agGridAdapter.getAgGridApi().addGlobalListener((this.listenerGlobalRowGroupEventsThatTriggerAutoLayoutSave = (type) => {
|
|
1295
|
+
if (rowGroupEventsThatTriggersAutoLayoutSave.indexOf(type) > -1) {
|
|
1296
|
+
if (this.adaptableOptions.layoutOptions.displayRowGroups == 'dynamic') {
|
|
1297
|
+
this.debouncedSaveGridLayout();
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
}));
|
|
1301
|
+
/**
|
|
1302
|
+
* Use Case: Column Row Grouping changes and 'restoreUngroupedColumns' is true
|
|
1303
|
+
* Action: Make the column invisiblel
|
|
1304
|
+
*/
|
|
1305
|
+
this.agGridAdapter.getAgGridApi().addEventListener(Events.EVENT_COLUMN_ROW_GROUP_CHANGED, (this.listenerColumnRowGroupChanged = (params) => {
|
|
1306
|
+
var _a, _b;
|
|
1307
|
+
if (this.api.internalApi.isGridInPivotMode()) {
|
|
1308
|
+
return;
|
|
1309
|
+
}
|
|
1310
|
+
if ((_b = (_a = this.adaptableOptions) === null || _a === void 0 ? void 0 : _a.groupingOptions) === null || _b === void 0 ? void 0 : _b.restoreUngroupedColumns) {
|
|
1311
|
+
this.persistColumnIndexBeforeGrouping(params);
|
|
1312
|
+
}
|
|
1313
|
+
}));
|
|
1314
|
+
/**
|
|
1315
|
+
* Use Case: A Column has finished being resized
|
|
1316
|
+
* Action 1: Save the Layout (on a debounce)
|
|
1317
|
+
* Action 2: Emit the internal ColumnResized event - used by Sparkline Column (in Charts)
|
|
1318
|
+
*/
|
|
1319
|
+
this.agGridAdapter.getAgGridApi().addEventListener(Events.EVENT_COLUMN_RESIZED, (this.listenerColumnResized = (params) => {
|
|
1320
|
+
if (params.finished == true && params.type == 'columnResized' && params.column) {
|
|
1321
|
+
this.debouncedSaveGridLayout();
|
|
1322
|
+
}
|
|
1323
|
+
}));
|
|
1324
|
+
/**
|
|
1325
|
+
* Use Case: Row Selection has changed
|
|
1326
|
+
* Action: Set Selected Rows (on a debeounce)
|
|
1327
|
+
*/
|
|
1328
|
+
this.debouncedSetSelectedRows = debounce(() => {
|
|
1329
|
+
if (!this.isReady) {
|
|
1330
|
+
return;
|
|
1331
|
+
}
|
|
1332
|
+
this.refreshSelectedRowsState();
|
|
1333
|
+
}, HALF_SECOND);
|
|
1334
|
+
const columnEventsThatTriggerSetRowSelection = [
|
|
1335
|
+
Events.EVENT_ROW_GROUP_OPENED,
|
|
1336
|
+
Events.EVENT_SELECTION_CHANGED,
|
|
1337
|
+
Events.EVENT_ROW_SELECTED,
|
|
1338
|
+
];
|
|
1339
|
+
this.agGridAdapter.getAgGridApi().addGlobalListener((this.listenerGlobalSetRowSelection = (type) => {
|
|
1340
|
+
if (ArrayExtensions.ContainsItem(columnEventsThatTriggerSetRowSelection, type)) {
|
|
1341
|
+
this.debouncedSetSelectedRows();
|
|
1342
|
+
}
|
|
1343
|
+
}));
|
|
1344
|
+
/**
|
|
1345
|
+
* Use Case: User has selected a range of cells
|
|
1346
|
+
* Action: Set Selected Cells (on a debounce)
|
|
1347
|
+
*/
|
|
1348
|
+
this.debouncedSetSelectedCells = debounce(() => {
|
|
1349
|
+
if (!this.isReady) {
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
this.refreshSelectedCellsState();
|
|
1353
|
+
}, 250);
|
|
1354
|
+
this.agGridAdapter.getAgGridApi().addEventListener(Events.EVENT_RANGE_SELECTION_CHANGED, (this.listenerRangeSelectionChanged = (params) => {
|
|
1355
|
+
if (params.finished == true) {
|
|
1356
|
+
this.debouncedSetSelectedCells();
|
|
1357
|
+
}
|
|
1358
|
+
}));
|
|
1359
|
+
/**
|
|
1360
|
+
* Use Case: Sort has changed in the Grid
|
|
1361
|
+
* Action1: Update AdapTable Sort Info
|
|
1362
|
+
* Action2: Set Selected Cells (on a debounce)
|
|
1363
|
+
*/
|
|
1364
|
+
this.agGridAdapter.getAgGridApi().addEventListener(Events.EVENT_SORT_CHANGED, (this.listenerSortChanged = () => {
|
|
1365
|
+
this.onSortChanged();
|
|
1366
|
+
this.debouncedSetSelectedCells();
|
|
1367
|
+
}));
|
|
1368
|
+
const showGroupingTotalsAsHeader = this.adaptableOptions.groupingOptions.showGroupingTotalsAsHeader;
|
|
1369
|
+
/**
|
|
1370
|
+
* Use Case: Model has updated
|
|
1371
|
+
* Action: If user has set to see grouping totals as header create a pinned row (bit of a hack)
|
|
1372
|
+
*/
|
|
1373
|
+
this.agGridAdapter.getAgGridApi().addEventListener(Events.EVENT_MODEL_UPDATED, (this.listenerModelUpdated = (params) => {
|
|
1374
|
+
if (showGroupingTotalsAsHeader) {
|
|
1375
|
+
if (params && params.api) {
|
|
1376
|
+
const pinnedData = params.api.getPinnedTopRow(0);
|
|
1377
|
+
const model = params.api.getModel();
|
|
1378
|
+
const rootNode = model.getRootNode();
|
|
1379
|
+
if (!pinnedData) {
|
|
1380
|
+
params.api.setPinnedTopRowData([rootNode.aggData]);
|
|
1381
|
+
}
|
|
1382
|
+
else {
|
|
1383
|
+
pinnedData.updateData(rootNode.aggData);
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
}));
|
|
1388
|
+
const eventsThatTriggerChartingChanges = [
|
|
1389
|
+
Events.EVENT_CHART_CREATED,
|
|
1390
|
+
/** Chart Range selection has changed */
|
|
1391
|
+
Events.EVENT_CHART_RANGE_SELECTION_CHANGED,
|
|
1392
|
+
/** Chart Options have changed */
|
|
1393
|
+
Events.EVENT_CHART_OPTIONS_CHANGED,
|
|
1394
|
+
/** Chart was destroyed */
|
|
1395
|
+
Events.EVENT_CHART_DESTROYED,
|
|
1396
|
+
];
|
|
1397
|
+
const chartingModule = this.ModuleService.getModuleById('Charting');
|
|
1398
|
+
if (chartingModule.isModuleAvailable()) {
|
|
1399
|
+
this.agGridAdapter.getAgGridApi().addGlobalListener((type, params) => {
|
|
1400
|
+
if (ArrayExtensions.ContainsItem(eventsThatTriggerChartingChanges, type)) {
|
|
1401
|
+
this.ChartingService.onChartModelChange(this.getChartModels(), type, params);
|
|
1402
|
+
}
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1405
|
+
/**
|
|
1406
|
+
* Row and Cell listeners created in 2020
|
|
1407
|
+
* These have supplanted many of the events we previously had and simplified things
|
|
1408
|
+
*/
|
|
1409
|
+
this.rowListeners = {
|
|
1410
|
+
dataChanged: (event) => {
|
|
1411
|
+
this.onRowDataChanged({
|
|
1412
|
+
rowNode: event.node,
|
|
1413
|
+
oldData: event.oldData,
|
|
1414
|
+
newData: event.newData,
|
|
1415
|
+
});
|
|
1416
|
+
},
|
|
1417
|
+
cellChanged: (event) => {
|
|
1418
|
+
if (event.column) {
|
|
1419
|
+
this.onCellDataChanged({
|
|
1420
|
+
rowNode: event.node,
|
|
1421
|
+
oldValue: event.oldValue,
|
|
1422
|
+
newValue: event.newValue,
|
|
1423
|
+
colId: event.column.colId,
|
|
1424
|
+
});
|
|
1425
|
+
}
|
|
1426
|
+
},
|
|
1427
|
+
};
|
|
1428
|
+
}
|
|
1429
|
+
performAudit(action, oldState, newState) {
|
|
1430
|
+
if (this.isReady) {
|
|
1431
|
+
const adaptableStateChangedInfo = {
|
|
1432
|
+
adaptableApi: this.api,
|
|
1433
|
+
actionName: action.type,
|
|
1434
|
+
clientTimestamp: new Date(),
|
|
1435
|
+
userName: this.adaptableOptions.userName,
|
|
1436
|
+
adaptableId: this.adaptableOptions.adaptableId,
|
|
1437
|
+
adaptableStateKey: this.adaptableOptions.adaptableStateKey,
|
|
1438
|
+
action: action,
|
|
1439
|
+
oldState: oldState,
|
|
1440
|
+
newState: newState,
|
|
1441
|
+
};
|
|
1442
|
+
this.api.eventApi.emit('AdaptableStateChanged', adaptableStateChangedInfo);
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
forPlugins(callback) {
|
|
1446
|
+
if (Array.isArray(this.adaptableOptions.plugins)) {
|
|
1447
|
+
this.adaptableOptions.plugins.forEach((plugin) => {
|
|
1448
|
+
callback(plugin);
|
|
1449
|
+
});
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
getPluginProperty(pluginId, propertyName, ...args) {
|
|
1453
|
+
const plugins = this.adaptableOptions.plugins || [];
|
|
1454
|
+
const thePlugin = plugins.filter((p) => p.pluginId === pluginId)[0];
|
|
1455
|
+
if (!thePlugin) {
|
|
1456
|
+
throw `Cannot find plugin "${pluginId}". Make sure you spelled it right!`;
|
|
1457
|
+
}
|
|
1458
|
+
if (thePlugin && thePlugin.hasProperty(propertyName)) {
|
|
1459
|
+
return thePlugin.getProperty(propertyName)(...args);
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
getPlugin(pluginId) {
|
|
1463
|
+
const plugins = this.adaptableOptions.plugins || [];
|
|
1464
|
+
const thePlugin = plugins.filter((p) => p.pluginId === pluginId)[0];
|
|
1465
|
+
if (!thePlugin) {
|
|
1466
|
+
throw `Cannot find plugin "${pluginId}". Make sure you spelled it right!`;
|
|
1467
|
+
}
|
|
1468
|
+
return thePlugin;
|
|
1469
|
+
}
|
|
1470
|
+
initServices() {
|
|
1471
|
+
// create the services
|
|
1472
|
+
this.LicenseService = this.initLicenseService();
|
|
1473
|
+
this.ChartingService = new ChartingService(this.api);
|
|
1474
|
+
this.ThemeService = new ThemeService(this.api);
|
|
1475
|
+
this.ValidationService = new ValidationService(this.api);
|
|
1476
|
+
this.ReportService = new ReportService(this.api);
|
|
1477
|
+
this.ModuleService = new ModuleService(this.api);
|
|
1478
|
+
this.CalculatedColumnExpressionService = new CalculatedColumnExpressionService(this.api);
|
|
1479
|
+
this.EntitlementService = new EntitlementService(this.api);
|
|
1480
|
+
this.QueryLanguageService = new QueryLanguageService(this.api);
|
|
1481
|
+
this.AlertService = new AlertService(this.api);
|
|
1482
|
+
this.TeamSharingService = new TeamSharingService(this.api);
|
|
1483
|
+
this.Fdc3Service = new Fdc3Service(this.api);
|
|
1484
|
+
this.CellPopupService = new CellPopupService(this.api);
|
|
1485
|
+
this.RowEditService = new RowEditService(this.api);
|
|
1486
|
+
this.MetamodelService = new MetamodelService(() => this.api.optionsApi.getAdaptableOptions(), true);
|
|
1487
|
+
}
|
|
1488
|
+
initLicenseService() {
|
|
1489
|
+
const globalObject = typeof globalThis !== 'undefined' ? globalThis : window;
|
|
1490
|
+
const licenseKey = globalObject.ADAPTABLE_LICENSE_KEY || this.api.optionsApi.getLicenseKey();
|
|
1491
|
+
return new LicenseService(this, licenseKey, {
|
|
1492
|
+
publishedAt: publishTimestamp,
|
|
1493
|
+
});
|
|
1494
|
+
}
|
|
1495
|
+
initModules() {
|
|
1496
|
+
const modules = new Map();
|
|
1497
|
+
modules.set(ModuleConstants.AlertModuleId, new AlertModule(this.api));
|
|
1498
|
+
modules.set(ModuleConstants.BulkUpdateModuleId, new BulkUpdateModule(this.api));
|
|
1499
|
+
modules.set(ModuleConstants.CalculatedColumnModuleId, new CalculatedColumnModule(this.api));
|
|
1500
|
+
modules.set(ModuleConstants.CellSummaryModuleId, new CellSummaryModule(this.api));
|
|
1501
|
+
modules.set(ModuleConstants.ChartingModuleId, new ChartingModule(this.api));
|
|
1502
|
+
modules.set(ModuleConstants.ColumnFilterModuleId, new ColumnFilterModule(this.api));
|
|
1503
|
+
modules.set(ModuleConstants.ColumnInfoModuleId, new ColumnInfoModule(this.api));
|
|
1504
|
+
modules.set(ModuleConstants.CommentsModuleId, new CommentsModule(this.api));
|
|
1505
|
+
modules.set(ModuleConstants.CustomSortModuleId, new CustomSortModule(this.api));
|
|
1506
|
+
modules.set(ModuleConstants.DashboardModuleId, new DashboardModule(this.api));
|
|
1507
|
+
modules.set(ModuleConstants.DataChangeHistoryModuleId, new DataChangeHistoryModule(this.api));
|
|
1508
|
+
modules.set(ModuleConstants.DataImportModuleId, new DataImportModule(this.api));
|
|
1509
|
+
modules.set(ModuleConstants.DataSetModuleId, new DataSetModule(this.api));
|
|
1510
|
+
modules.set(ModuleConstants.ExportModuleId, new ExportModule(this.api));
|
|
1511
|
+
modules.set(ModuleConstants.Fdc3ModuleId, new Fdc3Module(this.api));
|
|
1512
|
+
modules.set(ModuleConstants.FlashingCellModuleId, new FlashingCellModule(this.api));
|
|
1513
|
+
modules.set(ModuleConstants.FormatColumnModuleId, new FormatColumnModule(this.api));
|
|
1514
|
+
modules.set(ModuleConstants.FreeTextColumnModuleId, new FreeTextColumnModule(this.api));
|
|
1515
|
+
modules.set(ModuleConstants.GridFilterModuleId, new GridFilterModule(this.api));
|
|
1516
|
+
modules.set(ModuleConstants.GridInfoModuleId, new GridInfoModule(this.api));
|
|
1517
|
+
modules.set(ModuleConstants.LayoutModuleId, new LayoutModule(this.api));
|
|
1518
|
+
modules.set(ModuleConstants.NamedQueryModuleId, new NamedQueryModule(this.api));
|
|
1519
|
+
modules.set(ModuleConstants.NotesModuleId, new NotesModule(this.api));
|
|
1520
|
+
modules.set(ModuleConstants.PlusMinusModuleId, new PlusMinusModule(this.api));
|
|
1521
|
+
modules.set(ModuleConstants.QuickSearchModuleId, new QuickSearchModule(this.api));
|
|
1522
|
+
modules.set(ModuleConstants.ScheduleModuleId, new ScheduleModule(this.api));
|
|
1523
|
+
modules.set(ModuleConstants.SettingsPanelModuleId, new SettingsPanelModule(this.api));
|
|
1524
|
+
modules.set(ModuleConstants.ShortcutModuleId, new ShortcutModule(this.api));
|
|
1525
|
+
modules.set(ModuleConstants.SmartEditModuleId, new SmartEditModule(this.api));
|
|
1526
|
+
modules.set(ModuleConstants.StateManagementModuleId, new StateManagementModule(this.api));
|
|
1527
|
+
modules.set(ModuleConstants.StatusBarModuleId, new StatusBarModule(this.api));
|
|
1528
|
+
modules.set(ModuleConstants.StyledColumnModuleId, new StyledColumnModule(this.api));
|
|
1529
|
+
modules.set(ModuleConstants.SystemStatusModuleId, new SystemStatusModule(this.api));
|
|
1530
|
+
modules.set(ModuleConstants.TeamSharingModuleId, new TeamSharingModule(this.api));
|
|
1531
|
+
modules.set(ModuleConstants.ThemeModuleId, new ThemeModule(this.api));
|
|
1532
|
+
modules.set(ModuleConstants.ToolPanelModuleId, new ToolPanelModule(this.api));
|
|
1533
|
+
return modules;
|
|
1534
|
+
}
|
|
1535
|
+
/**
|
|
1536
|
+
* This method contains all the updates on the AdaptableState which were made AFTER Adaptbale was ready
|
|
1537
|
+
* This was contidioned because we required AG Grid to be ready before we could make these updates
|
|
1538
|
+
* We should be able to refactor the code, no that we no fore sure that Adaptable State is ready BEFORE AG Grid init
|
|
1539
|
+
*/
|
|
1540
|
+
temporaryAdaptableStateUpdates() {
|
|
1541
|
+
this.api.eventApi.on('AdaptableReady', () => {
|
|
1542
|
+
var _a, _b;
|
|
1543
|
+
// update status bar state
|
|
1544
|
+
const adaptableStatusPanels = (_b = (_a = this.agGridAdapter.initialGridOptions.statusBar) === null || _a === void 0 ? void 0 : _a.statusPanels) === null || _b === void 0 ? void 0 : _b.filter((statusPanel) => this.adaptableStatusPanelKeys.includes(statusPanel.key));
|
|
1545
|
+
const statusBarModule = this.ModuleService.getModuleById(ModuleConstants.StatusBarModuleId);
|
|
1546
|
+
// need to add only the adaptable panels
|
|
1547
|
+
statusBarModule.syncStateWithOptions(adaptableStatusPanels);
|
|
1548
|
+
});
|
|
1549
|
+
}
|
|
1550
|
+
validatePrimaryKey() {
|
|
1551
|
+
if (this.hasAutogeneratedPrimaryKey) {
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
const primaryKey = this.adaptableOptions.primaryKey;
|
|
1555
|
+
const primaryKeyColDef = this.agGridAdapter.getAgGridApi().getColumnDef(primaryKey);
|
|
1556
|
+
if (!primaryKeyColDef) {
|
|
1557
|
+
const errorMessage = `The Primary Key Column '${this.adaptableOptions.primaryKey}' does not exist. This will affect many functions in Adaptable.`;
|
|
1558
|
+
if (this.adaptableOptions.alertOptions.showMissingPrimaryKeyAlert) {
|
|
1559
|
+
// show an alert if that is the option
|
|
1560
|
+
this.api.alertApi.showAlertError('No Primary Key', errorMessage);
|
|
1561
|
+
}
|
|
1562
|
+
else {
|
|
1563
|
+
if (this.adaptableOptions.columnOptions.showMissingColumnsWarning) {
|
|
1564
|
+
this.logger.consoleError(errorMessage);
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
deriveAdaptableColumnStateFromAgGrid() {
|
|
1570
|
+
const allColumns = [];
|
|
1571
|
+
const agGridCols = this.agGridAdapter.getAgGridApi().getColumns();
|
|
1572
|
+
const columnGroupChildren = this.agGridAdapter
|
|
1573
|
+
.getAgGridApi()
|
|
1574
|
+
// TODO AFL MIG: check why this assertion is here
|
|
1575
|
+
.getAllDisplayedColumnGroups();
|
|
1576
|
+
const groupsCount = {};
|
|
1577
|
+
const colsToGroups = columnGroupChildren.reduce((acc, columnGroup) => {
|
|
1578
|
+
var _a, _b, _c;
|
|
1579
|
+
if (!((_b = (_a = columnGroup.getProvidedColumnGroup) === null || _a === void 0 ? void 0 : _a.call(columnGroup)) === null || _b === void 0 ? void 0 : _b.getColGroupDef())) {
|
|
1580
|
+
return acc;
|
|
1581
|
+
}
|
|
1582
|
+
const ColumnGroupId = columnGroup.getGroupId();
|
|
1583
|
+
const AllowGroupSplit = !columnGroup.getProvidedColumnGroup().getColGroupDef().marryChildren;
|
|
1584
|
+
const FriendlyName = (_c = columnGroup.getProvidedColumnGroup().getColGroupDef().headerName) !== null && _c !== void 0 ? _c : ColumnGroupId;
|
|
1585
|
+
const columnsInGroup = columnGroup.getLeafColumns();
|
|
1586
|
+
columnsInGroup.forEach((col) => {
|
|
1587
|
+
const group = {
|
|
1588
|
+
columnGroupId: ColumnGroupId,
|
|
1589
|
+
friendlyName: FriendlyName,
|
|
1590
|
+
allowGroupSplit: AllowGroupSplit,
|
|
1591
|
+
groupCount: 0,
|
|
1592
|
+
};
|
|
1593
|
+
groupsCount[group.columnGroupId] = groupsCount[group.columnGroupId] || 0;
|
|
1594
|
+
groupsCount[group.columnGroupId] += columnsInGroup.length;
|
|
1595
|
+
acc[col.getColId()] = group;
|
|
1596
|
+
});
|
|
1597
|
+
return acc;
|
|
1598
|
+
}, {});
|
|
1599
|
+
Object.keys(colsToGroups).forEach((colId) => {
|
|
1600
|
+
colsToGroups[colId].groupCount = groupsCount[colsToGroups[colId].columnGroupId];
|
|
1601
|
+
});
|
|
1602
|
+
// TODO sort the visible columns by layout order
|
|
1603
|
+
agGridCols.forEach((agGridColumn) => {
|
|
1604
|
+
const colId = agGridColumn.getColId();
|
|
1605
|
+
if (!this.api.columnApi.isAutoRowGroupColumn(colId)) {
|
|
1606
|
+
allColumns.push(this.agGridAdapter.createAdaptableColumnFromAgGridColumn(agGridColumn, colsToGroups));
|
|
1607
|
+
}
|
|
1608
|
+
});
|
|
1609
|
+
this.api.gridApi.internalApi.setColumns(allColumns);
|
|
1610
|
+
}
|
|
1611
|
+
checkShouldClearExistingFiltersOrSearches() {
|
|
1612
|
+
// if they have selected to clear column filters on startup then do it
|
|
1613
|
+
if (this.adaptableOptions.columnFilterOptions.clearColumnFiltersOnStartUp) {
|
|
1614
|
+
if (ArrayExtensions.IsNotNullOrEmpty(this.api.columnFilterApi.getColumnFilters())) {
|
|
1615
|
+
this.logger.warn('Clearing existing Column Filters as "clearColumnFiltersOnStartUp" is true');
|
|
1616
|
+
this.api.columnFilterApi.clearColumnFilters();
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
// if they have selected to clear the Grid filter on startup then do it
|
|
1620
|
+
if (this.adaptableOptions.gridFilterOptions.clearGridFilterOnStartUp) {
|
|
1621
|
+
if (StringExtensions.IsNotNullOrEmpty(this.api.gridFilterApi.getCurrentGridFilterExpression())) {
|
|
1622
|
+
this.logger.warn('Clearing existing Grid Filter as "clearGridFilterOnStartUp" is true');
|
|
1623
|
+
this.api.gridFilterApi.setGridFilterExpression('');
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
// if they have selected to clear searches on startup then do it
|
|
1627
|
+
if (this.adaptableOptions.quickSearchOptions.clearQuickSearchOnStartUp) {
|
|
1628
|
+
if (StringExtensions.IsNotNullOrEmpty(this.api.quickSearchApi.getQuickSearchState().QuickSearchText)) {
|
|
1629
|
+
this.logger.warn('Clearing existing Searches as "clearQuickSearchOnStartUp" is true');
|
|
1630
|
+
this.api.quickSearchApi.clearQuickSearch();
|
|
1631
|
+
}
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
getGridCellFromRowNode(rowNode, columnId) {
|
|
1635
|
+
if (rowNode == null) {
|
|
1636
|
+
return undefined;
|
|
1637
|
+
}
|
|
1638
|
+
const abColumn = this.api.columnApi.getColumnWithColumnId(columnId);
|
|
1639
|
+
const pkValue = this.getPrimaryKeyValueFromRowNode(rowNode);
|
|
1640
|
+
const rawValue = this.getRawValueFromRowNode(rowNode, columnId);
|
|
1641
|
+
const displayValue = this.getDisplayValueFromRawValue(rowNode, columnId, rawValue);
|
|
1642
|
+
const normalisedValue = this.getNormalisedValueFromRawValue(rawValue, abColumn);
|
|
1643
|
+
const isPivotCell = this.api.columnApi.isAutoPivotColumn(columnId);
|
|
1644
|
+
const isRowGroupCell = rowNode.group;
|
|
1645
|
+
return {
|
|
1646
|
+
rawValue: rawValue,
|
|
1647
|
+
displayValue: displayValue,
|
|
1648
|
+
normalisedValue: normalisedValue,
|
|
1649
|
+
column: abColumn,
|
|
1650
|
+
primaryKeyValue: pkValue,
|
|
1651
|
+
rowNode: rowNode,
|
|
1652
|
+
isPivotCell,
|
|
1653
|
+
isRowGroupCell,
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
getPrimaryKeyValueFromRowNode(rowNode, gridApi) {
|
|
1657
|
+
if (!rowNode) {
|
|
1658
|
+
return null;
|
|
1659
|
+
}
|
|
1660
|
+
const agGridApi = gridApi || this.agGridAdapter.getAgGridApi();
|
|
1661
|
+
let result;
|
|
1662
|
+
if (!this.hasAutogeneratedPrimaryKey) {
|
|
1663
|
+
result = agGridApi.getValue(this.adaptableOptions.primaryKey, rowNode);
|
|
1664
|
+
}
|
|
1665
|
+
if (result == undefined && rowNode.data) {
|
|
1666
|
+
result = rowNode.data[this.adaptableOptions.primaryKey];
|
|
1667
|
+
}
|
|
1668
|
+
return result;
|
|
1669
|
+
}
|
|
1670
|
+
getRawValueFromRowNode(rowNode, columnId) {
|
|
1671
|
+
if (rowNode == null) {
|
|
1672
|
+
return undefined;
|
|
1673
|
+
}
|
|
1674
|
+
return this.agGridAdapter.getAgGridApi().getValue(columnId, rowNode);
|
|
1675
|
+
}
|
|
1676
|
+
getDisplayValueFromRowNode(rowNode, columnId) {
|
|
1677
|
+
if (rowNode == null) {
|
|
1678
|
+
return undefined;
|
|
1679
|
+
}
|
|
1680
|
+
const rawValue = this.getRawValueFromRowNode(rowNode, columnId);
|
|
1681
|
+
return this.getDisplayValueFromRawValue(rowNode, columnId, rawValue);
|
|
1682
|
+
}
|
|
1683
|
+
getDisplayValueFromRawValue(rowNode, columnId, rawValue) {
|
|
1684
|
+
var _a;
|
|
1685
|
+
const isActionColumn = this.api.columnApi.isActionColumn(columnId);
|
|
1686
|
+
if (isActionColumn) {
|
|
1687
|
+
return this.getCleanValue(rawValue);
|
|
1688
|
+
}
|
|
1689
|
+
const colDef = this.agGridAdapter.getAgGridApi().getColumnDef(columnId);
|
|
1690
|
+
if (colDef) {
|
|
1691
|
+
if (typeof colDef.valueFormatter == 'function') {
|
|
1692
|
+
const column = this.agGridAdapter.getAgGridApi().getColumn(columnId);
|
|
1693
|
+
const params = {
|
|
1694
|
+
value: rawValue,
|
|
1695
|
+
node: rowNode,
|
|
1696
|
+
data: rowNode.data,
|
|
1697
|
+
colDef,
|
|
1698
|
+
column,
|
|
1699
|
+
api: this.agGridAdapter.getAgGridApi(),
|
|
1700
|
+
columnApi: (_a = this.agGridAdapter.getLiveGridOptions()) === null || _a === void 0 ? void 0 : _a.columnApi,
|
|
1701
|
+
context: this.agGridAdapter.getLiveGridOptions().context,
|
|
1702
|
+
};
|
|
1703
|
+
const formattedValue = colDef.valueFormatter(params);
|
|
1704
|
+
return formattedValue || '';
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
return this.getCleanValue(rawValue);
|
|
1708
|
+
}
|
|
1709
|
+
getCleanValue(value) {
|
|
1710
|
+
if (typeof value === 'string') {
|
|
1711
|
+
return value;
|
|
1712
|
+
}
|
|
1713
|
+
if (value == null || value == 'null' || value == undefined || value == 'undefined') {
|
|
1714
|
+
return undefined;
|
|
1715
|
+
}
|
|
1716
|
+
return String(value) || '';
|
|
1717
|
+
}
|
|
1718
|
+
getNormalisedValueFromRawValue(rawValue, column) {
|
|
1719
|
+
if (!column) {
|
|
1720
|
+
return rawValue;
|
|
1721
|
+
}
|
|
1722
|
+
// prevents from null
|
|
1723
|
+
if (rawValue === undefined || rawValue === null) {
|
|
1724
|
+
return rawValue;
|
|
1725
|
+
}
|
|
1726
|
+
const dataType = column.dataType;
|
|
1727
|
+
if (dataType === 'String') {
|
|
1728
|
+
return typeof rawValue !== 'string' ? String(rawValue) : rawValue;
|
|
1729
|
+
}
|
|
1730
|
+
if (dataType === 'Number') {
|
|
1731
|
+
// empty string or space should not be converted to 0
|
|
1732
|
+
return typeof rawValue !== 'number' && StringExtensions.IsNumeric(rawValue)
|
|
1733
|
+
? Number(rawValue)
|
|
1734
|
+
: rawValue;
|
|
1735
|
+
}
|
|
1736
|
+
if (dataType === 'Boolean') {
|
|
1737
|
+
return typeof rawValue !== 'boolean' ? Boolean(rawValue) : rawValue;
|
|
1738
|
+
}
|
|
1739
|
+
if (dataType === 'Date') {
|
|
1740
|
+
return rawValue instanceof Date ? rawValue : parseDateValue(rawValue);
|
|
1741
|
+
}
|
|
1742
|
+
return rawValue;
|
|
1743
|
+
}
|
|
1744
|
+
updateColumnModelAndRefreshGrid() {
|
|
1745
|
+
this.deriveAdaptableColumnStateFromAgGrid();
|
|
1746
|
+
this.agGridColumnAdapter.setupColumns();
|
|
1747
|
+
this.redrawBody();
|
|
1748
|
+
this.refreshHeader();
|
|
1749
|
+
}
|
|
1750
|
+
redrawBody() {
|
|
1751
|
+
this.redrawRows();
|
|
1752
|
+
this._emit('GridRefreshed');
|
|
1753
|
+
}
|
|
1754
|
+
refreshHeader() {
|
|
1755
|
+
this.agGridAdapter.getAgGridApi().refreshHeader();
|
|
1756
|
+
}
|
|
1757
|
+
// TODO AFL: this method seems to be used A LOT
|
|
1758
|
+
// we should check if we couldn't use the `refresh` method instead for some cases
|
|
1759
|
+
// see https://www.ag-grid.com/react-data-grid/view-refresh/#redraw-rows
|
|
1760
|
+
redrawRows(rowNodes) {
|
|
1761
|
+
const redrawRowsParams = rowNodes
|
|
1762
|
+
? {
|
|
1763
|
+
rowNodes,
|
|
1764
|
+
}
|
|
1765
|
+
: undefined;
|
|
1766
|
+
try {
|
|
1767
|
+
this.agGridAdapter.getAgGridApi().redrawRows(redrawRowsParams);
|
|
1768
|
+
}
|
|
1769
|
+
catch (ex) {
|
|
1770
|
+
this.logger.consoleError('AG Grid redrawRows was unable to find some row nodes. Tried to redraw row nodes: ', rowNodes, ex);
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
redrawRow(rowNode) {
|
|
1774
|
+
this.redrawRows([rowNode]);
|
|
1775
|
+
}
|
|
1776
|
+
refreshCells(rowNodes, columns, forceUpdate, suppressFlash = false) {
|
|
1777
|
+
const refreshCellParams = {
|
|
1778
|
+
rowNodes,
|
|
1779
|
+
columns: columns,
|
|
1780
|
+
force: forceUpdate,
|
|
1781
|
+
suppressFlash,
|
|
1782
|
+
};
|
|
1783
|
+
this.agGridAdapter.getAgGridApi().refreshCells(refreshCellParams);
|
|
1784
|
+
}
|
|
1785
|
+
refreshColumns(columns, forceUpdate, suppressFlash) {
|
|
1786
|
+
this.refreshCells(null, columns, forceUpdate, suppressFlash);
|
|
1787
|
+
}
|
|
1788
|
+
jumpToRow(rowNode) {
|
|
1789
|
+
this.agGridAdapter.getAgGridApi().ensureNodeVisible(rowNode, 'middle');
|
|
1790
|
+
}
|
|
1791
|
+
jumpToColumn(columnId) {
|
|
1792
|
+
this.agGridAdapter.getAgGridApi().ensureColumnVisible(columnId);
|
|
1793
|
+
}
|
|
1794
|
+
jumpToCell(columnId, rowNode) {
|
|
1795
|
+
this.jumpToRow(rowNode);
|
|
1796
|
+
this.jumpToColumn(columnId);
|
|
1797
|
+
}
|
|
1798
|
+
selectColumn(columnId, config) {
|
|
1799
|
+
if (!(config === null || config === void 0 ? void 0 : config.keepExistingSelection)) {
|
|
1800
|
+
this.agGridAdapter.getAgGridApi().clearRangeSelection();
|
|
1801
|
+
}
|
|
1802
|
+
const cellRangeParams = {
|
|
1803
|
+
rowStartIndex: 0,
|
|
1804
|
+
rowEndIndex: this.agGridAdapter.getAgGridApi().getDisplayedRowCount() - 1,
|
|
1805
|
+
columnStart: columnId,
|
|
1806
|
+
columnEnd: columnId,
|
|
1807
|
+
};
|
|
1808
|
+
this.agGridAdapter.getAgGridApi().addCellRange(cellRangeParams);
|
|
1809
|
+
}
|
|
1810
|
+
selectColumns(columnIds, config) {
|
|
1811
|
+
if (!(config === null || config === void 0 ? void 0 : config.keepExistingSelection)) {
|
|
1812
|
+
this.agGridAdapter.getAgGridApi().clearRangeSelection();
|
|
1813
|
+
}
|
|
1814
|
+
const rowCount = this.agGridAdapter.getAgGridApi().getDisplayedRowCount();
|
|
1815
|
+
columnIds.forEach((colId) => {
|
|
1816
|
+
const cellRangeParams = {
|
|
1817
|
+
rowStartIndex: 0,
|
|
1818
|
+
rowEndIndex: rowCount - 1,
|
|
1819
|
+
columnStart: colId,
|
|
1820
|
+
columnEnd: colId,
|
|
1821
|
+
};
|
|
1822
|
+
this.agGridAdapter.getAgGridApi().addCellRange(cellRangeParams);
|
|
1823
|
+
});
|
|
1824
|
+
}
|
|
1825
|
+
selectAll() {
|
|
1826
|
+
this.agGridAdapter.getAgGridApi().selectAll();
|
|
1827
|
+
}
|
|
1828
|
+
deselectAll() {
|
|
1829
|
+
// need to do both as first just clears selected rows and second clears ranges
|
|
1830
|
+
this.agGridAdapter.getAgGridApi().deselectAll();
|
|
1831
|
+
this.agGridAdapter.getAgGridApi().clearRangeSelection();
|
|
1832
|
+
}
|
|
1833
|
+
setGridData(dataSource) {
|
|
1834
|
+
if (!this.isReady) {
|
|
1835
|
+
return;
|
|
1836
|
+
}
|
|
1837
|
+
if (this.hasAutogeneratedPrimaryKey) {
|
|
1838
|
+
this.addSyntheticPrimaryKey(dataSource);
|
|
1839
|
+
}
|
|
1840
|
+
this.agGridAdapter.setGridOption('rowData', dataSource);
|
|
1841
|
+
this.updateRowGroupsExpandedState();
|
|
1842
|
+
this.updateColumnModelAndRefreshGrid();
|
|
1843
|
+
}
|
|
1844
|
+
getGridData() {
|
|
1845
|
+
const data = [];
|
|
1846
|
+
this.agGridAdapter.getAgGridApi().forEachNode((rowNode) => {
|
|
1847
|
+
if (!this.isGroupRowNode(rowNode)) {
|
|
1848
|
+
data.push(rowNode.data);
|
|
1849
|
+
}
|
|
1850
|
+
});
|
|
1851
|
+
return data;
|
|
1852
|
+
}
|
|
1853
|
+
addSyntheticPrimaryKey(rowData = []) {
|
|
1854
|
+
for (let i = 0; i < rowData.length; i++) {
|
|
1855
|
+
rowData[i][AUTOGENERATED_PK_COLUMN] = createUuid();
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
// add a synthetic PK only if missing (useful in case of updating row data)
|
|
1859
|
+
addSyntheticPrimaryKeyIfMissing(rowData = []) {
|
|
1860
|
+
this.adaptableOptions.primaryKey = AUTOGENERATED_PK_COLUMN;
|
|
1861
|
+
for (let i = 0; i < rowData.length; i++) {
|
|
1862
|
+
if (!rowData[i][AUTOGENERATED_PK_COLUMN]) {
|
|
1863
|
+
rowData[i][AUTOGENERATED_PK_COLUMN] = createUuid();
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
getFirstDisplayedRowNode() {
|
|
1868
|
+
const firstDisplayedRowIndex = this.agGridAdapter
|
|
1869
|
+
.getAgGridApi()
|
|
1870
|
+
.getFirstDisplayedRowIndex();
|
|
1871
|
+
return this.agGridAdapter.getAgGridApi().getDisplayedRowAtIndex(firstDisplayedRowIndex);
|
|
1872
|
+
}
|
|
1873
|
+
getFirstRowNode() {
|
|
1874
|
+
let firstRowNode = this.getFirstDisplayedRowNode();
|
|
1875
|
+
if (firstRowNode === null || firstRowNode === void 0 ? void 0 : firstRowNode.group) {
|
|
1876
|
+
// all groups may be closed so it is safer to get first leaf node
|
|
1877
|
+
// all groups must have at least one leafe node
|
|
1878
|
+
firstRowNode = firstRowNode.allLeafChildren[0];
|
|
1879
|
+
}
|
|
1880
|
+
return firstRowNode;
|
|
1881
|
+
}
|
|
1882
|
+
updateRowGroupsExpandedState(layout) {
|
|
1883
|
+
if (!layout) {
|
|
1884
|
+
layout = this.api.layoutApi.getCurrentLayout();
|
|
1885
|
+
}
|
|
1886
|
+
if (this.api.layoutApi.internalApi.areExpandedRowGroupsSavedInLayouts() &&
|
|
1887
|
+
ArrayExtensions.IsNotNullOrEmpty(layout.ExpandedRowGroupValues)) {
|
|
1888
|
+
this.expandRowGroupsForValues(layout.ExpandedRowGroupValues);
|
|
1889
|
+
}
|
|
1890
|
+
if (this.adaptableOptions.layoutOptions.displayRowGroups === 'expanded') {
|
|
1891
|
+
this.expandAllRowGroups();
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
isGroupRowNode(rowNode) {
|
|
1895
|
+
if (!rowNode) {
|
|
1896
|
+
return false;
|
|
1897
|
+
}
|
|
1898
|
+
if (rowNode.isEmptyRowGroupNode()) {
|
|
1899
|
+
return true;
|
|
1900
|
+
}
|
|
1901
|
+
if (rowNode.group && rowNode.group === true) {
|
|
1902
|
+
return true;
|
|
1903
|
+
}
|
|
1904
|
+
if (rowNode.leafGroup && rowNode.leafGroup === true) {
|
|
1905
|
+
return true;
|
|
1906
|
+
}
|
|
1907
|
+
return false;
|
|
1908
|
+
}
|
|
1909
|
+
getFilteredData() {
|
|
1910
|
+
const data = [];
|
|
1911
|
+
this.agGridAdapter.getAgGridApi().forEachNodeAfterFilter((rowNode) => {
|
|
1912
|
+
if (!this.isGroupRowNode(rowNode)) {
|
|
1913
|
+
data.push(rowNode.data);
|
|
1914
|
+
}
|
|
1915
|
+
});
|
|
1916
|
+
return data;
|
|
1917
|
+
}
|
|
1918
|
+
updateRows(dataRows, dataUpdateConfig) {
|
|
1919
|
+
if (this.hasAutogeneratedPrimaryKey) {
|
|
1920
|
+
this.addSyntheticPrimaryKeyIfMissing(dataRows);
|
|
1921
|
+
}
|
|
1922
|
+
dataUpdateConfig = dataUpdateConfig || {};
|
|
1923
|
+
if (dataUpdateConfig.runAsync) {
|
|
1924
|
+
return new Promise((resolve) => {
|
|
1925
|
+
this.agGridAdapter
|
|
1926
|
+
.getAgGridApi()
|
|
1927
|
+
.applyTransactionAsync({ update: dataRows }, (transaction) => {
|
|
1928
|
+
if (typeof dataUpdateConfig.callback === 'function') {
|
|
1929
|
+
dataUpdateConfig.callback(transaction);
|
|
1930
|
+
}
|
|
1931
|
+
resolve(transaction === null || transaction === void 0 ? void 0 : transaction.update);
|
|
1932
|
+
});
|
|
1933
|
+
});
|
|
1934
|
+
}
|
|
1935
|
+
else {
|
|
1936
|
+
const transaction = this.agGridAdapter.getAgGridApi().applyTransaction({
|
|
1937
|
+
update: dataRows,
|
|
1938
|
+
});
|
|
1939
|
+
return Promise.resolve(transaction === null || transaction === void 0 ? void 0 : transaction.update);
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
addRows(dataRows, dataUpdateConfig) {
|
|
1943
|
+
if (this.hasAutogeneratedPrimaryKey) {
|
|
1944
|
+
this.addSyntheticPrimaryKey(dataRows);
|
|
1945
|
+
}
|
|
1946
|
+
dataUpdateConfig = dataUpdateConfig || {};
|
|
1947
|
+
const newData = { add: dataRows };
|
|
1948
|
+
if (dataUpdateConfig.addIndex !== undefined) {
|
|
1949
|
+
newData.addIndex = dataUpdateConfig.addIndex;
|
|
1950
|
+
}
|
|
1951
|
+
if (dataUpdateConfig.runAsync) {
|
|
1952
|
+
return new Promise((resolve) => {
|
|
1953
|
+
this.agGridAdapter.getAgGridApi().applyTransactionAsync(newData, (transaction) => {
|
|
1954
|
+
if (typeof dataUpdateConfig.callback === 'function') {
|
|
1955
|
+
dataUpdateConfig.callback(transaction);
|
|
1956
|
+
}
|
|
1957
|
+
resolve(transaction === null || transaction === void 0 ? void 0 : transaction.add);
|
|
1958
|
+
this.updateRowGroupsExpandedState();
|
|
1959
|
+
});
|
|
1960
|
+
});
|
|
1961
|
+
}
|
|
1962
|
+
else {
|
|
1963
|
+
const transaction = this.agGridAdapter.getAgGridApi().applyTransaction(newData);
|
|
1964
|
+
this.updateRowGroupsExpandedState();
|
|
1965
|
+
return Promise.resolve(transaction === null || transaction === void 0 ? void 0 : transaction.add);
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
addOrUpdateRows(dataRows, dataUpdateConfig) {
|
|
1969
|
+
const addDataRows = [];
|
|
1970
|
+
const updateDataRows = [];
|
|
1971
|
+
const primaryKey = this.adaptableOptions.primaryKey;
|
|
1972
|
+
dataRows.forEach((dataRow) => {
|
|
1973
|
+
const node = this.getRowNodeForPrimaryKey(dataRow[primaryKey]);
|
|
1974
|
+
if (node) {
|
|
1975
|
+
updateDataRows.push(dataRow);
|
|
1976
|
+
}
|
|
1977
|
+
else {
|
|
1978
|
+
addDataRows.push(dataRow);
|
|
1979
|
+
}
|
|
1980
|
+
});
|
|
1981
|
+
if (this.hasAutogeneratedPrimaryKey) {
|
|
1982
|
+
this.addSyntheticPrimaryKeyIfMissing(addDataRows);
|
|
1983
|
+
}
|
|
1984
|
+
dataUpdateConfig = dataUpdateConfig || {};
|
|
1985
|
+
if (dataUpdateConfig.runAsync) {
|
|
1986
|
+
return new Promise((resolve) => {
|
|
1987
|
+
this.agGridAdapter
|
|
1988
|
+
.getAgGridApi()
|
|
1989
|
+
.applyTransactionAsync({ update: updateDataRows, add: addDataRows, addIndex: dataUpdateConfig.addIndex }, (transaction) => {
|
|
1990
|
+
if (typeof dataUpdateConfig.callback === 'function') {
|
|
1991
|
+
dataUpdateConfig.callback(transaction);
|
|
1992
|
+
}
|
|
1993
|
+
resolve({
|
|
1994
|
+
added: transaction === null || transaction === void 0 ? void 0 : transaction.add,
|
|
1995
|
+
updated: transaction === null || transaction === void 0 ? void 0 : transaction.update,
|
|
1996
|
+
});
|
|
1997
|
+
});
|
|
1998
|
+
});
|
|
1999
|
+
}
|
|
2000
|
+
else {
|
|
2001
|
+
const transaction = this.agGridAdapter.getAgGridApi().applyTransaction({
|
|
2002
|
+
update: updateDataRows,
|
|
2003
|
+
add: addDataRows,
|
|
2004
|
+
addIndex: dataUpdateConfig.addIndex,
|
|
2005
|
+
});
|
|
2006
|
+
return Promise.resolve({
|
|
2007
|
+
added: transaction === null || transaction === void 0 ? void 0 : transaction.add,
|
|
2008
|
+
updated: transaction === null || transaction === void 0 ? void 0 : transaction.update,
|
|
2009
|
+
});
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
deleteRows(dataRows, dataUpdateConfig) {
|
|
2013
|
+
dataUpdateConfig = dataUpdateConfig || {};
|
|
2014
|
+
if (dataUpdateConfig.runAsync) {
|
|
2015
|
+
return new Promise((resolve) => {
|
|
2016
|
+
this.agGridAdapter
|
|
2017
|
+
.getAgGridApi()
|
|
2018
|
+
.applyTransactionAsync({ remove: dataRows }, (transaction) => {
|
|
2019
|
+
if (typeof dataUpdateConfig.callback === 'function') {
|
|
2020
|
+
dataUpdateConfig.callback(transaction);
|
|
2021
|
+
}
|
|
2022
|
+
resolve(transaction === null || transaction === void 0 ? void 0 : transaction.remove);
|
|
2023
|
+
});
|
|
2024
|
+
});
|
|
2025
|
+
}
|
|
2026
|
+
else {
|
|
2027
|
+
const transaction = this.agGridAdapter.getAgGridApi().applyTransaction({
|
|
2028
|
+
remove: dataRows,
|
|
2029
|
+
});
|
|
2030
|
+
return Promise.resolve(transaction.remove);
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
getRowNodeForPrimaryKey(primaryKeyValue) {
|
|
2034
|
+
if (this.useRowNodeLookUp) {
|
|
2035
|
+
return this.agGridAdapter.getAgGridApi().getRowNode(primaryKeyValue);
|
|
2036
|
+
}
|
|
2037
|
+
else {
|
|
2038
|
+
this.agGridAdapter.getAgGridApi().forEachNode((rowNode) => {
|
|
2039
|
+
if (primaryKeyValue == this.getPrimaryKeyValueFromRowNode(rowNode)) {
|
|
2040
|
+
return rowNode;
|
|
2041
|
+
}
|
|
2042
|
+
});
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
hideColumn(columnId) {
|
|
2046
|
+
let agGridColumn = this.agGridAdapter.getAgGridApi().getColumn(columnId);
|
|
2047
|
+
if (agGridColumn) {
|
|
2048
|
+
this.agGridAdapter.getAgGridApi().setColumnsVisible([columnId], false);
|
|
2049
|
+
this.deriveAdaptableColumnStateFromAgGrid();
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
showColumn(columnId) {
|
|
2053
|
+
let agGridColumn = this.agGridAdapter.getAgGridApi().getColumn(columnId);
|
|
2054
|
+
if (agGridColumn) {
|
|
2055
|
+
this.agGridAdapter.getAgGridApi().setColumnsVisible([columnId], true);
|
|
2056
|
+
this.deriveAdaptableColumnStateFromAgGrid();
|
|
2057
|
+
}
|
|
2058
|
+
}
|
|
2059
|
+
autoSizeColumn(columnId) {
|
|
2060
|
+
this.autoSizeColumns([columnId]);
|
|
2061
|
+
}
|
|
2062
|
+
autoSizeColumns(columnIds) {
|
|
2063
|
+
this.agGridAdapter.getAgGridApi().autoSizeColumns(columnIds);
|
|
2064
|
+
}
|
|
2065
|
+
autoSizeAllColumns() {
|
|
2066
|
+
this.agGridAdapter.getAgGridApi().autoSizeAllColumns();
|
|
2067
|
+
}
|
|
2068
|
+
setColumnOrder(VisibleColumnList) {
|
|
2069
|
+
const newColumnState = this.getSortedColumnStateForVisibleColumns(VisibleColumnList);
|
|
2070
|
+
this.agGridAdapter.getAgGridApi().applyColumnState({
|
|
2071
|
+
state: newColumnState,
|
|
2072
|
+
applyOrder: true,
|
|
2073
|
+
});
|
|
2074
|
+
this.deriveAdaptableColumnStateFromAgGrid();
|
|
2075
|
+
}
|
|
2076
|
+
getSortedColumnStateForVisibleColumns(visibleColumnList, columnState) {
|
|
2077
|
+
columnState = columnState || this.agGridAdapter.getAgGridApi().getColumnState();
|
|
2078
|
+
const NewVisibleColumnIdsMap = visibleColumnList.reduce((acc, colId, index) => {
|
|
2079
|
+
acc[colId] = index;
|
|
2080
|
+
return acc;
|
|
2081
|
+
}, {});
|
|
2082
|
+
const columnsStateIndexes = columnState.reduce((acc, colState, index) => {
|
|
2083
|
+
acc[colState.colId] = index;
|
|
2084
|
+
return acc;
|
|
2085
|
+
}, {});
|
|
2086
|
+
const newVisibleColumnsMap = visibleColumnList.reduce((acc, colId, index) => {
|
|
2087
|
+
acc[colId] = index;
|
|
2088
|
+
return acc;
|
|
2089
|
+
}, {});
|
|
2090
|
+
const result = [...columnState]
|
|
2091
|
+
.sort((colState1, colState2) => {
|
|
2092
|
+
const colId1 = colState1.colId;
|
|
2093
|
+
const colId2 = colState2.colId;
|
|
2094
|
+
const originalIndex1 = columnsStateIndexes[colId1];
|
|
2095
|
+
const originalIndex2 = columnsStateIndexes[colId2];
|
|
2096
|
+
const isRowGroup1 = this.api.columnApi.isAutoRowGroupColumn(colId1);
|
|
2097
|
+
const isRowGroup2 = this.api.columnApi.isAutoRowGroupColumn(colId2);
|
|
2098
|
+
if (isRowGroup1 && isRowGroup2) {
|
|
2099
|
+
return 1;
|
|
2100
|
+
}
|
|
2101
|
+
if (isRowGroup1) {
|
|
2102
|
+
return -1;
|
|
2103
|
+
}
|
|
2104
|
+
if (isRowGroup2) {
|
|
2105
|
+
return 1;
|
|
2106
|
+
}
|
|
2107
|
+
if (newVisibleColumnsMap[colId1] != null && newVisibleColumnsMap[colId2] == null) {
|
|
2108
|
+
return -1;
|
|
2109
|
+
}
|
|
2110
|
+
if (newVisibleColumnsMap[colId1] == null && newVisibleColumnsMap[colId2] != null) {
|
|
2111
|
+
return 1;
|
|
2112
|
+
}
|
|
2113
|
+
if (newVisibleColumnsMap[colId1] == null && newVisibleColumnsMap[colId2] == null) {
|
|
2114
|
+
return originalIndex1 - originalIndex2;
|
|
2115
|
+
}
|
|
2116
|
+
return newVisibleColumnsMap[colState1.colId] - newVisibleColumnsMap[colState2.colId];
|
|
2117
|
+
})
|
|
2118
|
+
.map((colState) => (Object.assign(Object.assign({}, colState), { hide: NewVisibleColumnIdsMap[colState.colId] == null })));
|
|
2119
|
+
return result;
|
|
2120
|
+
}
|
|
2121
|
+
getDistinctValuesForColumn(column, distinctValuesParams) {
|
|
2122
|
+
let gridCells = this.getGridCellsForPermittedValues(column, distinctValuesParams);
|
|
2123
|
+
if (ArrayExtensions.IsNullOrEmpty(gridCells)) {
|
|
2124
|
+
gridCells = this.getDistinctGridCellsForColumn(column, distinctValuesParams);
|
|
2125
|
+
}
|
|
2126
|
+
return this.getUniqueGridCells(column, gridCells);
|
|
2127
|
+
}
|
|
2128
|
+
getGridCellsForPermittedValues(column, distinctValuesParams) {
|
|
2129
|
+
var _a;
|
|
2130
|
+
let gridCells = [];
|
|
2131
|
+
const permittedValues = (_a = distinctValuesParams.permittedValues) !== null && _a !== void 0 ? _a : this.api.userInterfaceApi.getPermittedValuesForColumn(column);
|
|
2132
|
+
if (ArrayExtensions.IsNotNullOrEmpty(permittedValues)) {
|
|
2133
|
+
gridCells = permittedValues.map((pv) => {
|
|
2134
|
+
return {
|
|
2135
|
+
rawValue: pv,
|
|
2136
|
+
displayValue: pv,
|
|
2137
|
+
normalisedValue: pv,
|
|
2138
|
+
columnId: column.columnId,
|
|
2139
|
+
column: column,
|
|
2140
|
+
rowNode: undefined,
|
|
2141
|
+
isPivotCell: false,
|
|
2142
|
+
isRowGroupCell: false,
|
|
2143
|
+
};
|
|
2144
|
+
});
|
|
2145
|
+
return gridCells;
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
getDistinctGridCellsForColumn(column, distinctValuesParams) {
|
|
2149
|
+
let gridCells = [];
|
|
2150
|
+
if (distinctValuesParams.visibleRowsOnly) {
|
|
2151
|
+
this.agGridAdapter.getAgGridApi().forEachNodeAfterFilter((rowNode) => {
|
|
2152
|
+
const gridCell = this.addDistinctColumnValue(rowNode, column.columnId);
|
|
2153
|
+
if (gridCell &&
|
|
2154
|
+
gridCell.rawValue != undefined &&
|
|
2155
|
+
gridCell.rowNode !== distinctValuesParams.skipRowNode) {
|
|
2156
|
+
gridCells.push(gridCell);
|
|
2157
|
+
}
|
|
2158
|
+
});
|
|
2159
|
+
}
|
|
2160
|
+
else {
|
|
2161
|
+
this.agGridAdapter.getAgGridApi().forEachNode((rowNode) => {
|
|
2162
|
+
const gridCell = this.addDistinctColumnValue(rowNode, column.columnId);
|
|
2163
|
+
if (gridCell && gridCell.rowNode !== distinctValuesParams.skipRowNode) {
|
|
2164
|
+
if (gridCell.rawValue == undefined &&
|
|
2165
|
+
this.adaptableOptions.columnFilterOptions.valuesFilterOptions.includeBlankFilterValues) {
|
|
2166
|
+
gridCell.rawValue = BLANK_DISTINCT_COLUMN_VALUE;
|
|
2167
|
+
gridCell.displayValue = BLANK_DISTINCT_COLUMN_VALUE;
|
|
2168
|
+
gridCell.normalisedValue = BLANK_DISTINCT_COLUMN_VALUE;
|
|
2169
|
+
}
|
|
2170
|
+
gridCells.push(gridCell);
|
|
2171
|
+
}
|
|
2172
|
+
});
|
|
2173
|
+
}
|
|
2174
|
+
return gridCells;
|
|
2175
|
+
}
|
|
2176
|
+
addDistinctColumnValue(rowNode, columnId) {
|
|
2177
|
+
// we do not return the values of the aggregates when in grouping mode
|
|
2178
|
+
// otherwise they would appear in the filter dropdown etc....
|
|
2179
|
+
if (rowNode && !this.isGroupRowNode(rowNode)) {
|
|
2180
|
+
const returnValue = this.getGridCellFromRowNode(rowNode, columnId);
|
|
2181
|
+
if (Helper.objectExists(returnValue)) {
|
|
2182
|
+
return returnValue;
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
else {
|
|
2186
|
+
return undefined;
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
getUniqueGridCells(column, gridCells) {
|
|
2190
|
+
let uniqueVals = uniqBy(gridCells, (dataItem) => {
|
|
2191
|
+
const value = dataItem.rawValue;
|
|
2192
|
+
if (value instanceof Date) {
|
|
2193
|
+
return value.toISOString();
|
|
2194
|
+
}
|
|
2195
|
+
return value;
|
|
2196
|
+
});
|
|
2197
|
+
if (column.dataType == 'String' && this.api.predicateApi.useCaseSensitivity()) {
|
|
2198
|
+
uniqueVals = uniqBy(uniqueVals, (d) => d.displayValue.toLowerCase());
|
|
2199
|
+
}
|
|
2200
|
+
return uniqueVals.slice(0, this.api.columnFilterApi.internalApi.getFilterValuesMaxNumberOfItems(column));
|
|
2201
|
+
}
|
|
2202
|
+
getGridCellsForColumn(columnId) {
|
|
2203
|
+
let returnValues = [];
|
|
2204
|
+
this.agGridAdapter.getAgGridApi().forEachNode((rowNode) => {
|
|
2205
|
+
const gridCell = this.getGridCellFromRowNode(rowNode, columnId);
|
|
2206
|
+
if (gridCell && gridCell.rawValue != undefined) {
|
|
2207
|
+
returnValues.push(gridCell);
|
|
2208
|
+
}
|
|
2209
|
+
});
|
|
2210
|
+
return returnValues;
|
|
2211
|
+
}
|
|
2212
|
+
getRowNodesForPrimaryKeys(primaryKeyValues) {
|
|
2213
|
+
let rowNodes = [];
|
|
2214
|
+
if (this.useRowNodeLookUp) {
|
|
2215
|
+
primaryKeyValues.forEach((pkValue) => {
|
|
2216
|
+
const rowNode = this.agGridAdapter.getAgGridApi().getRowNode(pkValue);
|
|
2217
|
+
if (rowNode) {
|
|
2218
|
+
rowNodes.push(rowNode);
|
|
2219
|
+
}
|
|
2220
|
+
});
|
|
2221
|
+
}
|
|
2222
|
+
else {
|
|
2223
|
+
primaryKeyValues.forEach((pkValue) => {
|
|
2224
|
+
let foundRow = false;
|
|
2225
|
+
this.agGridAdapter.getAgGridApi().forEachNode((rowNode) => {
|
|
2226
|
+
if (!foundRow && pkValue == this.getPrimaryKeyValueFromRowNode(rowNode)) {
|
|
2227
|
+
rowNodes.push(rowNode);
|
|
2228
|
+
foundRow = true;
|
|
2229
|
+
}
|
|
2230
|
+
});
|
|
2231
|
+
});
|
|
2232
|
+
}
|
|
2233
|
+
return rowNodes;
|
|
2234
|
+
}
|
|
2235
|
+
getRowNodeByIndex(index) {
|
|
2236
|
+
return this.agGridAdapter.getAgGridApi().getDisplayedRowAtIndex(index);
|
|
2237
|
+
}
|
|
2238
|
+
getAgGridStatusPanels() {
|
|
2239
|
+
var _a, _b, _c;
|
|
2240
|
+
return (_c = (_b = (_a = this.agGridAdapter.getLiveGridOptions()) === null || _a === void 0 ? void 0 : _a.statusBar) === null || _b === void 0 ? void 0 : _b.statusPanels) !== null && _c !== void 0 ? _c : [];
|
|
2241
|
+
}
|
|
2242
|
+
setDataValue(value, column, primaryKeyValue, rowNode) {
|
|
2243
|
+
// note: because we use RowNode.setDataValue() this will cause Validation to fire
|
|
2244
|
+
// see https://www.ag-grid.com/javascript-data-grid/change-detection/#triggering-value-change-detection
|
|
2245
|
+
let newValue;
|
|
2246
|
+
let dataType = column.dataType;
|
|
2247
|
+
newValue = dataType == 'Number' ? Number(value) : value;
|
|
2248
|
+
if (dataType == undefined) {
|
|
2249
|
+
return; // no point continuing as probably a wrong column
|
|
2250
|
+
}
|
|
2251
|
+
if (rowNode) {
|
|
2252
|
+
rowNode.setDataValue(column.columnId, newValue);
|
|
2253
|
+
}
|
|
2254
|
+
else {
|
|
2255
|
+
if (this.useRowNodeLookUp) {
|
|
2256
|
+
const rowNode = this.agGridAdapter.getAgGridApi().getRowNode(primaryKeyValue);
|
|
2257
|
+
if (rowNode != null) {
|
|
2258
|
+
rowNode.setDataValue(column.columnId, newValue);
|
|
2259
|
+
}
|
|
2260
|
+
}
|
|
2261
|
+
else {
|
|
2262
|
+
let isUpdated = false;
|
|
2263
|
+
// prefer not to use this method but if we do then at least we can prevent further lookups once we find
|
|
2264
|
+
this.agGridAdapter.getAgGridApi().forEachNode((rowNode) => {
|
|
2265
|
+
if (!isUpdated) {
|
|
2266
|
+
if (primaryKeyValue == this.getPrimaryKeyValueFromRowNode(rowNode)) {
|
|
2267
|
+
rowNode.setDataValue(column.columnId, newValue);
|
|
2268
|
+
isUpdated = true;
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
});
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
isCellEditable(rowNode, column) {
|
|
2276
|
+
// it's safe to rely on the AG Grid implementation because we override the colDef.editable property, which is in this case the single source of truth
|
|
2277
|
+
return column === null || column === void 0 ? void 0 : column.isCellEditable(rowNode);
|
|
2278
|
+
}
|
|
2279
|
+
forAllRowNodesDo(func, config) {
|
|
2280
|
+
this.agGridAdapter.getAgGridApi().forEachNode((rowNode, rowIndex) => {
|
|
2281
|
+
const includeGroupRows = (config === null || config === void 0 ? void 0 : config.includeGroupRows) || !this.isGroupRowNode(rowNode);
|
|
2282
|
+
const filterFnFulfilled = !(config === null || config === void 0 ? void 0 : config.filterFn) || (config === null || config === void 0 ? void 0 : config.filterFn(rowNode));
|
|
2283
|
+
if (includeGroupRows && filterFnFulfilled) {
|
|
2284
|
+
func(rowNode, rowIndex);
|
|
2285
|
+
}
|
|
2286
|
+
});
|
|
2287
|
+
}
|
|
2288
|
+
forAllVisibleRowNodesDo(func, config) {
|
|
2289
|
+
if (this.getAgGridRowModelType() !== 'clientSide') {
|
|
2290
|
+
// only in client-side row model can we loop through filtered&sorted rows
|
|
2291
|
+
// see https://www.ag-grid.com/javascript-data-grid/accessing-data/#iterating-rows
|
|
2292
|
+
this.logger.warn('`forAllVisibleRowNodesDo()` is only supported in client-side row model. `forAllRowNodesDo` will be used instead.');
|
|
2293
|
+
return this.forAllRowNodesDo(func, config);
|
|
2294
|
+
}
|
|
2295
|
+
this.agGridAdapter.getAgGridApi().forEachNodeAfterFilterAndSort((rowNode, rowIndex) => {
|
|
2296
|
+
const includeGroupRows = (config === null || config === void 0 ? void 0 : config.includeGroupRows) || !this.isGroupRowNode(rowNode);
|
|
2297
|
+
const filterFnFulfilled = !(config === null || config === void 0 ? void 0 : config.filterFn) || (config === null || config === void 0 ? void 0 : config.filterFn(rowNode));
|
|
2298
|
+
if (includeGroupRows && filterFnFulfilled) {
|
|
2299
|
+
func(rowNode, rowIndex);
|
|
2300
|
+
}
|
|
2301
|
+
});
|
|
2302
|
+
}
|
|
2303
|
+
getAgGridRowModelType() {
|
|
2304
|
+
var _a, _b;
|
|
2305
|
+
// it seems that this can be null so we need explicitly to return "clientSide" in this case
|
|
2306
|
+
// need to check that for ServerSideRowModel it is ALWAYS returned...
|
|
2307
|
+
return (_b = (_a = this.agGridAdapter.initialGridOptions) === null || _a === void 0 ? void 0 : _a.rowModelType) !== null && _b !== void 0 ? _b : 'clientSide';
|
|
2308
|
+
}
|
|
2309
|
+
getAllRowNodes(config) {
|
|
2310
|
+
let rowNodes = [];
|
|
2311
|
+
this.forAllRowNodesDo((rowNode) => rowNodes.push(rowNode), config);
|
|
2312
|
+
return rowNodes;
|
|
2313
|
+
}
|
|
2314
|
+
getGroupRowNodes() {
|
|
2315
|
+
return this.getAllRowNodes({
|
|
2316
|
+
includeGroupRows: true,
|
|
2317
|
+
filterFn: (rowNode) => this.isGroupRowNode(rowNode),
|
|
2318
|
+
});
|
|
2319
|
+
}
|
|
2320
|
+
getRowsInViewport() {
|
|
2321
|
+
return this.agGridAdapter.getAgGridApi().getRenderedNodes();
|
|
2322
|
+
}
|
|
2323
|
+
isRowNodeVisible(rowNode) {
|
|
2324
|
+
const foundNode = this.agGridAdapter
|
|
2325
|
+
.getAgGridApi()
|
|
2326
|
+
.getRenderedNodes()
|
|
2327
|
+
.find((n) => n.id == rowNode.id);
|
|
2328
|
+
return foundNode != null;
|
|
2329
|
+
}
|
|
2330
|
+
selectNodes(rowNodes, clearSelection) {
|
|
2331
|
+
if (ArrayExtensions.IsNotNullOrEmpty(rowNodes)) {
|
|
2332
|
+
rowNodes.forEach((node) => this.selectNode(node, clearSelection));
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
deSelectNodes(rowNodes, clearSelection) {
|
|
2336
|
+
if (ArrayExtensions.IsNotNullOrEmpty(rowNodes)) {
|
|
2337
|
+
rowNodes.forEach((node) => this.deSelectNode(node, clearSelection));
|
|
2338
|
+
}
|
|
2339
|
+
}
|
|
2340
|
+
selectNode(rowNode, clearSelection) {
|
|
2341
|
+
if (!rowNode) {
|
|
2342
|
+
this.logger.error('No node to select');
|
|
2343
|
+
return;
|
|
2344
|
+
}
|
|
2345
|
+
rowNode.setSelected(true, clearSelection);
|
|
2346
|
+
}
|
|
2347
|
+
deSelectNode(rowNode, clearSelection) {
|
|
2348
|
+
if (!rowNode) {
|
|
2349
|
+
this.logger.error('No node to deselect');
|
|
2350
|
+
return;
|
|
2351
|
+
}
|
|
2352
|
+
rowNode.setSelected(false, clearSelection);
|
|
2353
|
+
}
|
|
2354
|
+
selectCells(columnIds, startNode, endNode, clearSelection) {
|
|
2355
|
+
if (clearSelection) {
|
|
2356
|
+
this.agGridAdapter.getAgGridApi().clearRangeSelection();
|
|
2357
|
+
}
|
|
2358
|
+
const cellRangeParams = {
|
|
2359
|
+
rowStartIndex: startNode.rowIndex,
|
|
2360
|
+
rowEndIndex: endNode.rowIndex,
|
|
2361
|
+
columns: columnIds,
|
|
2362
|
+
};
|
|
2363
|
+
this.agGridAdapter.getAgGridApi().addCellRange(cellRangeParams);
|
|
2364
|
+
}
|
|
2365
|
+
getAgGridColumnType(columnId) {
|
|
2366
|
+
var _a;
|
|
2367
|
+
const { type } = (_a = this.agGridAdapter.getAgGridApi().getColumnDef(columnId)) !== null && _a !== void 0 ? _a : {};
|
|
2368
|
+
return type || '';
|
|
2369
|
+
}
|
|
2370
|
+
setColumnSort(columnSorts) {
|
|
2371
|
+
if (!this.isReady) {
|
|
2372
|
+
return;
|
|
2373
|
+
}
|
|
2374
|
+
const columnSortsMap = columnSorts === null || columnSorts === void 0 ? void 0 : columnSorts.reduce((acc, columnSort, index) => {
|
|
2375
|
+
acc[columnSort.ColumnId] = Object.assign(Object.assign({}, columnSort), { SortIndex: index });
|
|
2376
|
+
return acc;
|
|
2377
|
+
}, {});
|
|
2378
|
+
const newColumnState = this.agGridAdapter
|
|
2379
|
+
.getAgGridApi()
|
|
2380
|
+
.getColumnState()
|
|
2381
|
+
.map((colState) => {
|
|
2382
|
+
const { colId } = colState;
|
|
2383
|
+
const state = Object.assign({}, colState);
|
|
2384
|
+
const colSort = columnSortsMap ? columnSortsMap[colId] : undefined;
|
|
2385
|
+
if (colSort) {
|
|
2386
|
+
state.sort = colSort.SortOrder === 'Asc' ? 'asc' : 'desc';
|
|
2387
|
+
state.sortIndex = colSort.SortIndex;
|
|
2388
|
+
}
|
|
2389
|
+
else {
|
|
2390
|
+
state.sort = null;
|
|
2391
|
+
state.sortIndex = null;
|
|
2392
|
+
}
|
|
2393
|
+
return state;
|
|
2394
|
+
});
|
|
2395
|
+
this.agGridAdapter.getAgGridApi().applyColumnState({
|
|
2396
|
+
state: newColumnState,
|
|
2397
|
+
applyOrder: true,
|
|
2398
|
+
});
|
|
2399
|
+
this.agGridAdapter.getAgGridApi().onSortChanged();
|
|
2400
|
+
}
|
|
2401
|
+
clearColumnSort() {
|
|
2402
|
+
this.setColumnSort(null);
|
|
2403
|
+
}
|
|
2404
|
+
hideColumnFilterForm() {
|
|
2405
|
+
if (this.hideFilterFormPopup) {
|
|
2406
|
+
this.hideFilterFormPopup();
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
clearColumnFiltering() {
|
|
2410
|
+
this.agGridAdapter
|
|
2411
|
+
.getAgGridApi()
|
|
2412
|
+
.getColumns()
|
|
2413
|
+
.forEach((c) => {
|
|
2414
|
+
this.agGridAdapter.getAgGridApi().destroyFilter(c);
|
|
2415
|
+
});
|
|
2416
|
+
}
|
|
2417
|
+
clearColumnFilteringForColumns(columnIds) {
|
|
2418
|
+
columnIds.forEach((c) => {
|
|
2419
|
+
const column = this.agGridAdapter
|
|
2420
|
+
.getAgGridApi()
|
|
2421
|
+
.getColumns()
|
|
2422
|
+
.find((col) => col.getColId() === c);
|
|
2423
|
+
if (column) {
|
|
2424
|
+
this.agGridAdapter.getAgGridApi().destroyFilter(column);
|
|
2425
|
+
}
|
|
2426
|
+
});
|
|
2427
|
+
}
|
|
2428
|
+
canGenerateCharts() {
|
|
2429
|
+
return (this.agGridAdapter.isModulePresent(ModuleNames.GridChartsModule) &&
|
|
2430
|
+
this.agGridAdapter.initialGridOptions.enableCharts);
|
|
2431
|
+
}
|
|
2432
|
+
canDisplaySparklines() {
|
|
2433
|
+
return this.agGridAdapter.isModulePresent(ModuleNames.SparklinesModule);
|
|
2434
|
+
}
|
|
2435
|
+
showCharts(chartsDefinitions, chartContainer) {
|
|
2436
|
+
return chartsDefinitions.map((chartDefinition) => this.showChart(chartDefinition, chartContainer));
|
|
2437
|
+
}
|
|
2438
|
+
showChart(chartDefinition, container) {
|
|
2439
|
+
if (!this.isReady) {
|
|
2440
|
+
this.logger.consoleError('Adaptable must be instantiated before calling showChart');
|
|
2441
|
+
return null;
|
|
2442
|
+
}
|
|
2443
|
+
/**
|
|
2444
|
+
* Ag-grid always creates new charts behind the sences.
|
|
2445
|
+
* So we need to update the model inside adaptable state.
|
|
2446
|
+
* This is important to be done as soon as possible so it is not considered new.
|
|
2447
|
+
*/
|
|
2448
|
+
const chartRef = this.agGridAdapter
|
|
2449
|
+
.getAgGridApi()
|
|
2450
|
+
.restoreChart(chartDefinition.Model, container);
|
|
2451
|
+
const chartModel = this.getChartModels().find((chartModel) => chartModel.chartId === chartRef.chartId);
|
|
2452
|
+
// Update the definition in state so it is not considered new
|
|
2453
|
+
this.api.chartingApi.editChartDefinition(Object.assign(Object.assign({}, chartDefinition), { Model: chartModel }));
|
|
2454
|
+
return chartRef;
|
|
2455
|
+
}
|
|
2456
|
+
updateChart(chart) {
|
|
2457
|
+
const upgradableProperties = {
|
|
2458
|
+
// Only Range charts are supported to be created at run time
|
|
2459
|
+
// the other two are pivot & cross-filter
|
|
2460
|
+
type: 'rangeChartUpdate',
|
|
2461
|
+
chartId: chart.Model.chartId,
|
|
2462
|
+
unlinkChart: Boolean(chart.Model.unlinkChart),
|
|
2463
|
+
suppressChartRanges: Boolean(chart.Model.suppressChartRanges),
|
|
2464
|
+
aggFunc: chart.Model.aggFunc,
|
|
2465
|
+
};
|
|
2466
|
+
this.agGridAdapter.getAgGridApi().updateChart(upgradableProperties);
|
|
2467
|
+
}
|
|
2468
|
+
getChartModels() {
|
|
2469
|
+
if (!this.isReady) {
|
|
2470
|
+
this.logger.consoleError('Adaptable must be instantiated before calling getChartModels');
|
|
2471
|
+
return [];
|
|
2472
|
+
}
|
|
2473
|
+
return this.agGridAdapter.getAgGridApi().getChartModels();
|
|
2474
|
+
}
|
|
2475
|
+
getRowCount() {
|
|
2476
|
+
return this.agGridAdapter.getAgGridApi().getDisplayedRowCount();
|
|
2477
|
+
}
|
|
2478
|
+
getColumnCount() {
|
|
2479
|
+
var _a, _b;
|
|
2480
|
+
return (_b = (_a = this.agGridAdapter.getAgGridApi().getColumns()) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
|
|
2481
|
+
}
|
|
2482
|
+
getVisibleColumnCount() {
|
|
2483
|
+
var _a, _b;
|
|
2484
|
+
return ((_b = (_a = this.agGridAdapter
|
|
2485
|
+
.getAgGridApi()
|
|
2486
|
+
.getColumns()) === null || _a === void 0 ? void 0 : _a.filter((c) => c.isVisible()).length) !== null && _b !== void 0 ? _b : 0);
|
|
2487
|
+
}
|
|
2488
|
+
isGridGroupable() {
|
|
2489
|
+
return !this.api.internalApi.isGridInTreeMode();
|
|
2490
|
+
}
|
|
2491
|
+
isGridGroupingActive() {
|
|
2492
|
+
let isGroupedActive = false;
|
|
2493
|
+
this.agGridAdapter.getAgGridApi().forEachNode((node) => {
|
|
2494
|
+
if (!isGroupedActive) {
|
|
2495
|
+
if (node.group) {
|
|
2496
|
+
isGroupedActive = true;
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
});
|
|
2500
|
+
return isGroupedActive;
|
|
2501
|
+
}
|
|
2502
|
+
setAgGridQuickSearch(searchText) {
|
|
2503
|
+
this.agGridAdapter.setGridOption('quickFilterText', searchText);
|
|
2504
|
+
}
|
|
2505
|
+
getAgGridCurrentThemeName() {
|
|
2506
|
+
const container = this.getAgGridContainerElement();
|
|
2507
|
+
if (container && container.classList) {
|
|
2508
|
+
// we detect the ag theme class
|
|
2509
|
+
const classList = container.classList;
|
|
2510
|
+
for (let i = 0, len = classList.length; i < len; i++) {
|
|
2511
|
+
const cls = classList[i];
|
|
2512
|
+
if (cls.indexOf('ag-theme-') === 0) {
|
|
2513
|
+
return cls;
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
return this.getAgGridLightThemeName();
|
|
2518
|
+
}
|
|
2519
|
+
getAgGridLightThemeName() {
|
|
2520
|
+
const container = this.getAgGridContainerElement();
|
|
2521
|
+
if (container && container.classList) {
|
|
2522
|
+
// we detect the ag theme class
|
|
2523
|
+
const classList = container.classList;
|
|
2524
|
+
for (let i = 0, len = classList.length; i < len; i++) {
|
|
2525
|
+
const cls = classList[i];
|
|
2526
|
+
if (cls.indexOf('ag-theme-') === 0) {
|
|
2527
|
+
// even if dark theme is included, we compute the light theme name out of it
|
|
2528
|
+
return cls.replace('-dark', '');
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
else {
|
|
2533
|
+
this.logger.warn('No AgGrid container found, defaulting to ag-theme-balham for the light theme');
|
|
2534
|
+
}
|
|
2535
|
+
this.logger.warn('No ag-theme- class found on the grid container, defaulting to ag-theme-balham');
|
|
2536
|
+
// fallback to the default light theme
|
|
2537
|
+
return 'ag-theme-balham';
|
|
2538
|
+
}
|
|
2539
|
+
applyAdaptableTheme(theme) {
|
|
2540
|
+
theme = this.ThemeService.mapOsTheme(theme);
|
|
2541
|
+
const themeName = typeof theme === 'string' ? theme : theme.Name;
|
|
2542
|
+
const isSystemTheme = this.api.themeApi.internalApi.isSystemTheme(themeName);
|
|
2543
|
+
const themeClassNamesToRemove = [];
|
|
2544
|
+
const themesToRemove = [];
|
|
2545
|
+
const allThemes = this.api.themeApi.getThemes().map((t) => {
|
|
2546
|
+
// we mutate the theme later,
|
|
2547
|
+
// and since we don't want the mutation to end up in state
|
|
2548
|
+
// we better clone it here
|
|
2549
|
+
return Object.assign({}, t);
|
|
2550
|
+
});
|
|
2551
|
+
const allThemesMap = allThemes.reduce((acc, theme) => {
|
|
2552
|
+
acc[theme.Name] = theme;
|
|
2553
|
+
return acc;
|
|
2554
|
+
}, {});
|
|
2555
|
+
const themeObject = allThemesMap[themeName];
|
|
2556
|
+
// REMOVE PREVIOUS THEME
|
|
2557
|
+
// const themePrefix = 'ab--theme-'
|
|
2558
|
+
const el = document.documentElement;
|
|
2559
|
+
el.classList.forEach((cssClassName) => {
|
|
2560
|
+
const index = cssClassName.indexOf(GeneralConstants.THEME_STYLE);
|
|
2561
|
+
if (index === 0) {
|
|
2562
|
+
themeClassNamesToRemove.push(cssClassName);
|
|
2563
|
+
const themeName = cssClassName.substring(GeneralConstants.THEME_STYLE.length);
|
|
2564
|
+
if (allThemesMap[themeName]) {
|
|
2565
|
+
themesToRemove.push(allThemesMap[themeName]);
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
});
|
|
2569
|
+
themeClassNamesToRemove.forEach((cssClassName) => el.classList.remove(cssClassName));
|
|
2570
|
+
// remove infinite table classnames
|
|
2571
|
+
themesToRemove.forEach((theme) => {
|
|
2572
|
+
el.classList.remove(`infinite-${theme.Name}`);
|
|
2573
|
+
});
|
|
2574
|
+
// VARIANT
|
|
2575
|
+
let variantTheme = '';
|
|
2576
|
+
if (!isSystemTheme && themeObject.Variant) {
|
|
2577
|
+
variantTheme = themeObject.Variant;
|
|
2578
|
+
}
|
|
2579
|
+
// APPLY NEW THEME
|
|
2580
|
+
const newTheme = allThemesMap[themeName];
|
|
2581
|
+
const getClassName = (theme) => GeneralConstants.THEME_STYLE + theme;
|
|
2582
|
+
el.classList.add(getClassName(themeName));
|
|
2583
|
+
if (variantTheme) {
|
|
2584
|
+
el.classList.add(getClassName(variantTheme));
|
|
2585
|
+
}
|
|
2586
|
+
if (isSystemTheme) {
|
|
2587
|
+
// add infinite table classname for theme
|
|
2588
|
+
el.classList.add(`infinite-${themeName}`);
|
|
2589
|
+
}
|
|
2590
|
+
else if (variantTheme) {
|
|
2591
|
+
el.classList.add(`infinite-${variantTheme}`);
|
|
2592
|
+
}
|
|
2593
|
+
// AG THEME CLASS NAME
|
|
2594
|
+
const container = this.getAgGridContainerElement();
|
|
2595
|
+
const getAgGridLightThemeName = () => this.getAgGridLightThemeName();
|
|
2596
|
+
const getAgGridDarkThemeName = () => getAgGridLightThemeName() + '-dark';
|
|
2597
|
+
if (newTheme && (isSystemTheme || variantTheme)) {
|
|
2598
|
+
if ((variantTheme || themeName) === LIGHT_THEME) {
|
|
2599
|
+
newTheme.AgGridClassName = newTheme.AgGridClassName || getAgGridLightThemeName();
|
|
2600
|
+
}
|
|
2601
|
+
if ((variantTheme || themeName) === DARK_THEME) {
|
|
2602
|
+
newTheme.AgGridClassName = newTheme.AgGridClassName || getAgGridDarkThemeName();
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
if (!newTheme.AgGridClassName) {
|
|
2606
|
+
// default AG Grid to its light theme
|
|
2607
|
+
newTheme.AgGridClassName = getAgGridLightThemeName();
|
|
2608
|
+
}
|
|
2609
|
+
if (container != null) {
|
|
2610
|
+
if (themesToRemove.length) {
|
|
2611
|
+
themesToRemove.forEach((theme) => {
|
|
2612
|
+
if (theme.AgGridClassName) {
|
|
2613
|
+
container.classList.remove(theme.AgGridClassName);
|
|
2614
|
+
}
|
|
2615
|
+
});
|
|
2616
|
+
}
|
|
2617
|
+
// also remove all AG Grid theme class names
|
|
2618
|
+
const agGridClassNamesToRemove = [];
|
|
2619
|
+
container.classList.forEach((x) => {
|
|
2620
|
+
if (x && x.indexOf('ag-theme-') === 0) {
|
|
2621
|
+
agGridClassNamesToRemove.push(x);
|
|
2622
|
+
}
|
|
2623
|
+
});
|
|
2624
|
+
agGridClassNamesToRemove.forEach((x) => container.classList.remove(x));
|
|
2625
|
+
if (newTheme && newTheme.AgGridClassName) {
|
|
2626
|
+
container.classList.add(newTheme.AgGridClassName);
|
|
2627
|
+
}
|
|
2628
|
+
container.classList.add('ab-Grid');
|
|
2629
|
+
if (this.adaptableOptions.columnFilterOptions.indicateFilteredColumns) {
|
|
2630
|
+
container.classList.add('ab-Grid--indicate-filtered-columns');
|
|
2631
|
+
}
|
|
2632
|
+
}
|
|
2633
|
+
// MAC LIKE SCROLLBARS
|
|
2634
|
+
if (this.adaptableOptions.userInterfaceOptions &&
|
|
2635
|
+
this.adaptableOptions.userInterfaceOptions.useCustomMacLikeScrollbars &&
|
|
2636
|
+
getScrollbarSize() > 0) {
|
|
2637
|
+
el.classList.add('ab--custom-mac-like-scrollbars');
|
|
2638
|
+
}
|
|
2639
|
+
else {
|
|
2640
|
+
el.classList.remove('ab--custom-mac-like-scrollbars');
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
setRowGroupColumns(columnIds) {
|
|
2644
|
+
this.agGridAdapter.getAgGridApi().setRowGroupColumns(columnIds);
|
|
2645
|
+
}
|
|
2646
|
+
getAgGridAllGridColumns() {
|
|
2647
|
+
return this.agGridAdapter.getAgGridApi().getAllGridColumns();
|
|
2648
|
+
}
|
|
2649
|
+
clearRowGroupColumns() {
|
|
2650
|
+
this.agGridAdapter
|
|
2651
|
+
.getAgGridApi()
|
|
2652
|
+
.removeRowGroupColumns(this.agGridAdapter.getAgGridApi().getRowGroupColumns());
|
|
2653
|
+
}
|
|
2654
|
+
expandAllRowGroups() {
|
|
2655
|
+
this.agGridAdapter.getAgGridApi().forEachNode((node) => {
|
|
2656
|
+
if (node.group) {
|
|
2657
|
+
node.expanded = true;
|
|
2658
|
+
}
|
|
2659
|
+
});
|
|
2660
|
+
this.agGridAdapter.getAgGridApi().onGroupExpandedOrCollapsed();
|
|
2661
|
+
}
|
|
2662
|
+
closeAllRowGroups() {
|
|
2663
|
+
this.agGridAdapter.getAgGridApi().forEachNode((node) => {
|
|
2664
|
+
if (node.group) {
|
|
2665
|
+
node.expanded = false;
|
|
2666
|
+
}
|
|
2667
|
+
});
|
|
2668
|
+
this.agGridAdapter.getAgGridApi().onGroupExpandedOrCollapsed();
|
|
2669
|
+
}
|
|
2670
|
+
expandRowGroupsForValues(columnValues) {
|
|
2671
|
+
if (ArrayExtensions.IsNotNullOrEmpty(columnValues)) {
|
|
2672
|
+
const expandedKeys = columnValues.reduce((acc, key) => {
|
|
2673
|
+
acc[key] = true;
|
|
2674
|
+
return acc;
|
|
2675
|
+
}, {});
|
|
2676
|
+
this.agGridAdapter.getAgGridApi().forEachNode((node) => {
|
|
2677
|
+
if (node.group && !node.expanded) {
|
|
2678
|
+
const nodePath = [];
|
|
2679
|
+
let current = node;
|
|
2680
|
+
while (current) {
|
|
2681
|
+
nodePath.push(current.key);
|
|
2682
|
+
current = current.parent;
|
|
2683
|
+
}
|
|
2684
|
+
const nodeKey = nodePath
|
|
2685
|
+
.filter((x) => !!x)
|
|
2686
|
+
.reverse()
|
|
2687
|
+
.join(GROUP_PATH_SEPARATOR);
|
|
2688
|
+
if (expandedKeys[nodeKey]) {
|
|
2689
|
+
node.setExpanded(true);
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
});
|
|
2693
|
+
this.agGridAdapter.getAgGridApi().onGroupExpandedOrCollapsed();
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
getExpandRowGroupsKeys() {
|
|
2697
|
+
let returnValues = [];
|
|
2698
|
+
if (this.api.layoutApi.internalApi.areExpandedRowGroupsSavedInLayouts()) {
|
|
2699
|
+
this.agGridAdapter.getAgGridApi().forEachNode((node) => {
|
|
2700
|
+
if (node.group && node.expanded) {
|
|
2701
|
+
let current = node;
|
|
2702
|
+
const path = [];
|
|
2703
|
+
while (current) {
|
|
2704
|
+
path.push(current.key);
|
|
2705
|
+
current = current.parent;
|
|
2706
|
+
}
|
|
2707
|
+
returnValues.push(path
|
|
2708
|
+
.filter((x) => !!x)
|
|
2709
|
+
.reverse()
|
|
2710
|
+
.join(GROUP_PATH_SEPARATOR));
|
|
2711
|
+
}
|
|
2712
|
+
});
|
|
2713
|
+
}
|
|
2714
|
+
return returnValues;
|
|
2715
|
+
}
|
|
2716
|
+
getAgGridColumnForColumnId(columnId) {
|
|
2717
|
+
return this.agGridAdapter.getAgGridApi().getColumn(columnId);
|
|
2718
|
+
}
|
|
2719
|
+
getMinMaxCachedValueForColumn(column, minMax) {
|
|
2720
|
+
var _a;
|
|
2721
|
+
const { columnId, dataType } = column;
|
|
2722
|
+
if (dataType !== 'Number') {
|
|
2723
|
+
return undefined;
|
|
2724
|
+
}
|
|
2725
|
+
let value = (_a = this.columnMinMaxValuesCache[columnId]) === null || _a === void 0 ? void 0 : _a[minMax];
|
|
2726
|
+
if (value !== undefined) {
|
|
2727
|
+
return value;
|
|
2728
|
+
}
|
|
2729
|
+
const distinctRawValues = this.api.gridApi.internalApi
|
|
2730
|
+
.getUnsortedDistinctRawValuesForColumn(columnId)
|
|
2731
|
+
.map((item) => item.rawValue);
|
|
2732
|
+
value = minMax === 'min' ? Math.min(...distinctRawValues) : Math.max(...distinctRawValues);
|
|
2733
|
+
this.columnMinMaxValuesCache[columnId] = Object.assign(Object.assign({}, this.columnMinMaxValuesCache[columnId]), { [minMax]: value });
|
|
2734
|
+
return value;
|
|
2735
|
+
}
|
|
2736
|
+
getAgGridRegisteredModules() {
|
|
2737
|
+
return this.agGridAdapter.getRegisteredModules();
|
|
2738
|
+
}
|
|
2739
|
+
destroy(config) {
|
|
2740
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10;
|
|
2741
|
+
if ((_a = this.agGridAdapter) === null || _a === void 0 ? void 0 : _a.getAgGridApi()) {
|
|
2742
|
+
this.agGridAdapter
|
|
2743
|
+
.getAgGridApi()
|
|
2744
|
+
.removeEventListener(Events.EVENT_FIRST_DATA_RENDERED, this.listenerFirstDataRendered);
|
|
2745
|
+
this.agGridAdapter
|
|
2746
|
+
.getAgGridApi()
|
|
2747
|
+
.removeEventListener(Events.EVENT_COLUMN_PIVOT_MODE_CHANGED, this.listenerPivotModeChanged);
|
|
2748
|
+
this.agGridAdapter
|
|
2749
|
+
.getAgGridApi()
|
|
2750
|
+
.removeEventListener(Events.EVENT_COLUMN_PIVOT_CHANGED, this.listenerPivotChanged);
|
|
2751
|
+
this.agGridAdapter
|
|
2752
|
+
.getAgGridApi()
|
|
2753
|
+
.removeEventListener(Events.EVENT_CELL_EDITING_STARTED, this.listenerCellEditingStarted);
|
|
2754
|
+
this.agGridAdapter
|
|
2755
|
+
.getAgGridApi()
|
|
2756
|
+
.removeEventListener(Events.EVENT_COLUMN_ROW_GROUP_CHANGED, this.listenerColumnRowGroupChanged);
|
|
2757
|
+
this.agGridAdapter
|
|
2758
|
+
.getAgGridApi()
|
|
2759
|
+
.removeEventListener(Events.EVENT_RANGE_SELECTION_CHANGED, this.listenerRangeSelectionChanged);
|
|
2760
|
+
this.agGridAdapter
|
|
2761
|
+
.getAgGridApi()
|
|
2762
|
+
.removeEventListener(Events.EVENT_COLUMN_RESIZED, this.listenerColumnResized);
|
|
2763
|
+
this.agGridAdapter
|
|
2764
|
+
.getAgGridApi()
|
|
2765
|
+
.removeEventListener(Events.EVENT_SORT_CHANGED, this.listenerSortChanged);
|
|
2766
|
+
this.agGridAdapter
|
|
2767
|
+
.getAgGridApi()
|
|
2768
|
+
.removeEventListener(Events.EVENT_MODEL_UPDATED, this.listenerModelUpdated);
|
|
2769
|
+
this.agGridAdapter.getAgGridApi().removeGlobalListener(this.listenerGlobalSetRowSelection);
|
|
2770
|
+
this.agGridAdapter
|
|
2771
|
+
.getAgGridApi()
|
|
2772
|
+
.removeGlobalListener(this.listenerGlobalColumnEventsThatTriggerStateChange);
|
|
2773
|
+
this.agGridAdapter
|
|
2774
|
+
.getAgGridApi()
|
|
2775
|
+
.removeGlobalListener(this.listenerGlobalColumnEventsThatTriggerAutoLayoutSave);
|
|
2776
|
+
this.agGridAdapter
|
|
2777
|
+
.getAgGridApi()
|
|
2778
|
+
.removeGlobalListener(this.listenerGlobalRowGroupEventsThatTriggerAutoLayoutSave);
|
|
2779
|
+
this.listenerFirstDataRendered = null;
|
|
2780
|
+
this.listenerPivotModeChanged = null;
|
|
2781
|
+
this.listenerPivotChanged = null;
|
|
2782
|
+
this.listenerCellEditingStarted = null;
|
|
2783
|
+
this.listenerColumnRowGroupChanged = null;
|
|
2784
|
+
this.listenerRangeSelectionChanged = null;
|
|
2785
|
+
this.listenerColumnResized = null;
|
|
2786
|
+
this.listenerGlobalSetRowSelection = null;
|
|
2787
|
+
this.listenerSortChanged = null;
|
|
2788
|
+
this.listenerModelUpdated = null;
|
|
2789
|
+
this.listenerGlobalColumnEventsThatTriggerStateChange = null;
|
|
2790
|
+
this.listenerGlobalColumnEventsThatTriggerAutoLayoutSave = null;
|
|
2791
|
+
this.listenerGlobalRowGroupEventsThatTriggerAutoLayoutSave = null;
|
|
2792
|
+
this.throttleFilterOnEditDataChange = null;
|
|
2793
|
+
this.throttleFilterOnTickingDataChange = null;
|
|
2794
|
+
const liveGridOptions = this.agGridAdapter.getLiveGridOptions();
|
|
2795
|
+
if (liveGridOptions) {
|
|
2796
|
+
this.agGridOptionsService.revertGridOptionsPropertiesToUserValue(liveGridOptions, [
|
|
2797
|
+
'aggFuncs',
|
|
2798
|
+
'allowContextMenuWithControlKey',
|
|
2799
|
+
'columnTypes',
|
|
2800
|
+
'components',
|
|
2801
|
+
'context',
|
|
2802
|
+
'dataTypeDefinitions',
|
|
2803
|
+
'doesExternalFilterPass',
|
|
2804
|
+
'excelStyles',
|
|
2805
|
+
'getContextMenuItems',
|
|
2806
|
+
'getMainMenuItems',
|
|
2807
|
+
'getRowClass',
|
|
2808
|
+
'getRowId',
|
|
2809
|
+
'getRowStyle',
|
|
2810
|
+
'gridId',
|
|
2811
|
+
'initialGroupOrderComparator',
|
|
2812
|
+
'isExternalFilterPresent',
|
|
2813
|
+
'sideBar',
|
|
2814
|
+
'statusBar',
|
|
2815
|
+
'suppressAggFuncInHeader',
|
|
2816
|
+
]);
|
|
2817
|
+
if (liveGridOptions.components) {
|
|
2818
|
+
liveGridOptions.components.AdaptableToolPanel = null;
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
if (config && config.destroyApi === false) {
|
|
2823
|
+
}
|
|
2824
|
+
else {
|
|
2825
|
+
(_b = this.agGridAdapter.getAgGridApi()) === null || _b === void 0 ? void 0 : _b.destroy();
|
|
2826
|
+
}
|
|
2827
|
+
const gridContainerElement = this.getAgGridContainerElement();
|
|
2828
|
+
if (gridContainerElement) {
|
|
2829
|
+
gridContainerElement.removeEventListener('keydown', this.agGridListenerKeydown);
|
|
2830
|
+
gridContainerElement.removeEventListener('mouseenter', this.agGridListenerMouseEnter);
|
|
2831
|
+
gridContainerElement.removeEventListener('mouseleave', this.agGridListenerMouseLeave);
|
|
2832
|
+
this.agGridListenerKeydown = null;
|
|
2833
|
+
this.agGridListenerMouseEnter = null;
|
|
2834
|
+
this.agGridListenerMouseLeave = null;
|
|
2835
|
+
}
|
|
2836
|
+
this.api.internalDestroySelf();
|
|
2837
|
+
(_c = this.agGridOptionsService) === null || _c === void 0 ? void 0 : _c.destroy();
|
|
2838
|
+
this.agGridOptionsService = null;
|
|
2839
|
+
(_d = this.agGridAdapter) === null || _d === void 0 ? void 0 : _d.destroy();
|
|
2840
|
+
this.agGridAdapter = null;
|
|
2841
|
+
(_e = this.agGridMenuAdapter) === null || _e === void 0 ? void 0 : _e.destroy();
|
|
2842
|
+
this.agGridMenuAdapter = null;
|
|
2843
|
+
(_f = this.agGridColumnAdapter) === null || _f === void 0 ? void 0 : _f.destroy();
|
|
2844
|
+
this.agGridColumnAdapter = null;
|
|
2845
|
+
this.rowListeners = null;
|
|
2846
|
+
this.emitter.destroy();
|
|
2847
|
+
this.emitter = null;
|
|
2848
|
+
this.adaptableOptions = null;
|
|
2849
|
+
this.columnMinMaxValuesCache = null;
|
|
2850
|
+
this.lifecycleState = 'preDestroyed';
|
|
2851
|
+
AdaptableAgGrid.dismissInstance(this);
|
|
2852
|
+
(_g = this.unmountLoadingScreen) === null || _g === void 0 ? void 0 : _g.call(this);
|
|
2853
|
+
this.unmountLoadingScreen = null;
|
|
2854
|
+
const abContainerElement = this.getAdaptableContainerElement();
|
|
2855
|
+
if (config && !config.unmount) {
|
|
2856
|
+
return;
|
|
2857
|
+
}
|
|
2858
|
+
if (abContainerElement != null) {
|
|
2859
|
+
(_h = this.unmountReactRoot) === null || _h === void 0 ? void 0 : _h.call(this);
|
|
2860
|
+
}
|
|
2861
|
+
this.unmountReactRoot = null;
|
|
2862
|
+
this.DANGER_USE_GETTER_adaptableContainerElement = null;
|
|
2863
|
+
this.DANGER_USE_GETTER_agGridContainerElement = null;
|
|
2864
|
+
(_j = this.adaptableStore) === null || _j === void 0 ? void 0 : _j.destroy();
|
|
2865
|
+
this.adaptableStore = null;
|
|
2866
|
+
this.adaptableOptions = null;
|
|
2867
|
+
this.adaptableStatusPanelKeys = null;
|
|
2868
|
+
(_l = (_k = this.CalculatedColumnExpressionService) === null || _k === void 0 ? void 0 : _k.destroy) === null || _l === void 0 ? void 0 : _l.call(_k);
|
|
2869
|
+
this.CalculatedColumnExpressionService = null;
|
|
2870
|
+
(_o = (_m = this.DataService) === null || _m === void 0 ? void 0 : _m.destroy) === null || _o === void 0 ? void 0 : _o.call(_m);
|
|
2871
|
+
this.DataService = null;
|
|
2872
|
+
(_q = (_p = this.EntitlementService) === null || _p === void 0 ? void 0 : _p.destroy) === null || _q === void 0 ? void 0 : _q.call(_p);
|
|
2873
|
+
this.EntitlementService = null;
|
|
2874
|
+
(_s = (_r = this.Fdc3Service) === null || _r === void 0 ? void 0 : _r.destroy) === null || _s === void 0 ? void 0 : _s.call(_r);
|
|
2875
|
+
this.Fdc3Service = null;
|
|
2876
|
+
(_u = (_t = this.ReportService) === null || _t === void 0 ? void 0 : _t.destroy) === null || _u === void 0 ? void 0 : _u.call(_t);
|
|
2877
|
+
this.ReportService = null;
|
|
2878
|
+
(_w = (_v = this.ModuleService) === null || _v === void 0 ? void 0 : _v.destroy) === null || _w === void 0 ? void 0 : _w.call(_v);
|
|
2879
|
+
this.ModuleService = null;
|
|
2880
|
+
(_y = (_x = this.ValidationService) === null || _x === void 0 ? void 0 : _x.destroy) === null || _y === void 0 ? void 0 : _y.call(_x);
|
|
2881
|
+
this.ValidationService = null;
|
|
2882
|
+
(_0 = (_z = this.QueryLanguageService) === null || _z === void 0 ? void 0 : _z.destroy) === null || _0 === void 0 ? void 0 : _0.call(_z);
|
|
2883
|
+
this.QueryLanguageService = null;
|
|
2884
|
+
(_2 = (_1 = this.AlertService) === null || _1 === void 0 ? void 0 : _1.destroy) === null || _2 === void 0 ? void 0 : _2.call(_1);
|
|
2885
|
+
this.AlertService = null;
|
|
2886
|
+
(_4 = (_3 = this.TeamSharingService) === null || _3 === void 0 ? void 0 : _3.destroy) === null || _4 === void 0 ? void 0 : _4.call(_3);
|
|
2887
|
+
this.TeamSharingService = null;
|
|
2888
|
+
(_6 = (_5 = this.RowEditService) === null || _5 === void 0 ? void 0 : _5.destroy) === null || _6 === void 0 ? void 0 : _6.call(_5);
|
|
2889
|
+
this.RowEditService = null;
|
|
2890
|
+
(_8 = (_7 = this.MetamodelService) === null || _7 === void 0 ? void 0 : _7.destroy) === null || _8 === void 0 ? void 0 : _8.call(_7);
|
|
2891
|
+
this.MetamodelService = null;
|
|
2892
|
+
(_10 = (_9 = this.LicenseService) === null || _9 === void 0 ? void 0 : _9.destroy) === null || _10 === void 0 ? void 0 : _10.call(_9);
|
|
2893
|
+
this.LicenseService = null;
|
|
2894
|
+
}
|
|
2895
|
+
canExportToExcel() {
|
|
2896
|
+
return this.agGridAdapter.isModulePresent(ModuleNames.ExcelExportModule);
|
|
2897
|
+
}
|
|
2898
|
+
exportToExcel(reportData, fileName) {
|
|
2899
|
+
const columnDefs = reportData.columns.map((column) => ({
|
|
2900
|
+
field: column.columnId,
|
|
2901
|
+
headerName: column.friendlyName,
|
|
2902
|
+
}));
|
|
2903
|
+
const NESTED_COL_SEPARATOR = '.';
|
|
2904
|
+
const nestedColumns = reportData.columns.filter((column) => column.columnId.includes(NESTED_COL_SEPARATOR));
|
|
2905
|
+
if (nestedColumns.length) {
|
|
2906
|
+
// the rowData of nested fields (containing dots) was flattened during the report data extraction and we need to un-flatten it back
|
|
2907
|
+
// ex.
|
|
2908
|
+
// current state: { field: 'outerKey.innerKey', value: 2}
|
|
2909
|
+
// original (desired) state: { field: 'outerKey.innerKey', value: {outerKey: {innerKey: 2}}}
|
|
2910
|
+
reportData.rows.forEach((rowDataEntry) => nestedColumns.forEach((nestedColumn) => {
|
|
2911
|
+
const cellExportValue = rowDataEntry[nestedColumn.columnId];
|
|
2912
|
+
let intermediaryValue = rowDataEntry;
|
|
2913
|
+
// augment the rowDataEntry with the new object
|
|
2914
|
+
nestedColumn.columnId
|
|
2915
|
+
.split(NESTED_COL_SEPARATOR)
|
|
2916
|
+
.forEach((nestedKey, index, nestedCols) => {
|
|
2917
|
+
// we reached the leaf node, so we set the cell value and break
|
|
2918
|
+
if (index === nestedCols.length - 1) {
|
|
2919
|
+
intermediaryValue[nestedKey] = cellExportValue;
|
|
2920
|
+
return;
|
|
2921
|
+
}
|
|
2922
|
+
if (intermediaryValue[nestedKey] == undefined) {
|
|
2923
|
+
intermediaryValue[nestedKey] = {};
|
|
2924
|
+
} // else means that the object already has a property with this key
|
|
2925
|
+
intermediaryValue = intermediaryValue[nestedKey];
|
|
2926
|
+
});
|
|
2927
|
+
// delete the obsolete flattened property
|
|
2928
|
+
delete rowDataEntry[nestedColumn.columnId];
|
|
2929
|
+
}));
|
|
2930
|
+
}
|
|
2931
|
+
const gridOptions = {
|
|
2932
|
+
columnDefs,
|
|
2933
|
+
rowData: reportData.rows,
|
|
2934
|
+
};
|
|
2935
|
+
let gridParams = { modules: this.getAgGridRegisteredModules() };
|
|
2936
|
+
const ephemeralGridApi = createGrid(document.createElement('div'), gridOptions, gridParams);
|
|
2937
|
+
ephemeralGridApi.exportDataAsExcel({
|
|
2938
|
+
sheetName: 'Sheet 1',
|
|
2939
|
+
fileName: fileName,
|
|
2940
|
+
});
|
|
2941
|
+
ephemeralGridApi.destroy();
|
|
2942
|
+
}
|
|
2943
|
+
exportVisualDataToExcel() {
|
|
2944
|
+
// // add adaptable style props to user defined props
|
|
2945
|
+
// this.setExcelStylesForExport();
|
|
2946
|
+
//
|
|
2947
|
+
// this.gridOptions.api.exportDataAsExcel({
|
|
2948
|
+
// sheetName: 'Sheet 1',
|
|
2949
|
+
// fileName: this.ReportService.getReportFileName(this.adaptableOptions.adaptableId, 'Excel'),
|
|
2950
|
+
// // delegate the cell value processing to Adaptable
|
|
2951
|
+
// processCellCallback: ({ node, column, value }: ProcessCellForExportParams): string => {
|
|
2952
|
+
// const columnId = column.getColId();
|
|
2953
|
+
// if (
|
|
2954
|
+
// node?.group &&
|
|
2955
|
+
// (this.api.columnApi.isAutoRowGroupColumn(columnId) ||
|
|
2956
|
+
// // we would still need to process the cell if this is a group row with an aggregated value
|
|
2957
|
+
// node?.aggData?.[columnId] == undefined)
|
|
2958
|
+
// ) {
|
|
2959
|
+
// // skip processing of row groups, this was already handled in processRowGroupCallback()
|
|
2960
|
+
// return value;
|
|
2961
|
+
// }
|
|
2962
|
+
// return this.processCellForExcelExport(node, columnId);
|
|
2963
|
+
// },
|
|
2964
|
+
// processRowGroupCallback: (params: ProcessRowGroupForExportParams): string => {
|
|
2965
|
+
// // recreating the standard AG Grid styling for row groups: 'Parent -> Child'
|
|
2966
|
+
// // additionally the values are formatted
|
|
2967
|
+
// let rowGroupNode = params.node;
|
|
2968
|
+
// const isFooterRow = rowGroupNode.footer;
|
|
2969
|
+
// const rowGroupSummary = [this.processRowGroupForExcelExport(rowGroupNode) ?? ''];
|
|
2970
|
+
// while (rowGroupNode.parent) {
|
|
2971
|
+
// rowGroupNode = rowGroupNode.parent;
|
|
2972
|
+
// const formattedParentNode = this.processRowGroupForExcelExport(rowGroupNode);
|
|
2973
|
+
// if (formattedParentNode) {
|
|
2974
|
+
// rowGroupSummary.push(formattedParentNode);
|
|
2975
|
+
// }
|
|
2976
|
+
// }
|
|
2977
|
+
//
|
|
2978
|
+
// let summary = rowGroupSummary.reverse().join(' -> ');
|
|
2979
|
+
// if (isFooterRow) {
|
|
2980
|
+
// summary = `Total: ${summary}`;
|
|
2981
|
+
// }
|
|
2982
|
+
// return summary;
|
|
2983
|
+
// },
|
|
2984
|
+
// });
|
|
2985
|
+
//
|
|
2986
|
+
// // keep only the user defined props
|
|
2987
|
+
// this.setGridOptionsProperty('excelStyles', (userExcelStyles) => {
|
|
2988
|
+
// return userExcelStyles;
|
|
2989
|
+
// });
|
|
2990
|
+
}
|
|
2991
|
+
isQuickFilterAvailable() {
|
|
2992
|
+
return this.hasFloatingFilterOnAtLeastOneColumn(this.agGridAdapter.getAgGridApi().getColumnDefs());
|
|
2993
|
+
}
|
|
2994
|
+
hasFloatingFilterOnAtLeastOneColumn(columnDefs) {
|
|
2995
|
+
let col;
|
|
2996
|
+
for (col of columnDefs) {
|
|
2997
|
+
if (col.floatingFilter) {
|
|
2998
|
+
return true;
|
|
2999
|
+
}
|
|
3000
|
+
if (col.children) {
|
|
3001
|
+
if (this.hasFloatingFilterOnAtLeastOneColumn(col.children)) {
|
|
3002
|
+
return true;
|
|
3003
|
+
}
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
3006
|
+
return false;
|
|
3007
|
+
}
|
|
3008
|
+
getChartRef(chartId) {
|
|
3009
|
+
return this.agGridAdapter.getAgGridApi().getChartRef(chartId);
|
|
3010
|
+
}
|
|
3011
|
+
setLayout(layout) {
|
|
3012
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3013
|
+
if (!layout) {
|
|
3014
|
+
layout = this.api.layoutApi.getCurrentLayout();
|
|
3015
|
+
}
|
|
3016
|
+
const perfSetLayout = this.logger.beginPerf(`setLayout(${layout.Name})`);
|
|
3017
|
+
layout.Columns = layout.Columns || [];
|
|
3018
|
+
const actionRowColumn = this.api.actionRowApi.internalApi.getColDefsForActionRowColumns()[0];
|
|
3019
|
+
if (actionRowColumn) {
|
|
3020
|
+
layout.Columns.push(actionRowColumn.colId);
|
|
3021
|
+
layout.PinnedColumnsMap = layout.PinnedColumnsMap || {};
|
|
3022
|
+
layout.PinnedColumnsMap[actionRowColumn.colId] = actionRowColumn.pinned;
|
|
3023
|
+
}
|
|
3024
|
+
const layoutColumnsMap = layout.Columns.reduce((acc, colId) => {
|
|
3025
|
+
acc[colId] = true;
|
|
3026
|
+
return acc;
|
|
3027
|
+
}, {});
|
|
3028
|
+
const columnsState = this.agGridAdapter.getAgGridApi().getColumnState();
|
|
3029
|
+
const columnsStateIndexes = {};
|
|
3030
|
+
const columnsStateMap = columnsState.reduce((acc, colState, index) => {
|
|
3031
|
+
columnsStateIndexes[colState.colId] = index;
|
|
3032
|
+
acc[colState.colId] = colState;
|
|
3033
|
+
return acc;
|
|
3034
|
+
}, {});
|
|
3035
|
+
let sortIndex = 0;
|
|
3036
|
+
const sortModelMap = ((_a = layout.ColumnSorts) !== null && _a !== void 0 ? _a : []).reduce((acc, customSort) => {
|
|
3037
|
+
const colId = customSort.ColumnId;
|
|
3038
|
+
acc[colId] = {
|
|
3039
|
+
colId,
|
|
3040
|
+
sort: customSort.SortOrder === 'Asc' ? 'asc' : 'desc',
|
|
3041
|
+
sortIndex,
|
|
3042
|
+
};
|
|
3043
|
+
sortIndex++;
|
|
3044
|
+
return acc;
|
|
3045
|
+
}, {});
|
|
3046
|
+
const groupedColumnsIndexesMap = (layout.RowGroupedColumns || []).reduce((acc, colId, index) => {
|
|
3047
|
+
acc[colId] = index;
|
|
3048
|
+
return acc;
|
|
3049
|
+
}, {});
|
|
3050
|
+
let pivotedColumnsIndexesMap = {};
|
|
3051
|
+
const aggregationFunctionsColumnsMap = layout.AggregationColumns || {};
|
|
3052
|
+
const columnsToShow = !layout.EnablePivot
|
|
3053
|
+
? layout.Columns
|
|
3054
|
+
: ((_b = this.agGridAdapter
|
|
3055
|
+
.getAgGridApi()
|
|
3056
|
+
.getPivotResultColumns()) === null || _b === void 0 ? void 0 : _b.map((column) => column.getColId())) || [];
|
|
3057
|
+
let isChanged = false;
|
|
3058
|
+
const colsToAutoSize = {};
|
|
3059
|
+
let newColumnsState = this.getSortedColumnStateForVisibleColumns(columnsToShow, columnsState);
|
|
3060
|
+
newColumnsState = newColumnsState
|
|
3061
|
+
.map((colState) => {
|
|
3062
|
+
var _a, _b, _c;
|
|
3063
|
+
const { colId } = colState;
|
|
3064
|
+
const oldColState = columnsStateMap[colId];
|
|
3065
|
+
const hide = this.api.columnApi.isAutoPivotColumn(colId)
|
|
3066
|
+
? colState.hide
|
|
3067
|
+
: !layoutColumnsMap[colId];
|
|
3068
|
+
const newColState = Object.assign(Object.assign({}, oldColState), { hide });
|
|
3069
|
+
if (layout.ColumnWidthMap && layout.ColumnWidthMap[colId] != null) {
|
|
3070
|
+
newColState.width = layout.ColumnWidthMap[colId];
|
|
3071
|
+
}
|
|
3072
|
+
else if (!hide) {
|
|
3073
|
+
// autosize only the columns which are part of the selected layout
|
|
3074
|
+
colsToAutoSize[colId] = true;
|
|
3075
|
+
}
|
|
3076
|
+
if (actionRowColumn && actionRowColumn.colId === colId) {
|
|
3077
|
+
newColState.width = actionRowColumn.width;
|
|
3078
|
+
}
|
|
3079
|
+
newColState.rowGroupIndex =
|
|
3080
|
+
groupedColumnsIndexesMap[colId] != null ? groupedColumnsIndexesMap[colId] : null;
|
|
3081
|
+
const previousRowGroup = newColState.rowGroup;
|
|
3082
|
+
newColState.rowGroup = newColState.rowGroupIndex != null;
|
|
3083
|
+
if (!previousRowGroup && newColState.rowGroup) {
|
|
3084
|
+
this.agGridColumnAdapter.triggerSetupColumnKeyCreator(colId);
|
|
3085
|
+
}
|
|
3086
|
+
const normalizePinned = (pinnedValue) => {
|
|
3087
|
+
if (typeof pinnedValue === 'string') {
|
|
3088
|
+
return pinnedValue;
|
|
3089
|
+
}
|
|
3090
|
+
return pinnedValue == true ? 'left' : !!pinnedValue;
|
|
3091
|
+
};
|
|
3092
|
+
const newValuePinned = normalizePinned(layout.PinnedColumnsMap ? layout.PinnedColumnsMap[colId] : false);
|
|
3093
|
+
const stateValuePinned = normalizePinned(newColState.pinned);
|
|
3094
|
+
if (newValuePinned !== stateValuePinned) {
|
|
3095
|
+
newColState.pinned = newValuePinned;
|
|
3096
|
+
}
|
|
3097
|
+
newColState.pivotIndex = null;
|
|
3098
|
+
if (pivotedColumnsIndexesMap[colId] != null) {
|
|
3099
|
+
newColState.pivotIndex = pivotedColumnsIndexesMap[colId];
|
|
3100
|
+
}
|
|
3101
|
+
newColState.aggFunc = null;
|
|
3102
|
+
if (aggregationFunctionsColumnsMap[colId] != null) {
|
|
3103
|
+
const colDef = this.agGridAdapter.getAgGridApi().getColumnDef(colId);
|
|
3104
|
+
let aggFunc = null;
|
|
3105
|
+
const aggFuncFromLayout = aggregationFunctionsColumnsMap[colId];
|
|
3106
|
+
const adaptableAggFunc = this.getActiveAdaptableAggFuncForCol(colId);
|
|
3107
|
+
if (aggFuncFromLayout === true) {
|
|
3108
|
+
// if we have true, it means - take the default aggFunc from colDef
|
|
3109
|
+
// NOTE: colState gives us the current aggFunc, which can be null,
|
|
3110
|
+
// while the colDef gives us the initially configured aggFunc for that column
|
|
3111
|
+
aggFunc =
|
|
3112
|
+
(_c = (_b = (_a = colState.aggFunc) !== null && _a !== void 0 ? _a : colDef === null || colDef === void 0 ? void 0 : colDef.aggFunc) !== null && _b !== void 0 ? _b :
|
|
3113
|
+
// @ts-ignore available only wth ag-Grid v27.3.x
|
|
3114
|
+
colDef === null || colDef === void 0 ? void 0 : colDef.defaultAggFunc) !== null && _c !== void 0 ? _c : 'sum';
|
|
3115
|
+
}
|
|
3116
|
+
else if (adaptableAggFunc && adaptableAggFunc.type === 'weightedAverage') {
|
|
3117
|
+
aggFunc = WEIGHTED_AVERAGE_AGG_FN_NAME;
|
|
3118
|
+
}
|
|
3119
|
+
else if (typeof aggFuncFromLayout === 'string') {
|
|
3120
|
+
aggFunc = aggFuncFromLayout;
|
|
3121
|
+
}
|
|
3122
|
+
newColState.aggFunc = aggFunc;
|
|
3123
|
+
}
|
|
3124
|
+
if (sortModelMap[colId]) {
|
|
3125
|
+
newColState.sort = sortModelMap[colId].sort;
|
|
3126
|
+
newColState.sortIndex = sortModelMap[colId].sortIndex;
|
|
3127
|
+
}
|
|
3128
|
+
else {
|
|
3129
|
+
newColState.sort = null;
|
|
3130
|
+
newColState.sortIndex = null;
|
|
3131
|
+
}
|
|
3132
|
+
isChanged = isChanged || !lodashIsEqual(newColState, oldColState);
|
|
3133
|
+
return newColState;
|
|
3134
|
+
})
|
|
3135
|
+
.filter((x) => !!x);
|
|
3136
|
+
if (!isChanged) {
|
|
3137
|
+
// order changed
|
|
3138
|
+
const toString = (c) => `${c.colId}-${c.rowGroupIndex}-${c.pivotIndex}-${c.aggFunc}-${c.pinned}-${c.width}-${c.hide}`;
|
|
3139
|
+
const oldColStateString = columnsState.map(toString).join(',');
|
|
3140
|
+
const newColStateString = newColumnsState.map(toString).join(',');
|
|
3141
|
+
isChanged = newColStateString != oldColStateString;
|
|
3142
|
+
}
|
|
3143
|
+
const pivoted = !!layout.EnablePivot;
|
|
3144
|
+
const shouldUpdatePivoted = this.agGridAdapter.getAgGridApi().isPivotMode() !== pivoted;
|
|
3145
|
+
/**
|
|
3146
|
+
* Pivot columns are secondary columns that are created on the fly and base
|
|
3147
|
+
* their configuration on the main columns by copying that configuration.
|
|
3148
|
+
* Because they copy the colDefs they might have an old copy of the colldefs.
|
|
3149
|
+
* This is why when the layout is pivoted we need to set columns before pivoting is applied.
|
|
3150
|
+
* e.g. {
|
|
3151
|
+
* field: 'pivot-1',
|
|
3152
|
+
* pivotValueColumn: {
|
|
3153
|
+
* colDef: {
|
|
3154
|
+
* field: 'price',
|
|
3155
|
+
* // this is a copy of the original column
|
|
3156
|
+
* }
|
|
3157
|
+
* }
|
|
3158
|
+
*
|
|
3159
|
+
*/
|
|
3160
|
+
if (shouldUpdatePivoted) {
|
|
3161
|
+
this.updateColumnModelAndRefreshGrid();
|
|
3162
|
+
}
|
|
3163
|
+
isChanged = isChanged || shouldUpdatePivoted;
|
|
3164
|
+
let shouldUpdateHeaders = false;
|
|
3165
|
+
// update the header name for all columns
|
|
3166
|
+
// there should be a simpler solution for this, once the Layout Management is refactored
|
|
3167
|
+
this.agGridAdapter
|
|
3168
|
+
.getAgGridApi()
|
|
3169
|
+
.getColumns()
|
|
3170
|
+
.forEach((col) => {
|
|
3171
|
+
const colDef = col.getColDef();
|
|
3172
|
+
const colId = col.getColId();
|
|
3173
|
+
const abColumn = this.api.columnApi.getColumnWithColumnId(colId);
|
|
3174
|
+
const colSetupInfo = {
|
|
3175
|
+
col,
|
|
3176
|
+
colDef,
|
|
3177
|
+
colId,
|
|
3178
|
+
abColumn,
|
|
3179
|
+
};
|
|
3180
|
+
shouldUpdateHeaders =
|
|
3181
|
+
this.agGridColumnAdapter.setupColumnHeader(colSetupInfo) || shouldUpdateHeaders;
|
|
3182
|
+
});
|
|
3183
|
+
isChanged = isChanged || shouldUpdateHeaders;
|
|
3184
|
+
if (isChanged) {
|
|
3185
|
+
// it's important we set pivot mode
|
|
3186
|
+
// before we set column state
|
|
3187
|
+
// as otherwise column order is not preserved properly when
|
|
3188
|
+
// going from pivoted to unpivoted layout
|
|
3189
|
+
if (shouldUpdatePivoted) {
|
|
3190
|
+
this.agGridAdapter.getAgGridApi().setPivotMode(pivoted);
|
|
3191
|
+
}
|
|
3192
|
+
const perfApplyColumnState = this.logger.beginPerf('applyColumnState (layout.isChanged)');
|
|
3193
|
+
this.agGridAdapter.getAgGridApi().applyColumnState({
|
|
3194
|
+
state: newColumnsState,
|
|
3195
|
+
applyOrder: true,
|
|
3196
|
+
});
|
|
3197
|
+
this.applyGroupColumnWidth(layout);
|
|
3198
|
+
perfApplyColumnState.end();
|
|
3199
|
+
this.api.gridApi.setColumnSorts(layout.ColumnSorts);
|
|
3200
|
+
this.agGridAdapter.getAgGridApi().setPivotColumns(layout.PivotColumns || []);
|
|
3201
|
+
// aggrid 25.1.0 introduced a bug such that a layout that has a grouped column, if the column has enableRowGroup: true but not rowGroup: true
|
|
3202
|
+
// the group column is not possitioned correctly at the start of the layout
|
|
3203
|
+
// see the test in layout/layout-switch/"should be able to switch from grouped to non-grouped and back"
|
|
3204
|
+
// so we figured out the following line fixes the issue
|
|
3205
|
+
// this.gridOptions.api.setColumnDefs(this.gridOptions.api.getColumnDefs()); //TODO find a solution for weighted averages - column floating filters are not showing
|
|
3206
|
+
// these updates need to be at the end, the methods are based on the grid state/col defs
|
|
3207
|
+
// the layout needs to be applied for them to work
|
|
3208
|
+
this.updateRowGroupsExpandedState(layout);
|
|
3209
|
+
}
|
|
3210
|
+
const colsToAutoSizeArray = Object.keys(colsToAutoSize);
|
|
3211
|
+
if (pivoted && ((_d = (_c = this.adaptableOptions) === null || _c === void 0 ? void 0 : _c.layoutOptions) === null || _d === void 0 ? void 0 : _d.autoSizeColumnsInPivotLayout)) {
|
|
3212
|
+
// when a pivoted layout loads, autosize all cols
|
|
3213
|
+
requestAnimationFrame(() => {
|
|
3214
|
+
this.agGridAdapter.getAgGridApi().autoSizeAllColumns();
|
|
3215
|
+
});
|
|
3216
|
+
//but if it's also the first time the grid is loading
|
|
3217
|
+
//it's not timely enough the above call, so we keep trying... I know it's ugly, we need to find a better way
|
|
3218
|
+
setTimeout(() => {
|
|
3219
|
+
this.agGridAdapter.getAgGridApi().autoSizeAllColumns();
|
|
3220
|
+
setTimeout(() => {
|
|
3221
|
+
this.agGridAdapter.getAgGridApi().autoSizeAllColumns();
|
|
3222
|
+
}, 200);
|
|
3223
|
+
}, 100);
|
|
3224
|
+
}
|
|
3225
|
+
else if (((_f = (_e = this.adaptableOptions) === null || _e === void 0 ? void 0 : _e.layoutOptions) === null || _f === void 0 ? void 0 : _f.autoSizeColumnsInLayout) &&
|
|
3226
|
+
colsToAutoSizeArray.length) {
|
|
3227
|
+
this.agGridAdapter.getAgGridApi().autoSizeColumns(colsToAutoSizeArray);
|
|
3228
|
+
}
|
|
3229
|
+
this.forPlugins((plugin) => {
|
|
3230
|
+
if (plugin.afterSetLayout) {
|
|
3231
|
+
plugin.afterSetLayout(this, layout);
|
|
3232
|
+
}
|
|
3233
|
+
});
|
|
3234
|
+
perfSetLayout.end();
|
|
3235
|
+
}
|
|
3236
|
+
getActiveAdaptableAggFuncForCol(columnId) {
|
|
3237
|
+
if (!columnId) {
|
|
3238
|
+
return null;
|
|
3239
|
+
}
|
|
3240
|
+
const currentLayout = this.api.layoutApi.getCurrentLayout();
|
|
3241
|
+
const aggregationFunctionsColumnsMap = currentLayout.AggregationColumns || {};
|
|
3242
|
+
const adaptableAggFunc = aggregationFunctionsColumnsMap[columnId];
|
|
3243
|
+
if (typeof adaptableAggFunc === 'object' &&
|
|
3244
|
+
'type' in adaptableAggFunc &&
|
|
3245
|
+
adaptableAggFunc.type === 'weightedAverage') {
|
|
3246
|
+
return adaptableAggFunc;
|
|
3247
|
+
}
|
|
3248
|
+
return null;
|
|
3249
|
+
}
|
|
3250
|
+
/**
|
|
3251
|
+
* Setting layout works by modifing the column state.
|
|
3252
|
+
* The column state is based on the current existing columns.
|
|
3253
|
+
* At this point the column groups do not exist, and the widths from layout are not applied.
|
|
3254
|
+
*
|
|
3255
|
+
* After the col sate is applied and the column groups are created we need
|
|
3256
|
+
* to apply the state again to update the widths of the group columns.
|
|
3257
|
+
*/
|
|
3258
|
+
applyGroupColumnWidth(layout) {
|
|
3259
|
+
if (!layout.RowGroupedColumns || !layout.RowGroupedColumns.length) {
|
|
3260
|
+
return;
|
|
3261
|
+
}
|
|
3262
|
+
const groupColumnWithDifferentWidths = this.agGridAdapter
|
|
3263
|
+
.getAgGridApi()
|
|
3264
|
+
.getColumnState()
|
|
3265
|
+
.reduce((acc, col) => {
|
|
3266
|
+
var _a;
|
|
3267
|
+
if (this.api.columnApi.isAutoRowGroupColumn(col.colId)) {
|
|
3268
|
+
const widthInLayout = (_a = layout.ColumnWidthMap) === null || _a === void 0 ? void 0 : _a[col.colId];
|
|
3269
|
+
if (widthInLayout && widthInLayout !== col.width) {
|
|
3270
|
+
acc.push(Object.assign(Object.assign({}, col), { width: widthInLayout }));
|
|
3271
|
+
}
|
|
3272
|
+
}
|
|
3273
|
+
return acc;
|
|
3274
|
+
}, []);
|
|
3275
|
+
if (groupColumnWithDifferentWidths.length === 0) {
|
|
3276
|
+
return;
|
|
3277
|
+
}
|
|
3278
|
+
this.agGridAdapter.getAgGridApi().applyColumnState({
|
|
3279
|
+
state: groupColumnWithDifferentWidths,
|
|
3280
|
+
});
|
|
3281
|
+
}
|
|
3282
|
+
onRowDataChanged({ rowNode, oldData, newData, }) {
|
|
3283
|
+
if (oldData == null || oldData == undefined) {
|
|
3284
|
+
return;
|
|
3285
|
+
}
|
|
3286
|
+
if (oldData == newData) {
|
|
3287
|
+
return;
|
|
3288
|
+
}
|
|
3289
|
+
const primaryKeyValue = this.getPrimaryKeyValueFromRowNode(rowNode);
|
|
3290
|
+
if (!primaryKeyValue) {
|
|
3291
|
+
return;
|
|
3292
|
+
}
|
|
3293
|
+
// rowNode = this.getRowNodeForPrimaryKey(primaryKeyValue);
|
|
3294
|
+
let cellDataChangedInfos = [];
|
|
3295
|
+
Object.keys(oldData).forEach((key) => {
|
|
3296
|
+
if (this.api.columnApi.isColumnInGrid(key)) {
|
|
3297
|
+
const oldValue = oldData[key];
|
|
3298
|
+
const newValue = newData[key];
|
|
3299
|
+
if (oldValue != newValue) {
|
|
3300
|
+
const cellDataChangedInfo = this.api.internalApi.buildDataChangedInfo({
|
|
3301
|
+
oldValue: oldValue,
|
|
3302
|
+
newValue: newValue,
|
|
3303
|
+
column: this.api.columnApi.getColumnWithColumnId(key),
|
|
3304
|
+
primaryKeyValue: primaryKeyValue,
|
|
3305
|
+
rowNode: rowNode,
|
|
3306
|
+
trigger: 'tick',
|
|
3307
|
+
});
|
|
3308
|
+
if (this.isUndoChange(cellDataChangedInfo)) {
|
|
3309
|
+
cellDataChangedInfo.trigger = 'undo';
|
|
3310
|
+
}
|
|
3311
|
+
cellDataChangedInfos.push(cellDataChangedInfo);
|
|
3312
|
+
}
|
|
3313
|
+
}
|
|
3314
|
+
});
|
|
3315
|
+
this.performPostEditChecks(cellDataChangedInfos);
|
|
3316
|
+
}
|
|
3317
|
+
onCellDataChanged({ rowNode, oldValue, newValue, colId, }) {
|
|
3318
|
+
if (oldValue == newValue) {
|
|
3319
|
+
return;
|
|
3320
|
+
}
|
|
3321
|
+
const abColumn = this.api.columnApi.getColumnWithColumnId(colId);
|
|
3322
|
+
if (!abColumn) {
|
|
3323
|
+
return;
|
|
3324
|
+
}
|
|
3325
|
+
if (this.isGroupRowNode(rowNode)) {
|
|
3326
|
+
const cellDataChangedInfo = this.api.internalApi.buildDataChangedInfo({
|
|
3327
|
+
oldValue: oldValue,
|
|
3328
|
+
newValue: newValue,
|
|
3329
|
+
column: abColumn,
|
|
3330
|
+
/**
|
|
3331
|
+
* A grouped row does not have an underling data item.
|
|
3332
|
+
* Because of this we use the rowNode.id as an identifier.
|
|
3333
|
+
*/
|
|
3334
|
+
primaryKeyValue: rowNode.id,
|
|
3335
|
+
rowNode: rowNode,
|
|
3336
|
+
trigger: 'aggChange',
|
|
3337
|
+
});
|
|
3338
|
+
this.DataService.CreateDataChangedEvent(cellDataChangedInfo);
|
|
3339
|
+
return;
|
|
3340
|
+
}
|
|
3341
|
+
const primaryKeyValue = this.getPrimaryKeyValueFromRowNode(rowNode);
|
|
3342
|
+
if (!primaryKeyValue) {
|
|
3343
|
+
return;
|
|
3344
|
+
}
|
|
3345
|
+
const cellDataChangedInfo = this.api.internalApi.buildDataChangedInfo({
|
|
3346
|
+
oldValue: oldValue,
|
|
3347
|
+
newValue: newValue,
|
|
3348
|
+
column: abColumn,
|
|
3349
|
+
primaryKeyValue: primaryKeyValue,
|
|
3350
|
+
rowNode: rowNode,
|
|
3351
|
+
trigger: 'edit',
|
|
3352
|
+
});
|
|
3353
|
+
if (this.isUndoChange(cellDataChangedInfo)) {
|
|
3354
|
+
cellDataChangedInfo.trigger = 'undo';
|
|
3355
|
+
}
|
|
3356
|
+
this.performPostEditChecks([cellDataChangedInfo]);
|
|
3357
|
+
}
|
|
3358
|
+
isUndoChange(dataChange) {
|
|
3359
|
+
// check if this is not a reverted change
|
|
3360
|
+
const undoChange = this.api.internalApi.getDataService().extractUndoChange(dataChange);
|
|
3361
|
+
return !!undoChange;
|
|
3362
|
+
}
|
|
3363
|
+
/**
|
|
3364
|
+
* There are a few things that we need to do AFTER we edit a cell and it makes sense to put them in one place
|
|
3365
|
+
*/
|
|
3366
|
+
performPostEditChecks(cellDataChangedInfos) {
|
|
3367
|
+
const firstInfo = cellDataChangedInfos[0];
|
|
3368
|
+
if (!firstInfo || !firstInfo.rowNode) {
|
|
3369
|
+
return;
|
|
3370
|
+
}
|
|
3371
|
+
cellDataChangedInfos.forEach((cellDataChangedInfo) => {
|
|
3372
|
+
if (cellDataChangedInfo.trigger === 'undo') {
|
|
3373
|
+
this.logger.info(`Undo data change: PK(${cellDataChangedInfo.primaryKeyValue}) Col(${cellDataChangedInfo.column}) RevertedValue(${cellDataChangedInfo.oldValue}) OriginalValue(${cellDataChangedInfo.newValue})`);
|
|
3374
|
+
}
|
|
3375
|
+
if (cellDataChangedInfo.trigger === 'edit' || cellDataChangedInfo.trigger === 'undo') {
|
|
3376
|
+
this.checkChangedCellCurrentlySelected(cellDataChangedInfo);
|
|
3377
|
+
this.api.freeTextColumnApi.internalApi.handleFreeTextColumnDataChange(cellDataChangedInfo);
|
|
3378
|
+
}
|
|
3379
|
+
this.DataService.CreateDataChangedEvent(cellDataChangedInfo);
|
|
3380
|
+
this.resetMinMaxCachedValueForColumn(cellDataChangedInfo.column);
|
|
3381
|
+
});
|
|
3382
|
+
this.refreshCellsBasedOnCellDataChange(cellDataChangedInfos);
|
|
3383
|
+
firstInfo.trigger == 'tick' ? this.filterOnTickingDataChange() : this.filterOnEditDataChange();
|
|
3384
|
+
}
|
|
3385
|
+
refreshCellsBasedOnCellDataChange(cellDataChangedInfos) {
|
|
3386
|
+
const [firstInfo] = cellDataChangedInfos;
|
|
3387
|
+
// if node is visible then check if need to refresh other columns / whole row if the updating column is:
|
|
3388
|
+
// 1. referenced in Format Column Styles that have Expressions (refreshing whole row if Scope is All)
|
|
3389
|
+
// 2. referenced in Format Column styles that use Column Comparisons (which might also be calculated columns)
|
|
3390
|
+
if (this.agGridAdapter.isVisibleNode(firstInfo.rowNode)) {
|
|
3391
|
+
let dataChangedScope = {
|
|
3392
|
+
wholeRow: false,
|
|
3393
|
+
columnIds: new Set(),
|
|
3394
|
+
};
|
|
3395
|
+
this.getFormatColumnExpressionStylesChanges(dataChangedScope, cellDataChangedInfos);
|
|
3396
|
+
if (dataChangedScope.wholeRow === false) {
|
|
3397
|
+
this.getFormatColumnPredicateStyleChanges(dataChangedScope, cellDataChangedInfos);
|
|
3398
|
+
}
|
|
3399
|
+
if (dataChangedScope.wholeRow) {
|
|
3400
|
+
this.redrawRow(firstInfo.rowNode);
|
|
3401
|
+
}
|
|
3402
|
+
else {
|
|
3403
|
+
this.getStyledColumnComparisonChanges(dataChangedScope, cellDataChangedInfos);
|
|
3404
|
+
if (dataChangedScope.columnIds.size > 0) {
|
|
3405
|
+
this.refreshCells([firstInfo.rowNode], Array.from(dataChangedScope.columnIds.values()), true);
|
|
3406
|
+
}
|
|
3407
|
+
}
|
|
3408
|
+
}
|
|
3409
|
+
this.refreshColumnForRelativeRangeStyledColumns(cellDataChangedInfos);
|
|
3410
|
+
}
|
|
3411
|
+
refreshColumnForRelativeRangeStyledColumns(cellDataChangedInfos) {
|
|
3412
|
+
const columnIdMap = new Set();
|
|
3413
|
+
cellDataChangedInfos.forEach((cellDataChangeInfo) => {
|
|
3414
|
+
const styledColumn = this.api.styledColumnApi.getActiveStyledColumnForColumn(cellDataChangeInfo.column);
|
|
3415
|
+
if (styledColumn &&
|
|
3416
|
+
this.api.styledColumnApi.internalApi.hasStyledColumnRelativeCellRange(styledColumn)) {
|
|
3417
|
+
columnIdMap.add(styledColumn.ColumnId);
|
|
3418
|
+
}
|
|
3419
|
+
});
|
|
3420
|
+
const columnIdsToUpdate = [...columnIdMap];
|
|
3421
|
+
if (columnIdsToUpdate.length) {
|
|
3422
|
+
this.refreshColumns(columnIdsToUpdate, true);
|
|
3423
|
+
}
|
|
3424
|
+
}
|
|
3425
|
+
getStyledColumnComparisonChanges(dataChangedScope, cellDataChangedInfos) {
|
|
3426
|
+
this.api.styledColumnApi.getStyledColumns().forEach((sc) => {
|
|
3427
|
+
let columnComparison = this.api.styledColumnApi.internalApi.getColumnComparisonForStyledColumn(sc);
|
|
3428
|
+
if (columnComparison) {
|
|
3429
|
+
let affectedColumnIds = this.api.styledColumnApi.internalApi.getColumnIdsFromColumnComparison(columnComparison);
|
|
3430
|
+
if (ArrayExtensions.IsNotNullOrEmpty(affectedColumnIds)) {
|
|
3431
|
+
cellDataChangedInfos.forEach((cellDataChangedInfo) => {
|
|
3432
|
+
if (affectedColumnIds.includes(cellDataChangedInfo.column.columnId)) {
|
|
3433
|
+
dataChangedScope.columnIds.add(sc.ColumnId);
|
|
3434
|
+
}
|
|
3435
|
+
});
|
|
3436
|
+
}
|
|
3437
|
+
}
|
|
3438
|
+
});
|
|
3439
|
+
}
|
|
3440
|
+
getFormatColumnPredicateStyleChanges(dataChangedScope, cellDataChangedInfos) {
|
|
3441
|
+
cellDataChangedInfos.forEach((cellDataChangeInfo) => {
|
|
3442
|
+
const dependentColumns = this.api.formatColumnApi.internalApi.getFormatColumnColumnsDependentOnColumnChange(cellDataChangeInfo.column);
|
|
3443
|
+
for (let colId of dependentColumns) {
|
|
3444
|
+
dataChangedScope.columnIds.add(colId);
|
|
3445
|
+
}
|
|
3446
|
+
});
|
|
3447
|
+
}
|
|
3448
|
+
getFormatColumnExpressionStylesChanges(dataChangedScope, cellDataChangedInfos) {
|
|
3449
|
+
const formatColumnsWithExpression = [];
|
|
3450
|
+
formatColumnsWithExpression.push(...this.api.formatColumnApi.internalApi.getFormatColumnsWithExpression());
|
|
3451
|
+
if (ArrayExtensions.IsNullOrEmpty(formatColumnsWithExpression)) {
|
|
3452
|
+
return;
|
|
3453
|
+
}
|
|
3454
|
+
cellDataChangedInfos.forEach((cellDataChangedInfo) => {
|
|
3455
|
+
if (!dataChangedScope.wholeRow) {
|
|
3456
|
+
formatColumnsWithExpression.forEach((styleModule) => {
|
|
3457
|
+
if (!dataChangedScope.wholeRow) {
|
|
3458
|
+
const columnIds = this.api.expressionApi.getColumnsFromExpression(styleModule.Rule.BooleanExpression);
|
|
3459
|
+
if (columnIds.includes(cellDataChangedInfo.column.columnId)) {
|
|
3460
|
+
if (this.api.scopeApi.scopeIsAll(styleModule.Scope)) {
|
|
3461
|
+
dataChangedScope.wholeRow = true;
|
|
3462
|
+
return;
|
|
3463
|
+
}
|
|
3464
|
+
else {
|
|
3465
|
+
this.api.scopeApi
|
|
3466
|
+
.getColumnsForScope(styleModule.Scope)
|
|
3467
|
+
.map((c) => c.columnId)
|
|
3468
|
+
.forEach((colId) => {
|
|
3469
|
+
dataChangedScope.columnIds.add(colId);
|
|
3470
|
+
});
|
|
3471
|
+
}
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
});
|
|
3475
|
+
}
|
|
3476
|
+
});
|
|
3477
|
+
}
|
|
3478
|
+
checkChangedCellCurrentlySelected(cellDataChangedInfo) {
|
|
3479
|
+
let selectedCellInfo = this.api.gridApi.getSelectedCellInfo();
|
|
3480
|
+
if (selectedCellInfo && ArrayExtensions.IsNotNullOrEmpty(selectedCellInfo.gridCells)) {
|
|
3481
|
+
let matchingCell = selectedCellInfo.gridCells.find((gc) => gc.primaryKeyValue == cellDataChangedInfo.primaryKeyValue &&
|
|
3482
|
+
gc.column == cellDataChangedInfo.column);
|
|
3483
|
+
if (matchingCell) {
|
|
3484
|
+
this.refreshSelectedCellsState();
|
|
3485
|
+
}
|
|
3486
|
+
}
|
|
3487
|
+
let selectedRowInfo = this.api.gridApi.getSelectedRowInfo();
|
|
3488
|
+
if (selectedRowInfo && ArrayExtensions.IsNotNullOrEmpty(selectedRowInfo.gridRows)) {
|
|
3489
|
+
let matchingRow = selectedRowInfo.gridRows.find((gr) => gr.primaryKeyValue == cellDataChangedInfo.primaryKeyValue);
|
|
3490
|
+
if (matchingRow) {
|
|
3491
|
+
this.refreshSelectedRowsState();
|
|
3492
|
+
}
|
|
3493
|
+
}
|
|
3494
|
+
}
|
|
3495
|
+
resetMinMaxCachedValueForColumn(column) {
|
|
3496
|
+
if (!column) {
|
|
3497
|
+
this.columnMinMaxValuesCache[column.columnId] = {};
|
|
3498
|
+
}
|
|
3499
|
+
if (this.columnMinMaxValuesCache[column.columnId]) {
|
|
3500
|
+
this.columnMinMaxValuesCache[column.columnId] = undefined;
|
|
3501
|
+
}
|
|
3502
|
+
}
|
|
3503
|
+
filterOnTickingDataChange() {
|
|
3504
|
+
var _a;
|
|
3505
|
+
if (this.adaptableOptions.columnFilterOptions.filterActionOnExternalDataChange.applyFilter ==
|
|
3506
|
+
FilterOnDataChangeOptions.Always) {
|
|
3507
|
+
(_a = this.agGridAdapter.getAgGridApi()) === null || _a === void 0 ? void 0 : _a.onFilterChanged();
|
|
3508
|
+
}
|
|
3509
|
+
else if (this.adaptableOptions.columnFilterOptions.filterActionOnExternalDataChange.applyFilter ==
|
|
3510
|
+
FilterOnDataChangeOptions.Throttle) {
|
|
3511
|
+
this.throttleFilterOnTickingDataChange();
|
|
3512
|
+
}
|
|
3513
|
+
}
|
|
3514
|
+
filterOnEditDataChange() {
|
|
3515
|
+
var _a;
|
|
3516
|
+
if (this.adaptableOptions.columnFilterOptions.filterActionOnUserDataChange.applyFilter ==
|
|
3517
|
+
FilterOnDataChangeOptions.Always) {
|
|
3518
|
+
(_a = this.agGridAdapter.getAgGridApi()) === null || _a === void 0 ? void 0 : _a.onFilterChanged();
|
|
3519
|
+
}
|
|
3520
|
+
else if (this.adaptableOptions.columnFilterOptions.filterActionOnUserDataChange.applyFilter ==
|
|
3521
|
+
FilterOnDataChangeOptions.Throttle) {
|
|
3522
|
+
this.throttleFilterOnEditDataChange();
|
|
3523
|
+
}
|
|
3524
|
+
}
|
|
3525
|
+
shouldCreateDefaultLayout(adaptableState, adaptableOptions) {
|
|
3526
|
+
var _a, _b, _c;
|
|
3527
|
+
const layoutState = adaptableState.Layout || {};
|
|
3528
|
+
if (((_a = adaptableOptions.layoutOptions) === null || _a === void 0 ? void 0 : _a.createDefaultLayout) &&
|
|
3529
|
+
!((_b = layoutState.Layouts) === null || _b === void 0 ? void 0 : _b.find((layout) => layout.Name === DEFAULT_LAYOUT))) {
|
|
3530
|
+
return true;
|
|
3531
|
+
}
|
|
3532
|
+
return !((_c = layoutState.Layouts) === null || _c === void 0 ? void 0 : _c.length);
|
|
3533
|
+
}
|
|
3534
|
+
createDefaultLayout(state, gridOptionsColDefs) {
|
|
3535
|
+
var _a, _b;
|
|
3536
|
+
const allColumnDefs = this.agGridAdapter.getFlattenedColDefs(gridOptionsColDefs);
|
|
3537
|
+
const defaultLayout = ObjectFactory.CreateEmptyLayout({
|
|
3538
|
+
Name: DEFAULT_LAYOUT,
|
|
3539
|
+
Columns: allColumnDefs.map((c) => c.colId),
|
|
3540
|
+
AggregationColumns: allColumnDefs.reduce((acc, col) => {
|
|
3541
|
+
if (typeof col.aggFunc === 'string') {
|
|
3542
|
+
acc[col.colId] = col.aggFunc;
|
|
3543
|
+
}
|
|
3544
|
+
return acc;
|
|
3545
|
+
}, {}),
|
|
3546
|
+
PinnedColumnsMap: allColumnDefs.reduce((acc, col) => {
|
|
3547
|
+
const pinned = col.pinned;
|
|
3548
|
+
if (pinned) {
|
|
3549
|
+
acc[col.colId] = pinned === true ? 'left' : pinned;
|
|
3550
|
+
}
|
|
3551
|
+
return acc;
|
|
3552
|
+
}, {}),
|
|
3553
|
+
RowGroupedColumns: allColumnDefs.reduce((acc, col) => {
|
|
3554
|
+
if (col.rowGroup) {
|
|
3555
|
+
acc.push(col.colId);
|
|
3556
|
+
}
|
|
3557
|
+
return acc;
|
|
3558
|
+
}, []),
|
|
3559
|
+
});
|
|
3560
|
+
// ADD special columns
|
|
3561
|
+
const calculatedColumns = ((_a = state.CalculatedColumn) === null || _a === void 0 ? void 0 : _a.CalculatedColumns) || [];
|
|
3562
|
+
if (calculatedColumns.length) {
|
|
3563
|
+
defaultLayout.Columns.push(...calculatedColumns.map((c) => c.ColumnId));
|
|
3564
|
+
}
|
|
3565
|
+
const freeTextColumns = ((_b = state.FreeTextColumn) === null || _b === void 0 ? void 0 : _b.FreeTextColumns) || [];
|
|
3566
|
+
if (freeTextColumns.length) {
|
|
3567
|
+
defaultLayout.Columns.push(...freeTextColumns.map((c) => c.ColumnId));
|
|
3568
|
+
}
|
|
3569
|
+
return defaultLayout;
|
|
3570
|
+
}
|
|
3571
|
+
/*
|
|
3572
|
+
* This is the opposite of setLayout
|
|
3573
|
+
*/
|
|
3574
|
+
updateLayoutFromGrid() {
|
|
3575
|
+
var _a, _b;
|
|
3576
|
+
const currentLayout = this.api.layoutApi.getCurrentLayout();
|
|
3577
|
+
if (currentLayout.IsReadOnly) {
|
|
3578
|
+
// reaply the layout so the grid is reverted
|
|
3579
|
+
this.setLayout();
|
|
3580
|
+
return;
|
|
3581
|
+
}
|
|
3582
|
+
const layout = Object.assign({}, currentLayout);
|
|
3583
|
+
let columnOrder = [];
|
|
3584
|
+
const columnFlexes = {};
|
|
3585
|
+
const pinnedColumns = {};
|
|
3586
|
+
const columnSorts = [];
|
|
3587
|
+
const columnState = this.agGridAdapter.getAgGridApi().getColumnState();
|
|
3588
|
+
let groupedColumns = [...new Array(columnState.length)];
|
|
3589
|
+
let pivotedColumns = [...new Array(columnState.length)];
|
|
3590
|
+
const pivotColumns = [];
|
|
3591
|
+
const aggregatedColumns = {};
|
|
3592
|
+
const columnWidths = columnState.reduce((acc, colState) => {
|
|
3593
|
+
const { colId } = colState;
|
|
3594
|
+
if (colState.sort && colState.sortIndex != null) {
|
|
3595
|
+
columnSorts.push({
|
|
3596
|
+
ColumnId: colId,
|
|
3597
|
+
SortOrder: colState.sort === 'asc' ? 'Asc' : 'Desc',
|
|
3598
|
+
SortIndex: colState.sortIndex,
|
|
3599
|
+
});
|
|
3600
|
+
}
|
|
3601
|
+
if (colState.width != null) {
|
|
3602
|
+
acc[colId] = colState.width;
|
|
3603
|
+
}
|
|
3604
|
+
if (colState.flex != null) {
|
|
3605
|
+
columnFlexes[colId] = colState.flex;
|
|
3606
|
+
}
|
|
3607
|
+
if (colState.pinned === 'left') {
|
|
3608
|
+
pinnedColumns[colId] = 'left';
|
|
3609
|
+
}
|
|
3610
|
+
if (colState.pinned === 'right') {
|
|
3611
|
+
pinnedColumns[colId] = 'right';
|
|
3612
|
+
}
|
|
3613
|
+
if (!colState.hide) {
|
|
3614
|
+
columnOrder.push(colId);
|
|
3615
|
+
}
|
|
3616
|
+
if (colState.rowGroupIndex != null) {
|
|
3617
|
+
groupedColumns[colState.rowGroupIndex] = colId;
|
|
3618
|
+
}
|
|
3619
|
+
if (colState.pivotIndex != null) {
|
|
3620
|
+
pivotedColumns[colState.pivotIndex] = colId;
|
|
3621
|
+
}
|
|
3622
|
+
if (colState.aggFunc && typeof colState.aggFunc === 'string') {
|
|
3623
|
+
aggregatedColumns[colId] = colState.aggFunc;
|
|
3624
|
+
}
|
|
3625
|
+
return acc;
|
|
3626
|
+
}, {});
|
|
3627
|
+
columnSorts.sort((a, b) => a.SortIndex - b.SortIndex);
|
|
3628
|
+
this.agGridAdapter
|
|
3629
|
+
.getAgGridApi()
|
|
3630
|
+
.getPivotColumns()
|
|
3631
|
+
.forEach((col) => {
|
|
3632
|
+
pivotColumns.push(col.getColId());
|
|
3633
|
+
});
|
|
3634
|
+
groupedColumns = groupedColumns.filter((x) => !!x);
|
|
3635
|
+
pivotedColumns = pivotedColumns.filter((x) => !!x);
|
|
3636
|
+
if ((_b = (_a = this.adaptableOptions) === null || _a === void 0 ? void 0 : _a.groupingOptions) === null || _b === void 0 ? void 0 : _b.restoreUngroupedColumns) {
|
|
3637
|
+
columnOrder = this.restoreUnGroupColumnOrder({
|
|
3638
|
+
columnOrder,
|
|
3639
|
+
newGroupColumns: groupedColumns,
|
|
3640
|
+
});
|
|
3641
|
+
}
|
|
3642
|
+
layout.ColumnWidthMap = columnWidths;
|
|
3643
|
+
// layout.ColumnFlexMap = columnFlexes;
|
|
3644
|
+
layout.PinnedColumnsMap = pinnedColumns;
|
|
3645
|
+
layout.Columns = columnOrder;
|
|
3646
|
+
layout.ColumnSorts = columnSorts;
|
|
3647
|
+
layout.RowGroupedColumns = groupedColumns;
|
|
3648
|
+
if (Object.keys(aggregatedColumns).length) {
|
|
3649
|
+
// AG Grid aggregations are not 1-1 with adaptable column-aggregations
|
|
3650
|
+
layout.AggregationColumns = this.mapAggregationColumnsFromGrid(aggregatedColumns, currentLayout);
|
|
3651
|
+
}
|
|
3652
|
+
else {
|
|
3653
|
+
layout.AggregationColumns = {};
|
|
3654
|
+
}
|
|
3655
|
+
layout.EnablePivot = this.agGridAdapter.getAgGridApi().isPivotMode();
|
|
3656
|
+
layout.PivotColumns = pivotColumns;
|
|
3657
|
+
if (
|
|
3658
|
+
// check first row node for presence of data without iterating over whole grid
|
|
3659
|
+
this.api.layoutApi.internalApi.areExpandedRowGroupsSavedInLayouts() &&
|
|
3660
|
+
this.api.gridApi.getFirstDisplayedRowNode()) {
|
|
3661
|
+
layout.ExpandedRowGroupValues = this.getExpandRowGroupsKeys();
|
|
3662
|
+
}
|
|
3663
|
+
const previousVisibleColumns = currentLayout.Columns;
|
|
3664
|
+
const newVisibleColumns = layout.Columns;
|
|
3665
|
+
// check if all new columns were previously visible
|
|
3666
|
+
const someColumnsAreNew = newVisibleColumns.some((colId) => !previousVisibleColumns.includes(colId));
|
|
3667
|
+
if (someColumnsAreNew) {
|
|
3668
|
+
this.updateColumnModelAndRefreshGrid();
|
|
3669
|
+
}
|
|
3670
|
+
this.persistLayout(layout);
|
|
3671
|
+
}
|
|
3672
|
+
persistLayout(layout) {
|
|
3673
|
+
if (this.api.layoutApi.shouldAutoSaveLayouts()) {
|
|
3674
|
+
this.api.layoutApi.createOrUpdateLayout(layout);
|
|
3675
|
+
}
|
|
3676
|
+
else {
|
|
3677
|
+
this.api.layoutApi.internalApi.updateCurrentDraftLayout(layout);
|
|
3678
|
+
}
|
|
3679
|
+
}
|
|
3680
|
+
/**
|
|
3681
|
+
* When reading the state from the grid, we have to make sure 'avg' is not overriden with the 'avg' string.
|
|
3682
|
+
*/
|
|
3683
|
+
mapAggregationColumnsFromGrid(aggFuncFromGrid, currentLayout) {
|
|
3684
|
+
return Object.entries(aggFuncFromGrid).reduce((acc, [colId, agg]) => {
|
|
3685
|
+
const adaptableAggFunc = this.getActiveAdaptableAggFuncForCol(colId);
|
|
3686
|
+
if ((adaptableAggFunc === null || adaptableAggFunc === void 0 ? void 0 : adaptableAggFunc.type) === 'weightedAverage' && agg === WEIGHTED_AVERAGE_AGG_FN_NAME) {
|
|
3687
|
+
// do not override the agg func
|
|
3688
|
+
acc[colId] = currentLayout.AggregationColumns[colId];
|
|
3689
|
+
}
|
|
3690
|
+
else {
|
|
3691
|
+
acc[colId] = agg;
|
|
3692
|
+
}
|
|
3693
|
+
return acc;
|
|
3694
|
+
}, {});
|
|
3695
|
+
}
|
|
3696
|
+
persistColumnIndexBeforeGrouping(params) {
|
|
3697
|
+
const layout = this.api.layoutApi.getCurrentLayout();
|
|
3698
|
+
const columnGroupsInLayout = layout.RowGroupedColumns;
|
|
3699
|
+
const columnGroupsInGrid = params.columns.map((col) => col.getColId());
|
|
3700
|
+
// what is new
|
|
3701
|
+
const newGroups = columnGroupsInGrid.filter((colId) => !columnGroupsInLayout.includes(colId));
|
|
3702
|
+
newGroups.forEach((colId) => {
|
|
3703
|
+
const columnIndex = layout.Columns.filter((colId) => !(this.api.columnApi.isAutoRowGroupColumn(colId) ||
|
|
3704
|
+
this.api.columnApi.isAutoPivotColumn(colId))).findIndex((columnIdInLayout) => columnIdInLayout === colId);
|
|
3705
|
+
// user may group after a column not in layout
|
|
3706
|
+
if (columnIndex !== -1) {
|
|
3707
|
+
this.api.internalApi.persistPreviousGroupedColumnsIndex(layout.Uuid, colId, columnIndex);
|
|
3708
|
+
}
|
|
3709
|
+
});
|
|
3710
|
+
}
|
|
3711
|
+
/**
|
|
3712
|
+
* Restores the order previous grouping order.
|
|
3713
|
+
*/
|
|
3714
|
+
restoreUnGroupColumnOrder({ newGroupColumns, columnOrder, }) {
|
|
3715
|
+
var _a;
|
|
3716
|
+
const newColumnOrder = [...columnOrder];
|
|
3717
|
+
const currentLayout = this.api.layoutApi.getCurrentLayout();
|
|
3718
|
+
const previousGroupedColumnsIndex = this.api.internalApi.getPreviousGroupedColumnsIndex(currentLayout.Uuid);
|
|
3719
|
+
const isUnGroup = newGroupColumns.length < ((_a = currentLayout === null || currentLayout === void 0 ? void 0 : currentLayout.RowGroupedColumns) === null || _a === void 0 ? void 0 : _a.length);
|
|
3720
|
+
if (!isUnGroup) {
|
|
3721
|
+
return columnOrder;
|
|
3722
|
+
}
|
|
3723
|
+
if (!previousGroupedColumnsIndex) {
|
|
3724
|
+
return columnOrder;
|
|
3725
|
+
}
|
|
3726
|
+
for (let [colId, previousIndex] of Object.entries(previousGroupedColumnsIndex)) {
|
|
3727
|
+
const isStillGrouped = newGroupColumns.includes(colId);
|
|
3728
|
+
const isAlreadyInGrid = currentLayout.Columns.includes(colId); // was not just added by ungrouping
|
|
3729
|
+
if (isStillGrouped) {
|
|
3730
|
+
continue;
|
|
3731
|
+
}
|
|
3732
|
+
if (isAlreadyInGrid) {
|
|
3733
|
+
// no longer grouped, but already in grid, this means it was already in grid before ungrouping
|
|
3734
|
+
// in this case the state can be cleared
|
|
3735
|
+
this.api.internalApi.persistPreviousGroupedColumnsIndex(currentLayout.Uuid, colId, null);
|
|
3736
|
+
continue;
|
|
3737
|
+
}
|
|
3738
|
+
// need to ajust index based if grouped
|
|
3739
|
+
const numberOfGroupedColumns = newColumnOrder.filter((colId) => this.api.columnApi.isAutoRowGroupColumn(colId)).length;
|
|
3740
|
+
const adjustedPreviousIndex = previousIndex + numberOfGroupedColumns;
|
|
3741
|
+
const indexInGrid = newColumnOrder.indexOf(colId);
|
|
3742
|
+
const hasDifferentPositionAsPreviousLayout = adjustedPreviousIndex !== null && // if null, the reorder was already applied
|
|
3743
|
+
indexInGrid > 0 && // needs to be in grid
|
|
3744
|
+
adjustedPreviousIndex !== indexInGrid;
|
|
3745
|
+
const isPreviousPositionInRange = adjustedPreviousIndex < newColumnOrder.length;
|
|
3746
|
+
if (hasDifferentPositionAsPreviousLayout && isPreviousPositionInRange) {
|
|
3747
|
+
newColumnOrder.splice(indexInGrid, 1);
|
|
3748
|
+
newColumnOrder.splice(adjustedPreviousIndex, 0, colId);
|
|
3749
|
+
}
|
|
3750
|
+
this.api.internalApi.persistPreviousGroupedColumnsIndex(currentLayout.Uuid, colId, null);
|
|
3751
|
+
}
|
|
3752
|
+
return newColumnOrder;
|
|
3753
|
+
}
|
|
3754
|
+
onSortChanged() {
|
|
3755
|
+
const columnSorts = this.getColumnSorts();
|
|
3756
|
+
this.api.gridApi.setColumnSorts(columnSorts);
|
|
3757
|
+
this._emit('SortChanged', columnSorts);
|
|
3758
|
+
}
|
|
3759
|
+
getColumnSorts() {
|
|
3760
|
+
const columnSorts = [];
|
|
3761
|
+
const columnState = this.agGridAdapter.getAgGridApi().getColumnState();
|
|
3762
|
+
columnState.forEach((colState) => {
|
|
3763
|
+
const { colId } = colState;
|
|
3764
|
+
if (colState.sort && colState.sortIndex != null) {
|
|
3765
|
+
columnSorts.push({
|
|
3766
|
+
ColumnId: colId,
|
|
3767
|
+
SortOrder: colState.sort === 'asc' ? 'Asc' : 'Desc',
|
|
3768
|
+
SortIndex: colState.sortIndex,
|
|
3769
|
+
});
|
|
3770
|
+
}
|
|
3771
|
+
});
|
|
3772
|
+
columnSorts.sort((a, b) => a.SortIndex - b.SortIndex);
|
|
3773
|
+
return columnSorts.map((c) => {
|
|
3774
|
+
return {
|
|
3775
|
+
ColumnId: c.ColumnId,
|
|
3776
|
+
SortOrder: c.SortOrder,
|
|
3777
|
+
};
|
|
3778
|
+
});
|
|
3779
|
+
}
|
|
3780
|
+
}
|