slickgrid-react 2.6.4 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/.eslintrc +0 -3
  2. package/CHANGELOG.md +9 -0
  3. package/README.md +2 -2
  4. package/dist/cjs/components/slickgrid-react.d.ts +207 -207
  5. package/dist/cjs/components/slickgrid-react.js +1338 -1337
  6. package/dist/cjs/components/slickgrid-react.js.map +1 -1
  7. package/dist/cjs/components/slickgridEventAggregator.d.ts +10 -10
  8. package/dist/cjs/components/slickgridEventAggregator.js +11 -11
  9. package/dist/cjs/components/slickgridReactProps.d.ts +290 -288
  10. package/dist/cjs/components/slickgridReactProps.js +2 -2
  11. package/dist/cjs/constants.d.ts +23 -23
  12. package/dist/cjs/constants.js +90 -90
  13. package/dist/cjs/constants.js.map +1 -1
  14. package/dist/cjs/global-grid-options.d.ts +5 -5
  15. package/dist/cjs/global-grid-options.js +266 -266
  16. package/dist/cjs/index.d.ts +8 -8
  17. package/dist/cjs/index.js +30 -30
  18. package/dist/cjs/models/gridOption.interface.d.ts +6 -6
  19. package/dist/cjs/models/gridOption.interface.js +2 -2
  20. package/dist/cjs/models/index.d.ts +4 -4
  21. package/dist/cjs/models/index.js +20 -20
  22. package/dist/cjs/models/reactComponentOutput.interface.d.ts +6 -6
  23. package/dist/cjs/models/reactComponentOutput.interface.js +2 -2
  24. package/dist/cjs/models/slickGrid.interface.d.ts +6 -6
  25. package/dist/cjs/models/slickGrid.interface.js +2 -2
  26. package/dist/cjs/models/slickgridReactInstance.interface.d.ts +36 -36
  27. package/dist/cjs/models/slickgridReactInstance.interface.js +2 -2
  28. package/dist/cjs/services/container.service.d.ts +6 -6
  29. package/dist/cjs/services/container.service.js +15 -15
  30. package/dist/cjs/services/index.d.ts +4 -4
  31. package/dist/cjs/services/index.js +20 -20
  32. package/dist/cjs/services/reactUtil.service.d.ts +5 -5
  33. package/dist/cjs/services/reactUtil.service.js +27 -27
  34. package/dist/cjs/services/singletons.d.ts +6 -6
  35. package/dist/cjs/services/singletons.js +9 -9
  36. package/dist/cjs/services/translater.service.d.ts +25 -25
  37. package/dist/cjs/services/translater.service.js +40 -40
  38. package/dist/cjs/services/utilities.d.ts +7 -7
  39. package/dist/cjs/services/utilities.js +20 -20
  40. package/dist/cjs/slickgrid-config.d.ts +5 -5
  41. package/dist/cjs/slickgrid-config.js +10 -10
  42. package/dist/esm/components/slickgrid-react.d.ts +207 -207
  43. package/dist/esm/components/slickgrid-react.js +1317 -1315
  44. package/dist/esm/components/slickgrid-react.js.map +1 -1
  45. package/dist/esm/components/slickgridEventAggregator.d.ts +10 -10
  46. package/dist/esm/components/slickgridEventAggregator.js +7 -7
  47. package/dist/esm/components/slickgridReactProps.d.ts +290 -288
  48. package/dist/esm/components/slickgridReactProps.js +1 -1
  49. package/dist/esm/constants.d.ts +23 -23
  50. package/dist/esm/constants.js +87 -86
  51. package/dist/esm/constants.js.map +1 -1
  52. package/dist/esm/global-grid-options.d.ts +5 -5
  53. package/dist/esm/global-grid-options.js +263 -263
  54. package/dist/esm/index.d.ts +8 -8
  55. package/dist/esm/index.js +8 -8
  56. package/dist/esm/models/gridOption.interface.d.ts +6 -6
  57. package/dist/esm/models/gridOption.interface.js +1 -1
  58. package/dist/esm/models/index.d.ts +4 -4
  59. package/dist/esm/models/index.js +4 -4
  60. package/dist/esm/models/reactComponentOutput.interface.d.ts +6 -6
  61. package/dist/esm/models/reactComponentOutput.interface.js +1 -1
  62. package/dist/esm/models/slickGrid.interface.d.ts +6 -6
  63. package/dist/esm/models/slickGrid.interface.js +1 -1
  64. package/dist/esm/models/slickgridReactInstance.interface.d.ts +36 -36
  65. package/dist/esm/models/slickgridReactInstance.interface.js +1 -1
  66. package/dist/esm/services/container.service.d.ts +6 -6
  67. package/dist/esm/services/container.service.js +11 -11
  68. package/dist/esm/services/index.d.ts +4 -4
  69. package/dist/esm/services/index.js +4 -4
  70. package/dist/esm/services/reactUtil.service.d.ts +5 -5
  71. package/dist/esm/services/reactUtil.service.js +20 -20
  72. package/dist/esm/services/singletons.d.ts +6 -6
  73. package/dist/esm/services/singletons.js +6 -6
  74. package/dist/esm/services/translater.service.d.ts +25 -25
  75. package/dist/esm/services/translater.service.js +33 -33
  76. package/dist/esm/services/utilities.d.ts +7 -7
  77. package/dist/esm/services/utilities.js +16 -16
  78. package/dist/esm/slickgrid-config.d.ts +5 -5
  79. package/dist/esm/slickgrid-config.js +6 -6
  80. package/package.json +56 -48
  81. package/tsconfig.json +2 -2
  82. package/dist/amd/components/slickgrid-react.d.ts +0 -207
  83. package/dist/amd/components/slickgrid-react.js +0 -1325
  84. package/dist/amd/components/slickgrid-react.js.map +0 -1
  85. package/dist/amd/components/slickgridEventAggregator.d.ts +0 -10
  86. package/dist/amd/components/slickgridEventAggregator.js +0 -14
  87. package/dist/amd/components/slickgridEventAggregator.js.map +0 -1
  88. package/dist/amd/components/slickgridReactProps.d.ts +0 -288
  89. package/dist/amd/components/slickgridReactProps.js +0 -5
  90. package/dist/amd/components/slickgridReactProps.js.map +0 -1
  91. package/dist/amd/constants.d.ts +0 -23
  92. package/dist/amd/constants.js +0 -93
  93. package/dist/amd/constants.js.map +0 -1
  94. package/dist/amd/global-grid-options.d.ts +0 -5
  95. package/dist/amd/global-grid-options.js +0 -268
  96. package/dist/amd/global-grid-options.js.map +0 -1
  97. package/dist/amd/index.d.ts +0 -8
  98. package/dist/amd/index.js +0 -27
  99. package/dist/amd/index.js.map +0 -1
  100. package/dist/amd/models/gridOption.interface.d.ts +0 -6
  101. package/dist/amd/models/gridOption.interface.js +0 -5
  102. package/dist/amd/models/gridOption.interface.js.map +0 -1
  103. package/dist/amd/models/index.d.ts +0 -4
  104. package/dist/amd/models/index.js +0 -23
  105. package/dist/amd/models/index.js.map +0 -1
  106. package/dist/amd/models/reactComponentOutput.interface.d.ts +0 -6
  107. package/dist/amd/models/reactComponentOutput.interface.js +0 -5
  108. package/dist/amd/models/reactComponentOutput.interface.js.map +0 -1
  109. package/dist/amd/models/slickGrid.interface.d.ts +0 -6
  110. package/dist/amd/models/slickGrid.interface.js +0 -5
  111. package/dist/amd/models/slickGrid.interface.js.map +0 -1
  112. package/dist/amd/models/slickgridReactInstance.interface.d.ts +0 -36
  113. package/dist/amd/models/slickgridReactInstance.interface.js +0 -5
  114. package/dist/amd/models/slickgridReactInstance.interface.js.map +0 -1
  115. package/dist/amd/services/container.service.d.ts +0 -6
  116. package/dist/amd/services/container.service.js +0 -18
  117. package/dist/amd/services/container.service.js.map +0 -1
  118. package/dist/amd/services/index.d.ts +0 -4
  119. package/dist/amd/services/index.js +0 -23
  120. package/dist/amd/services/index.js.map +0 -1
  121. package/dist/amd/services/reactUtil.service.d.ts +0 -5
  122. package/dist/amd/services/reactUtil.service.js +0 -30
  123. package/dist/amd/services/reactUtil.service.js.map +0 -1
  124. package/dist/amd/services/singletons.d.ts +0 -6
  125. package/dist/amd/services/singletons.js +0 -9
  126. package/dist/amd/services/singletons.js.map +0 -1
  127. package/dist/amd/services/translater.service.d.ts +0 -25
  128. package/dist/amd/services/translater.service.js +0 -43
  129. package/dist/amd/services/translater.service.js.map +0 -1
  130. package/dist/amd/services/utilities.d.ts +0 -7
  131. package/dist/amd/services/utilities.js +0 -23
  132. package/dist/amd/services/utilities.js.map +0 -1
  133. package/dist/amd/slickgrid-config.d.ts +0 -5
  134. package/dist/amd/slickgrid-config.js +0 -12
  135. package/dist/amd/slickgrid-config.js.map +0 -1
@@ -1,1338 +1,1339 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __importDefault = (this && this.__importDefault) || function (mod) {
26
- return (mod && mod.__esModule) ? mod : { "default": mod };
27
- };
28
- var _a;
29
- Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.SlickgridReact = void 0;
31
- // import 3rd party vendor libs
32
- const $ = __importStar(require("jquery"));
33
- const i18next_1 = __importDefault(require("i18next"));
34
- const react_1 = __importDefault(require("react"));
35
- require("slickgrid/slick.core");
36
- require("slickgrid/slick.interactions");
37
- require("slickgrid/slick.grid");
38
- require("slickgrid/slick.dataview");
39
- const Sortable_ = __importStar(require("sortablejs"));
40
- const Sortable = ((_a = Sortable_ === null || Sortable_ === void 0 ? void 0 : Sortable_['default']) !== null && _a !== void 0 ? _a : Sortable_); // patch for rollup
41
- const common_1 = require("@slickgrid-universal/common");
42
- const event_pub_sub_1 = require("@slickgrid-universal/event-pub-sub");
43
- const custom_footer_component_1 = require("@slickgrid-universal/custom-footer-component");
44
- const empty_warning_component_1 = require("@slickgrid-universal/empty-warning-component");
45
- const pagination_component_1 = require("@slickgrid-universal/pagination-component");
46
- const lite_1 = require("dequal/lite");
47
- const constants_1 = require("../constants");
48
- const global_grid_options_1 = require("../global-grid-options");
49
- const index_1 = require("../services/index");
50
- const singletons_1 = require("../services/singletons");
51
- // add Sortable to the window object so that SlickGrid lib can use globally
52
- window.Sortable = Sortable;
53
- class CustomEventPubSubService extends event_pub_sub_1.EventPubSubService {
54
- set elementSource(value) {
55
- this._elementSource = value;
56
- }
57
- }
58
- class SlickgridReact extends react_1.default.Component {
59
- setStateValue(key, value, callback) {
60
- if (this.state && this.state[key] === value) {
61
- return;
62
- }
63
- if (!this._mounted) {
64
- this.state = this.state || {};
65
- this.state[key] = value;
66
- return;
67
- }
68
- this.setState(() => {
69
- const result = {};
70
- result[key] = value;
71
- return result;
72
- }, callback);
73
- }
74
- get gridOptions() {
75
- return this._gridOptions || {};
76
- }
77
- set gridOptions(options) {
78
- var _a, _b, _c;
79
- let mergedOptions;
80
- // if we already have grid options, when grid was already initialized, we'll merge with those options
81
- // else we'll merge with global grid options
82
- if ((_a = this.grid) === null || _a === void 0 ? void 0 : _a.getOptions) {
83
- mergedOptions = $.extend(true, {}, this.grid.getOptions(), options);
84
- }
85
- else {
86
- mergedOptions = this.mergeGridOptions(options);
87
- }
88
- if (((_b = this.sharedService) === null || _b === void 0 ? void 0 : _b.gridOptions) && ((_c = this.grid) === null || _c === void 0 ? void 0 : _c.setOptions)) {
89
- this.sharedService.gridOptions = mergedOptions;
90
- this.grid.setOptions(mergedOptions, false, true); // make sure to supressColumnCheck (3rd arg) to avoid problem with changeColumnsArrangement() and custom grid view
91
- this.grid.reRenderColumns(true); // then call a re-render since we did supressColumnCheck on previous setOptions
92
- }
93
- this._gridOptions = mergedOptions;
94
- }
95
- get paginationService() {
96
- var _a;
97
- return (_a = this.state) === null || _a === void 0 ? void 0 : _a.paginationService;
98
- }
99
- set paginationService(value) {
100
- this.setStateValue('paginationService', value);
101
- }
102
- get dataset() {
103
- var _a;
104
- return ((_a = this.dataView) === null || _a === void 0 ? void 0 : _a.getItems()) || [];
105
- }
106
- set dataset(newDataset) {
107
- var _a, _b;
108
- const prevDatasetLn = this._currentDatasetLength;
109
- const isDatasetEqual = (0, lite_1.dequal)(newDataset, this.dataset || []);
110
- const isDeepCopyDataOnPageLoadEnabled = !!((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.enableDeepCopyDatasetOnPageLoad);
111
- let data = isDeepCopyDataOnPageLoadEnabled ? $.extend(true, [], newDataset) : newDataset;
112
- // when Tree Data is enabled and we don't yet have the hierarchical dataset filled, we can force a convert+sort of the array
113
- if (this.grid && ((_b = this.gridOptions) === null || _b === void 0 ? void 0 : _b.enableTreeData) && Array.isArray(newDataset) && (newDataset.length > 0 || newDataset.length !== prevDatasetLn || !isDatasetEqual)) {
114
- this._isDatasetHierarchicalInitialized = false;
115
- data = this.sortTreeDataset(newDataset, !isDatasetEqual); // if dataset changed, then force a refresh anyway
116
- }
117
- this.refreshGridData(data || []);
118
- this._currentDatasetLength = (newDataset || []).length;
119
- // expand/autofit columns on first page load
120
- // we can assume that if the prevDataset was empty then we are on first load
121
- if (this.grid && this.gridOptions.autoFitColumnsOnFirstLoad && prevDatasetLn === 0) {
122
- this.grid.autosizeColumns();
123
- }
124
- }
125
- get datasetHierarchical() {
126
- return this.sharedService.hierarchicalDataset;
127
- }
128
- set datasetHierarchical(newHierarchicalDataset) {
129
- var _a, _b, _c, _d, _f, _g;
130
- const isDatasetEqual = (0, lite_1.dequal)(newHierarchicalDataset, (_b = (_a = this.sharedService) === null || _a === void 0 ? void 0 : _a.hierarchicalDataset) !== null && _b !== void 0 ? _b : []);
131
- const prevFlatDatasetLn = this._currentDatasetLength;
132
- this.sharedService.hierarchicalDataset = newHierarchicalDataset;
133
- if (newHierarchicalDataset && this.props.columnDefinitions && ((_c = this.filterService) === null || _c === void 0 ? void 0 : _c.clearFilters)) {
134
- this.filterService.clearFilters();
135
- }
136
- // when a hierarchical dataset is set afterward, we can reset the flat dataset and call a tree data sort that will overwrite the flat dataset
137
- if (this.dataView && newHierarchicalDataset && this.grid && ((_d = this.sortService) === null || _d === void 0 ? void 0 : _d.processTreeDataInitialSort)) {
138
- this.dataView.setItems([], (_g = (_f = this._gridOptions) === null || _f === void 0 ? void 0 : _f.datasetIdPropertyName) !== null && _g !== void 0 ? _g : 'id');
139
- this.sortService.processTreeDataInitialSort();
140
- // we also need to reset/refresh the Tree Data filters because if we inserted new item(s) then it might not show up without doing this refresh
141
- // however we need 1 cpu cycle before having the DataView refreshed, so we need to wrap this check in a setTimeout
142
- setTimeout(() => {
143
- var _a, _b;
144
- const flatDatasetLn = (_b = (_a = this.dataView) === null || _a === void 0 ? void 0 : _a.getItemCount()) !== null && _b !== void 0 ? _b : 0;
145
- if (flatDatasetLn > 0 && (flatDatasetLn !== prevFlatDatasetLn || !isDatasetEqual)) {
146
- this.filterService.refreshTreeDataFilters();
147
- }
148
- });
149
- }
150
- this._isDatasetHierarchicalInitialized = true;
151
- }
152
- constructor(props) {
153
- var _a, _b, _c, _d, _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;
154
- super(props);
155
- this.props = props;
156
- this._mounted = false;
157
- this._columnDefinitions = [];
158
- this._currentDatasetLength = 0;
159
- this._dataset = null;
160
- this._hideHeaderRowAfterPageLoad = false;
161
- this._isGridInitialized = false;
162
- this._isDatasetInitialized = false;
163
- this._isDatasetHierarchicalInitialized = false;
164
- this._isPaginationInitialized = false;
165
- this._isLocalGrid = true;
166
- this._registeredResources = [];
167
- this.showPagination = false;
168
- this.serviceList = [];
169
- this.subscriptions = [];
170
- this.totalItems = 0;
171
- this.instances = null;
172
- const slickgridConfig = new common_1.SlickgridConfig();
173
- this._eventHandler = new Slick.EventHandler();
174
- this.showPagination = false;
175
- // check if the user wants to hide the header row from the start
176
- // we only want to do this check once in the constructor
177
- this._hideHeaderRowAfterPageLoad = (((_a = props.gridOptions) === null || _a === void 0 ? void 0 : _a.showHeaderRow) === false);
178
- this._gridOptions = this.mergeGridOptions(props.gridOptions || {});
179
- // initialize and assign all Service Dependencies
180
- this._eventPubSubService = (_c = (_b = this.props.externalServices) === null || _b === void 0 ? void 0 : _b.eventPubSubService) !== null && _c !== void 0 ? _c : new CustomEventPubSubService();
181
- this._eventPubSubService.eventNamingStyle = common_1.EventNamingStyle.camelCase;
182
- this.backendUtilityService = (_f = (_d = this.props.externalServices) === null || _d === void 0 ? void 0 : _d.backendUtilityService) !== null && _f !== void 0 ? _f : new common_1.BackendUtilityService();
183
- this.gridEventService = (_h = (_g = this.props.externalServices) === null || _g === void 0 ? void 0 : _g.gridEventService) !== null && _h !== void 0 ? _h : new common_1.GridEventService();
184
- this.sharedService = (_k = (_j = this.props.externalServices) === null || _j === void 0 ? void 0 : _j.sharedService) !== null && _k !== void 0 ? _k : new common_1.SharedService();
185
- this.collectionService = (_m = (_l = this.props.externalServices) === null || _l === void 0 ? void 0 : _l.collectionService) !== null && _m !== void 0 ? _m : new common_1.CollectionService(this.props.translaterService);
186
- this.extensionUtility = (_p = (_o = this.props.externalServices) === null || _o === void 0 ? void 0 : _o.extensionUtility) !== null && _p !== void 0 ? _p : new common_1.ExtensionUtility(this.sharedService, this.backendUtilityService, this.props.translaterService);
187
- this.filterFactory = new common_1.FilterFactory(slickgridConfig, this.props.translaterService, this.collectionService);
188
- this.filterService = (_r = (_q = this.props.externalServices) === null || _q === void 0 ? void 0 : _q.filterService) !== null && _r !== void 0 ? _r : new common_1.FilterService(this.filterFactory, this._eventPubSubService, this.sharedService, this.backendUtilityService);
189
- this.resizerService = (_t = (_s = this.props.externalServices) === null || _s === void 0 ? void 0 : _s.resizerService) !== null && _t !== void 0 ? _t : new common_1.ResizerService(this._eventPubSubService);
190
- this.sortService = (_v = (_u = this.props.externalServices) === null || _u === void 0 ? void 0 : _u.sortService) !== null && _v !== void 0 ? _v : new common_1.SortService(this.sharedService, this._eventPubSubService, this.backendUtilityService);
191
- this.treeDataService = (_x = (_w = this.props.externalServices) === null || _w === void 0 ? void 0 : _w.treeDataService) !== null && _x !== void 0 ? _x : new common_1.TreeDataService(this._eventPubSubService, this.sharedService, this.sortService);
192
- this.paginationService = (_z = (_y = this.props.externalServices) === null || _y === void 0 ? void 0 : _y.paginationService) !== null && _z !== void 0 ? _z : new common_1.PaginationService(this._eventPubSubService, this.sharedService, this.backendUtilityService);
193
- this.extensionService = (_1 = (_0 = this.props.externalServices) === null || _0 === void 0 ? void 0 : _0.extensionService) !== null && _1 !== void 0 ? _1 : new common_1.ExtensionService(this.extensionUtility, this.filterService, this._eventPubSubService, this.sharedService, this.sortService, this.treeDataService, this.props.translaterService);
194
- this.gridStateService = (_3 = (_2 = this.props.externalServices) === null || _2 === void 0 ? void 0 : _2.gridStateService) !== null && _3 !== void 0 ? _3 : new common_1.GridStateService(this.extensionService, this.filterService, this._eventPubSubService, this.sharedService, this.sortService, this.treeDataService);
195
- this.gridService = (_5 = (_4 = this.props.externalServices) === null || _4 === void 0 ? void 0 : _4.gridService) !== null && _5 !== void 0 ? _5 : new common_1.GridService(this.gridStateService, this.filterService, this._eventPubSubService, this.paginationService, this.sharedService, this.sortService, this.treeDataService);
196
- this.groupingService = (_7 = (_6 = this.props.externalServices) === null || _6 === void 0 ? void 0 : _6.groupingAndColspanService) !== null && _7 !== void 0 ? _7 : new common_1.GroupingAndColspanService(this.extensionUtility, this._eventPubSubService);
197
- this.serviceList = [
198
- this.extensionService,
199
- this.filterService,
200
- this.gridEventService,
201
- this.gridService,
202
- this.gridStateService,
203
- this.groupingService,
204
- this.paginationService,
205
- this.resizerService,
206
- this.sortService,
207
- this.treeDataService,
208
- ];
209
- if (this.props.datasetHierarchical) {
210
- this.sharedService.hierarchicalDataset = this.props.datasetHierarchical || [];
211
- }
212
- // register all Service instances in the container
213
- this.props.containerService.registerInstance('PubSubService', this._eventPubSubService);
214
- this.props.containerService.registerInstance('EventPubSubService', this._eventPubSubService);
215
- this.props.containerService.registerInstance('ExtensionUtility', this.extensionUtility);
216
- this.props.containerService.registerInstance('FilterService', this.filterService);
217
- this.props.containerService.registerInstance('CollectionService', this.collectionService);
218
- this.props.containerService.registerInstance('ExtensionService', this.extensionService);
219
- this.props.containerService.registerInstance('GridEventService', this.gridEventService);
220
- this.props.containerService.registerInstance('GridService', this.gridService);
221
- this.props.containerService.registerInstance('GridStateService', this.gridStateService);
222
- this.props.containerService.registerInstance('GroupingAndColspanService', this.groupingService);
223
- this.props.containerService.registerInstance('PaginationService', this.paginationService);
224
- this.props.containerService.registerInstance('ResizerService', this.resizerService);
225
- this.props.containerService.registerInstance('SharedService', this.sharedService);
226
- this.props.containerService.registerInstance('SortService', this.sortService);
227
- this.props.containerService.registerInstance('TranslaterService', this.props.translaterService);
228
- this.props.containerService.registerInstance('TreeDataService', this.treeDataService);
229
- }
230
- get eventHandler() {
231
- return this._eventHandler;
232
- }
233
- get isDatasetInitialized() {
234
- return this._isDatasetInitialized;
235
- }
236
- set isDatasetInitialized(isInitialized) {
237
- this._isDatasetInitialized = isInitialized;
238
- }
239
- set isDatasetHierarchicalInitialized(isInitialized) {
240
- this._isDatasetHierarchicalInitialized = isInitialized;
241
- }
242
- get registeredResources() {
243
- return this._registeredResources;
244
- }
245
- componentDidMount() {
246
- var _a, _b;
247
- this._mounted = true;
248
- if (this._elm && this._eventPubSubService instanceof CustomEventPubSubService) {
249
- this._eventPubSubService.elementSource = this._elm;
250
- // React doesn't play well with Custom Events & also the render is called after the constructor which brings a second problem
251
- // to fix both issues, we need to do the following:
252
- // loop through all component and subscribe to all props that startsWith "on", assuming they are custom event
253
- // and call their listener with event is dispatching
254
- for (const prop in this.props) {
255
- if (prop.startsWith('on')) {
256
- this.subscriptions.push(this._eventPubSubService.subscribe(prop, (data) => {
257
- const callback = this.props[prop];
258
- const gridEventName = this._eventPubSubService.getEventNameByNamingConvention(prop, '');
259
- typeof callback === 'function' && callback.call(null, new CustomEvent(gridEventName, { detail: data }));
260
- }));
261
- }
262
- }
263
- }
264
- this.initialization(this._eventHandler);
265
- this._isGridInitialized = true;
266
- if (!this._isPaginationInitialized && !this.props.datasetHierarchical && ((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.enablePagination) && this._isLocalGrid) {
267
- this.showPagination = true;
268
- this.loadLocalGridPagination(this.dataset);
269
- }
270
- // recheck the empty warning message after grid is shown so that it works in every use case
271
- if ((_b = this._gridOptions) === null || _b === void 0 ? void 0 : _b.enableEmptyDataWarningMessage) {
272
- const dataset = this.props.dataset || [];
273
- if (Array.isArray(dataset)) {
274
- const finalTotalCount = dataset.length;
275
- this.displayEmptyDataWarning(finalTotalCount < 1);
276
- }
277
- }
278
- }
279
- initialization(eventHandler) {
280
- var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
281
- if (!this._gridOptions || !this._columnDefinitions) {
282
- throw new Error('Using `<SlickgridReact>` requires columnDefinitions and gridOptions, it seems that you might have forgot to provide them since at least of them is undefined.');
283
- }
284
- this._gridOptions.translater = this.props.translaterService;
285
- this._eventHandler = eventHandler;
286
- // when detecting a frozen grid, we'll automatically enable the mousewheel scroll handler so that we can scroll from both left/right frozen containers
287
- if (this._gridOptions && ((this._gridOptions.frozenRow !== undefined && this._gridOptions.frozenRow >= 0) || this._gridOptions.frozenColumn !== undefined && this._gridOptions.frozenColumn >= 0) && this._gridOptions.enableMouseWheelScrollHandler === undefined) {
288
- this._gridOptions.enableMouseWheelScrollHandler = true;
289
- }
290
- this._eventPubSubService.eventNamingStyle = (_b = (_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.eventNamingStyle) !== null && _b !== void 0 ? _b : common_1.EventNamingStyle.camelCase;
291
- this._eventPubSubService.publish(`onBeforeGridCreate`, true);
292
- // make sure the dataset is initialized (if not it will throw an error that it cannot getLength of null)
293
- this._dataset = this._dataset || this.props.dataset || [];
294
- this._currentDatasetLength = this._dataset.length;
295
- this._gridOptions = this.mergeGridOptions(this._gridOptions);
296
- this._paginationOptions = (_c = this._gridOptions) === null || _c === void 0 ? void 0 : _c.pagination;
297
- this.locales = (_f = (_d = this._gridOptions) === null || _d === void 0 ? void 0 : _d.locales) !== null && _f !== void 0 ? _f : constants_1.Constants.locales;
298
- this.backendServiceApi = (_g = this._gridOptions) === null || _g === void 0 ? void 0 : _g.backendServiceApi;
299
- this._isLocalGrid = !this.backendServiceApi; // considered a local grid if it doesn't have a backend service set
300
- this.createBackendApiInternalPostProcessCallback(this._gridOptions);
301
- if (!this.props.customDataView) {
302
- const dataviewInlineFilters = this._gridOptions.dataView && this._gridOptions.dataView.inlineFilters || false;
303
- let dataViewOptions = { inlineFilters: dataviewInlineFilters };
304
- if (this._gridOptions.draggableGrouping || this._gridOptions.enableGrouping) {
305
- this.groupItemMetadataProvider = new common_1.SlickGroupItemMetadataProvider();
306
- this.sharedService.groupItemMetadataProvider = this.groupItemMetadataProvider;
307
- dataViewOptions = Object.assign(Object.assign({}, dataViewOptions), { groupItemMetadataProvider: this.groupItemMetadataProvider });
308
- }
309
- this.dataView = new Slick.Data.DataView(dataViewOptions);
310
- this._eventPubSubService.publish(`onDataviewCreated`, this.dataView);
311
- }
312
- // get any possible Services that user want to register which don't require SlickGrid to be instantiated
313
- // RxJS Resource is in this lot because it has to be registered before anything else and doesn't require SlickGrid to be initialized
314
- this.preRegisterResources();
315
- // for convenience to the user, we provide the property "editor" as an Slickgrid-React editor complex object
316
- // however "editor" is used internally by SlickGrid for it's own Editor Factory
317
- // so in our lib we will swap "editor" and copy it into a new property called "internalColumnEditor"
318
- // then take back "editor.model" and make it the new "editor" so that SlickGrid Editor Factory still works
319
- this._columnDefinitions = this.swapInternalEditorToSlickGridFactoryEditor(this.props.columnDefinitions);
320
- // if the user wants to automatically add a Custom Editor Formatter, we need to call the auto add function again
321
- if (this._gridOptions.autoAddCustomEditorFormatter) {
322
- (0, common_1.autoAddEditorFormatterToColumnsWithEditor)(this._columnDefinitions, this._gridOptions.autoAddCustomEditorFormatter);
323
- }
324
- // save reference for all columns before they optionally become hidden/visible
325
- this.sharedService.allColumns = this._columnDefinitions;
326
- this.sharedService.visibleColumns = this._columnDefinitions;
327
- // after subscribing to potential columns changed, we are ready to create these optional extensions
328
- // when we did find some to create (RowMove, RowDetail, RowSelections), it will automatically modify column definitions (by previous subscribe)
329
- this.extensionService.createExtensionsBeforeGridCreation(this._columnDefinitions, this._gridOptions);
330
- // if user entered some Pinning/Frozen "presets", we need to apply them in the grid options
331
- if ((_h = this.gridOptions.presets) === null || _h === void 0 ? void 0 : _h.pinning) {
332
- this.gridOptions = Object.assign(Object.assign({}, this.gridOptions), this.gridOptions.presets.pinning);
333
- }
334
- // build SlickGrid Grid, also user might optionally pass a custom dataview (e.g. remote model)
335
- this.grid = new Slick.Grid(`#${this.props.gridId}`, this.props.customDataView || this.dataView, this._columnDefinitions, this._gridOptions);
336
- this.sharedService.dataView = this.dataView;
337
- this.sharedService.slickGrid = this.grid;
338
- this.sharedService.gridContainerElement = this._elm;
339
- this.extensionService.bindDifferentExtensions();
340
- this.bindDifferentHooks(this.grid, this._gridOptions, this.dataView);
341
- // when it's a frozen grid, we need to keep the frozen column id for reference if we ever show/hide column from ColumnPicker/GridMenu afterward
342
- const frozenColumnIndex = (_k = (_j = this._gridOptions) === null || _j === void 0 ? void 0 : _j.frozenColumn) !== null && _k !== void 0 ? _k : -1;
343
- if (frozenColumnIndex >= 0 && frozenColumnIndex <= this._columnDefinitions.length && this._columnDefinitions.length > 0) {
344
- this.sharedService.frozenVisibleColumnId = (_m = (_l = this._columnDefinitions[frozenColumnIndex]) === null || _l === void 0 ? void 0 : _l.id) !== null && _m !== void 0 ? _m : '';
345
- }
346
- // get any possible Services that user want to register
347
- this.registerResources();
348
- // initialize the SlickGrid grid
349
- this.grid.init();
350
- // initialized the resizer service only after SlickGrid is initialized
351
- // if we don't we end up binding our resize to a grid element that doesn't yet exist in the DOM and the resizer service will fail silently (because it has a try/catch that unbinds the resize without throwing back)
352
- const gridContainerElm = this._elm;
353
- if (gridContainerElm) {
354
- this.resizerService.init(this.grid, gridContainerElm);
355
- }
356
- // user could show a custom footer with the data metrics (dataset length and last updated timestamp)
357
- if (!this._gridOptions.enablePagination && this._gridOptions.showCustomFooter && this._gridOptions.customFooterOptions && gridContainerElm) {
358
- this.slickFooter = new custom_footer_component_1.SlickFooterComponent(this.grid, this._gridOptions.customFooterOptions, this._eventPubSubService, this.props.translaterService);
359
- this.slickFooter.renderFooter(gridContainerElm);
360
- }
361
- if (!this.props.customDataView && this.dataView) {
362
- const initialDataset = ((_o = this._gridOptions) === null || _o === void 0 ? void 0 : _o.enableTreeData) ? this.sortTreeDataset(this.props.dataset) : this.props.dataset;
363
- if (Array.isArray(initialDataset)) {
364
- this.dataView.setItems(initialDataset, (_p = this._gridOptions.datasetIdPropertyName) !== null && _p !== void 0 ? _p : 'id');
365
- }
366
- // if you don't want the items that are not visible (due to being filtered out or being on a different page)
367
- // to stay selected, pass 'false' to the second arg
368
- if (((_q = this.grid) === null || _q === void 0 ? void 0 : _q.getSelectionModel()) && ((_r = this._gridOptions) === null || _r === void 0 ? void 0 : _r.dataView) && this._gridOptions.dataView.hasOwnProperty('syncGridSelection')) {
369
- // if we are using a Backend Service, we will do an extra flag check, the reason is because it might have some unintended behaviors
370
- // with the BackendServiceApi because technically the data in the page changes the DataView on every page change.
371
- let preservedRowSelectionWithBackend = false;
372
- if (this._gridOptions.backendServiceApi && this._gridOptions.dataView.hasOwnProperty('syncGridSelectionWithBackendService')) {
373
- preservedRowSelectionWithBackend = this._gridOptions.dataView.syncGridSelectionWithBackendService;
374
- }
375
- const syncGridSelection = this._gridOptions.dataView.syncGridSelection;
376
- if (typeof syncGridSelection === 'boolean') {
377
- let preservedRowSelection = syncGridSelection;
378
- if (!this._isLocalGrid) {
379
- // when using BackendServiceApi, we'll be using the "syncGridSelectionWithBackendService" flag BUT "syncGridSelection" must also be set to True
380
- preservedRowSelection = syncGridSelection && preservedRowSelectionWithBackend;
381
- }
382
- this.dataView.syncGridSelection(this.grid, preservedRowSelection);
383
- }
384
- else if (typeof syncGridSelection === 'object') {
385
- this.dataView.syncGridSelection(this.grid, syncGridSelection.preserveHidden, syncGridSelection.preserveHiddenOnSelectionChange);
386
- }
387
- }
388
- if (this._dataset.length > 0) {
389
- if (!this._isDatasetInitialized && (this._gridOptions.enableCheckboxSelector || this._gridOptions.enableRowSelection)) {
390
- this.loadRowSelectionPresetWhenExists();
391
- }
392
- this.loadFilterPresetsWhenDatasetInitialized();
393
- this._isDatasetInitialized = true;
394
- }
395
- }
396
- // user might want to hide the header row on page load but still have `enableFiltering: true`
397
- // if that is the case, we need to hide the headerRow ONLY AFTER all filters got created & dataView exist
398
- if (this._hideHeaderRowAfterPageLoad) {
399
- this.showHeaderRow(false);
400
- this.sharedService.hideHeaderRowAfterPageLoad = this._hideHeaderRowAfterPageLoad;
401
- }
402
- // publish & dispatch certain events
403
- this._eventPubSubService.publish(`onGridCreated`, this.grid);
404
- // after the DataView is created & updated execute some processes & dispatch some events
405
- if (!this.props.customDataView) {
406
- this.executeAfterDataviewCreated(this.grid, this._gridOptions);
407
- }
408
- // bind resize ONLY after the dataView is ready
409
- this.bindResizeHook(this.grid, this._gridOptions);
410
- // bind the Backend Service API callback functions only after the grid is initialized
411
- // because the preProcess() and onInit() might get triggered
412
- if ((_s = this._gridOptions) === null || _s === void 0 ? void 0 : _s.backendServiceApi) {
413
- this.bindBackendCallbackFunctions(this._gridOptions);
414
- }
415
- // create the React Grid Instance with reference to all Services
416
- const reactElementInstance = {
417
- element: this._elm,
418
- // Slick Grid & DataView objects
419
- dataView: this.dataView,
420
- slickGrid: this.grid,
421
- // public methods
422
- dispose: this.dispose.bind(this),
423
- // return all available Services (non-singleton)
424
- backendService: (_u = (_t = this._gridOptions) === null || _t === void 0 ? void 0 : _t.backendServiceApi) === null || _u === void 0 ? void 0 : _u.service,
425
- eventPubSubService: this._eventPubSubService,
426
- filterService: this.filterService,
427
- gridEventService: this.gridEventService,
428
- gridStateService: this.gridStateService,
429
- gridService: this.gridService,
430
- groupingService: this.groupingService,
431
- extensionService: this.extensionService,
432
- paginationService: this.paginationService,
433
- resizerService: this.resizerService,
434
- sortService: this.sortService,
435
- treeDataService: this.treeDataService,
436
- };
437
- // addons (SlickGrid extra plugins/controls)
438
- this.extensions = (_v = this.extensionService) === null || _v === void 0 ? void 0 : _v.extensionList;
439
- // all instances (SlickGrid, DataView & all Services)
440
- this.instances = reactElementInstance;
441
- this.setStateValue('instances', reactElementInstance);
442
- this._eventPubSubService.publish(`onReactGridCreated`, reactElementInstance);
443
- }
444
- componentWillUnmount(shouldEmptyDomElementContainer = false) {
445
- var _a, _b, _c, _d, _f;
446
- this._eventPubSubService.publish(`onBeforeGridDestroy`, this.grid);
447
- (_a = this._eventHandler) === null || _a === void 0 ? void 0 : _a.unsubscribeAll();
448
- i18next_1.default.off('languageChanged');
449
- // we could optionally also empty the content of the grid container DOM element
450
- if (shouldEmptyDomElementContainer) {
451
- this.emptyGridContainerElm();
452
- }
453
- this._eventPubSubService.publish(`onAfterGridDestroyed`, true);
454
- // dispose of all Services
455
- this.serviceList.forEach((service) => {
456
- if (service === null || service === void 0 ? void 0 : service.dispose) {
457
- service.dispose();
458
- }
459
- });
460
- this.serviceList = [];
461
- // dispose all registered external resources
462
- if (Array.isArray(this._registeredResources)) {
463
- while (this._registeredResources.length > 0) {
464
- const resource = this._registeredResources.pop();
465
- if (resource === null || resource === void 0 ? void 0 : resource.dispose) {
466
- resource.dispose();
467
- }
468
- }
469
- this._registeredResources = [];
470
- }
471
- // dispose the Components
472
- (_b = this.slickEmptyWarning) === null || _b === void 0 ? void 0 : _b.dispose();
473
- (_c = this.slickFooter) === null || _c === void 0 ? void 0 : _c.dispose();
474
- (_d = this.slickPagination) === null || _d === void 0 ? void 0 : _d.dispose();
475
- if (this.dataView) {
476
- if (this.dataView.setItems) {
477
- this.dataView.setItems([]);
478
- }
479
- if (this.dataView.destroy) {
480
- this.dataView.destroy();
481
- }
482
- }
483
- if ((_f = this.grid) === null || _f === void 0 ? void 0 : _f.destroy) {
484
- this.grid.destroy(shouldEmptyDomElementContainer);
485
- }
486
- // also dispose of all Subscriptions
487
- this.subscriptions = (0, index_1.disposeAllSubscriptions)(this.subscriptions);
488
- if (this.backendServiceApi) {
489
- for (const prop of Object.keys(this.backendServiceApi)) {
490
- this.backendServiceApi[prop] = null;
491
- }
492
- this.backendServiceApi = undefined;
493
- }
494
- for (const prop of Object.keys(this.props.columnDefinitions)) {
495
- this.props.columnDefinitions[prop] = null;
496
- }
497
- for (const prop of Object.keys(this.sharedService)) {
498
- this.sharedService[prop] = null;
499
- }
500
- this._dataset = null;
501
- this._columnDefinitions = [];
502
- }
503
- emptyGridContainerElm() {
504
- var _a, _b;
505
- const gridContainerId = (_b = (_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.gridContainerId) !== null && _b !== void 0 ? _b : 'grid1';
506
- const gridContainerElm = document.querySelector(`#${gridContainerId}`);
507
- (0, common_1.emptyElement)(gridContainerElm);
508
- }
509
- dispose(shouldEmptyDomElementContainer = false) {
510
- this.componentWillUnmount(shouldEmptyDomElementContainer);
511
- }
512
- componentDidUpdate(prevProps) {
513
- // get the grid options (order of precedence is Global Options first, then user option which could overwrite the Global options)
514
- if (this.props.gridOptions !== prevProps.gridOptions) {
515
- this._gridOptions = Object.assign(Object.assign({}, global_grid_options_1.GlobalGridOptions), this._gridOptions);
516
- }
517
- if (this.props.columnDefinitions !== prevProps.columnDefinitions) {
518
- this._columnDefinitions = this.props.columnDefinitions;
519
- this.columnDefinitionsChanged();
520
- }
521
- if (this.props.dataset !== prevProps.dataset) {
522
- this.dataset = this.props.dataset || prevProps.dataset;
523
- }
524
- if (this.props.datasetHierarchical && this.props.datasetHierarchical !== prevProps.datasetHierarchical) {
525
- this.datasetHierarchical = this.props.datasetHierarchical;
526
- }
527
- }
528
- columnDefinitionsChanged() {
529
- this._columnDefinitions = this.props.columnDefinitions;
530
- if (this._isGridInitialized) {
531
- this.updateColumnDefinitionsList(this.props.columnDefinitions);
532
- }
533
- if (this._columnDefinitions.length > 0) {
534
- this.copyColumnWidthsReference(this._columnDefinitions);
535
- }
536
- }
537
- /**
538
- * Commits the current edit to the grid
539
- */
540
- commitEdit(target) {
541
- if (this.grid.getOptions().autoCommitEdit) {
542
- const activeNode = this.grid.getActiveCellNode();
543
- // a timeout must be set or this could come into conflict when slickgrid
544
- // tries to commit the edit when going from one editor to another on the grid
545
- // through the click event. If the timeout was not here it would
546
- // try to commit/destroy the twice, which would throw a jquery
547
- // error about the element not being in the DOM
548
- setTimeout(() => {
549
- var _a;
550
- // make sure the target is the active editor so we do not
551
- // commit prematurely
552
- if ((activeNode === null || activeNode === void 0 ? void 0 : activeNode.contains(target)) && this.grid.getEditorLock().isActive() && !((_a = target === null || target === void 0 ? void 0 : target.classList) === null || _a === void 0 ? void 0 : _a.contains('autocomplete'))) {
553
- this.grid.getEditorLock().commitCurrentEdit();
554
- }
555
- });
556
- }
557
- }
558
- /**
559
- * Define our internal Post Process callback, it will execute internally after we get back result from the Process backend call
560
- * For now, this is GraphQL Service ONLY feature and it will basically
561
- * refresh the Dataset & Pagination without having the user to create his own PostProcess every time
562
- */
563
- createBackendApiInternalPostProcessCallback(gridOptions) {
564
- const backendApi = gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.backendServiceApi;
565
- if (backendApi === null || backendApi === void 0 ? void 0 : backendApi.service) {
566
- const backendApiService = backendApi.service;
567
- // internalPostProcess only works (for now) with a GraphQL Service, so make sure it is of that type
568
- if (typeof backendApiService.getDatasetName === 'function') {
569
- backendApi.internalPostProcess = (processResult) => {
570
- const datasetName = (backendApi && backendApiService && typeof backendApiService.getDatasetName === 'function') ? backendApiService.getDatasetName() : '';
571
- if (processResult === null || processResult === void 0 ? void 0 : processResult.data[datasetName]) {
572
- const data = processResult.data[datasetName].hasOwnProperty('nodes') ? processResult.data[datasetName].nodes : processResult.data[datasetName];
573
- const totalCount = processResult.data[datasetName].hasOwnProperty('totalCount') ? processResult.data[datasetName].totalCount : processResult.data[datasetName].length;
574
- this.refreshGridData(data, totalCount || 0);
575
- }
576
- };
577
- }
578
- }
579
- }
580
- bindDifferentHooks(grid, gridOptions, dataView) {
581
- var _a, _b, _c;
582
- // translate some of them on first load, then on each language change
583
- if (gridOptions.enableTranslate) {
584
- this.extensionService.translateAllExtensions();
585
- this.translateColumnHeaderTitleKeys();
586
- this.translateColumnGroupKeys();
587
- }
588
- // on locale change, we have to manually translate the Headers, GridMenu
589
- i18next_1.default.on('languageChanged', () => {
590
- // publish event of the same name that Slickgrid-Universal uses on a language change event
591
- this._eventPubSubService.publish('onLanguageChange');
592
- if (gridOptions.enableTranslate) {
593
- this.extensionService.translateAllExtensions();
594
- this.translateColumnHeaderTitleKeys();
595
- this.translateColumnGroupKeys();
596
- if (gridOptions.createPreHeaderPanel && !gridOptions.enableDraggableGrouping) {
597
- this.groupingService.translateGroupingAndColSpan();
598
- }
599
- }
600
- });
601
- // if user set an onInit Backend, we'll run it right away (and if so, we also need to run preProcess, internalPostProcess & postProcess)
602
- if (gridOptions.backendServiceApi) {
603
- const backendApi = gridOptions.backendServiceApi;
604
- if ((_a = backendApi === null || backendApi === void 0 ? void 0 : backendApi.service) === null || _a === void 0 ? void 0 : _a.init) {
605
- backendApi.service.init(backendApi.options, gridOptions.pagination, this.grid, this.sharedService);
606
- }
607
- }
608
- if (dataView && grid) {
609
- const slickgridEventPrefix = (_c = (_b = this._gridOptions) === null || _b === void 0 ? void 0 : _b.defaultSlickgridEventPrefix) !== null && _c !== void 0 ? _c : '';
610
- // expose all Slick Grid Events through dispatch
611
- for (const prop in grid) {
612
- if (grid.hasOwnProperty(prop) && prop.startsWith('on')) {
613
- const gridEventName = this._eventPubSubService.getEventNameByNamingConvention(prop, slickgridEventPrefix);
614
- this._eventHandler.subscribe(grid[prop], (event, args) => {
615
- if (this.props.hasOwnProperty(prop)) {
616
- const callback = this.props[prop];
617
- return typeof callback === 'function' && callback(new CustomEvent(gridEventName, { detail: { eventData: event, args } }));
618
- }
619
- return true;
620
- });
621
- }
622
- }
623
- // expose all Slick DataView Events through dispatch
624
- for (const prop in dataView) {
625
- if (dataView.hasOwnProperty(prop) && prop.startsWith('on')) {
626
- this._eventHandler.subscribe(dataView[prop], (event, args) => {
627
- const dataViewEventName = this._eventPubSubService.getEventNameByNamingConvention(prop, slickgridEventPrefix);
628
- if (this.props.hasOwnProperty(prop)) {
629
- const callback = this.props[prop];
630
- return typeof callback === 'function' && callback(new CustomEvent(dataViewEventName, { detail: { eventData: event, args } }));
631
- }
632
- return true;
633
- });
634
- }
635
- }
636
- // on cell click, mainly used with the columnDef.action callback
637
- this.gridEventService.bindOnBeforeEditCell(grid);
638
- this.gridEventService.bindOnCellChange(grid);
639
- this.gridEventService.bindOnClick(grid);
640
- if (dataView && grid) {
641
- // bind external sorting (backend) when available or default onSort (dataView)
642
- if (gridOptions.enableSorting) {
643
- // bind external sorting (backend) unless specified to use the local one
644
- if (gridOptions.backendServiceApi && !gridOptions.backendServiceApi.useLocalSorting) {
645
- this.sortService.bindBackendOnSort(grid);
646
- }
647
- else {
648
- this.sortService.bindLocalOnSort(grid);
649
- }
650
- }
651
- // bind external filter (backend) when available or default onFilter (dataView)
652
- if (gridOptions.enableFiltering) {
653
- this.filterService.init(grid);
654
- // bind external filter (backend) unless specified to use the local one
655
- if (gridOptions.backendServiceApi && !gridOptions.backendServiceApi.useLocalFiltering) {
656
- this.filterService.bindBackendOnFilter(grid);
657
- }
658
- else {
659
- this.filterService.bindLocalOnFilter(grid);
660
- }
661
- }
662
- // when column are reordered, we need to update the visibleColumn array
663
- this._eventHandler.subscribe(grid.onColumnsReordered, (_e, args) => {
664
- this.sharedService.hasColumnsReordered = true;
665
- this.sharedService.visibleColumns = args.impactedColumns;
666
- });
667
- // load any presets if any (after dataset is initialized)
668
- this.loadColumnPresetsWhenDatasetInitialized();
669
- this.loadFilterPresetsWhenDatasetInitialized();
670
- // When data changes in the DataView, we need to refresh the metrics and/or display a warning if the dataset is empty
671
- this._eventHandler.subscribe(dataView.onRowCountChanged, () => {
672
- grid.invalidate();
673
- this.handleOnItemCountChanged(dataView.getFilteredItemCount() || 0, dataView.getItemCount() || 0);
674
- });
675
- this._eventHandler.subscribe(dataView.onSetItemsCalled, (_e, args) => {
676
- var _a;
677
- this.handleOnItemCountChanged(dataView.getFilteredItemCount() || 0, args.itemCount);
678
- // when user has resize by content enabled, we'll force a full width calculation since we change our entire dataset
679
- if (args.itemCount > 0 && (this.gridOptions.autosizeColumnsByCellContentOnFirstLoad || this.gridOptions.enableAutoResizeColumnsByCellContent)) {
680
- this.resizerService.resizeColumnsByCellContent(!((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.resizeByContentOnlyOnFirstLoad));
681
- }
682
- });
683
- if ((gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.enableFiltering) && !gridOptions.enableRowDetailView) {
684
- this._eventHandler.subscribe(dataView.onRowsChanged, (_e, args) => {
685
- // filtering data with local dataset will not always show correctly unless we call this updateRow/render
686
- // also don't use "invalidateRows" since it destroys the entire row and as bad user experience when updating a row
687
- // see commit: https://github.com/slickgrid-universal/aurelia-slickgrid/commit/8c503a4d45fba11cbd8d8cc467fae8d177cc4f60
688
- if ((args === null || args === void 0 ? void 0 : args.rows) && Array.isArray(args.rows)) {
689
- args.rows.forEach((row) => grid.updateRow(row));
690
- grid.render();
691
- }
692
- });
693
- }
694
- }
695
- }
696
- // did the user add a colspan callback? If so, hook it into the DataView getItemMetadata
697
- if ((gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.colspanCallback) && (dataView === null || dataView === void 0 ? void 0 : dataView.getItem) && (dataView === null || dataView === void 0 ? void 0 : dataView.getItemMetadata)) {
698
- dataView.getItemMetadata = (rowNumber) => {
699
- let callbackResult = null;
700
- if (gridOptions.colspanCallback) {
701
- callbackResult = gridOptions.colspanCallback(dataView.getItem(rowNumber));
702
- }
703
- return callbackResult;
704
- };
705
- }
706
- }
707
- bindBackendCallbackFunctions(gridOptions) {
708
- var _a, _b, _c, _d, _f;
709
- const backendApi = gridOptions.backendServiceApi;
710
- const backendApiService = backendApi === null || backendApi === void 0 ? void 0 : backendApi.service;
711
- const serviceOptions = (backendApiService === null || backendApiService === void 0 ? void 0 : backendApiService.options) || {};
712
- const isExecuteCommandOnInit = (!serviceOptions) ? false : ((serviceOptions && serviceOptions.hasOwnProperty('executeProcessCommandOnInit')) ? serviceOptions['executeProcessCommandOnInit'] : true);
713
- if (backendApiService) {
714
- // update backend filters (if need be) BEFORE the query runs (via the onInit command a few lines below)
715
- // if user entered some any "presets", we need to reflect them all in the grid
716
- if (gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.presets) {
717
- // Filters "presets"
718
- if (backendApiService.updateFilters && Array.isArray(gridOptions.presets.filters) && gridOptions.presets.filters.length > 0) {
719
- backendApiService.updateFilters(gridOptions.presets.filters, true);
720
- }
721
- // Sorters "presets"
722
- if (backendApiService.updateSorters && Array.isArray(gridOptions.presets.sorters) && gridOptions.presets.sorters.length > 0) {
723
- // when using multi-column sort, we can have multiple but on single sort then only grab the first sort provided
724
- const sortColumns = ((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.multiColumnSort) ? gridOptions.presets.sorters : gridOptions.presets.sorters.slice(0, 1);
725
- backendApiService.updateSorters(undefined, sortColumns);
726
- }
727
- // Pagination "presets"
728
- if (backendApiService.updatePagination && gridOptions.presets.pagination) {
729
- const { pageNumber, pageSize } = gridOptions.presets.pagination;
730
- backendApiService.updatePagination(pageNumber, pageSize);
731
- }
732
- }
733
- else {
734
- const columnFilters = this.filterService.getColumnFilters();
735
- if (columnFilters && backendApiService.updateFilters) {
736
- backendApiService.updateFilters(columnFilters, false);
737
- }
738
- }
739
- // execute onInit command when necessary
740
- if (backendApi && backendApiService && (backendApi.onInit || isExecuteCommandOnInit)) {
741
- const query = (typeof backendApiService.buildQuery === 'function') ? backendApiService.buildQuery() : '';
742
- const process = isExecuteCommandOnInit ? ((_c = (_b = backendApi.process) === null || _b === void 0 ? void 0 : _b.call(backendApi, query)) !== null && _c !== void 0 ? _c : null) : ((_f = (_d = backendApi.onInit) === null || _d === void 0 ? void 0 : _d.call(backendApi, query)) !== null && _f !== void 0 ? _f : null);
743
- // wrap this inside a setTimeout to avoid timing issue since the gridOptions needs to be ready before running this onInit
744
- setTimeout(() => {
745
- var _a, _b, _c, _d;
746
- const backendUtilityService = this.backendUtilityService;
747
- // keep start time & end timestamps & return it after process execution
748
- const startTime = new Date();
749
- // run any pre-process, if defined, for example a spinner
750
- if (backendApi.preProcess) {
751
- backendApi.preProcess();
752
- }
753
- // the processes can be a Promise (like Http)
754
- const totalItems = (_c = (_b = (_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.pagination) === null || _b === void 0 ? void 0 : _b.totalItems) !== null && _c !== void 0 ? _c : 0;
755
- if (process instanceof Promise) {
756
- process
757
- .then((processResult) => backendUtilityService.executeBackendProcessesCallback(startTime, processResult, backendApi, totalItems))
758
- .catch((error) => backendUtilityService.onBackendError(error, backendApi));
759
- }
760
- else if (process && ((_d = this.rxjs) === null || _d === void 0 ? void 0 : _d.isObservable(process))) {
761
- this.subscriptions.push(process.subscribe((processResult) => backendUtilityService.executeBackendProcessesCallback(startTime, processResult, backendApi, totalItems), (error) => backendUtilityService.onBackendError(error, backendApi)));
762
- }
763
- });
764
- }
765
- }
766
- }
767
- bindResizeHook(grid, options) {
768
- if ((options.autoFitColumnsOnFirstLoad && options.autosizeColumnsByCellContentOnFirstLoad) || (options.enableAutoSizeColumns && options.enableAutoResizeColumnsByCellContent)) {
769
- throw new Error(`[Slickgrid-React] You cannot enable both autosize/fit viewport & resize by content, you must choose which resize technique to use. You can enable these 2 options ("autoFitColumnsOnFirstLoad" and "enableAutoSizeColumns") OR these other 2 options ("autosizeColumnsByCellContentOnFirstLoad" and "enableAutoResizeColumnsByCellContent").`);
770
- }
771
- // expand/autofit columns on first page load
772
- if (grid && options.autoFitColumnsOnFirstLoad && options.enableAutoSizeColumns && typeof grid.autosizeColumns === 'function') {
773
- this.grid.autosizeColumns();
774
- }
775
- // auto-resize grid on browser resize
776
- if (options.gridHeight || options.gridWidth) {
777
- this.resizerService.resizeGrid(0, { height: options.gridHeight, width: options.gridWidth });
778
- }
779
- else {
780
- this.resizerService.resizeGrid();
781
- }
782
- if (grid && (options === null || options === void 0 ? void 0 : options.enableAutoResize)) {
783
- if (options.autoFitColumnsOnFirstLoad && options.enableAutoSizeColumns && typeof grid.autosizeColumns === 'function') {
784
- grid.autosizeColumns();
785
- }
786
- }
787
- }
788
- executeAfterDataviewCreated(_grid, gridOptions) {
789
- var _a;
790
- // if user entered some Sort "presets", we need to reflect them all in the DOM
791
- if (gridOptions.enableSorting) {
792
- if (gridOptions.presets && Array.isArray(gridOptions.presets.sorters)) {
793
- // when using multi-column sort, we can have multiple but on single sort then only grab the first sort provided
794
- const sortColumns = ((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.multiColumnSort) ? gridOptions.presets.sorters : gridOptions.presets.sorters.slice(0, 1);
795
- this.sortService.loadGridSorters(sortColumns);
796
- }
797
- }
798
- }
799
- /**
800
- * On a Pagination changed, we will trigger a Grid State changed with the new pagination info
801
- * Also if we use Row Selection or the Checkbox Selector with a Backend Service (Odata, GraphQL), we need to reset any selection
802
- */
803
- paginationChanged(pagination) {
804
- var _a, _b, _c;
805
- const isSyncGridSelectionEnabled = (_b = (_a = this.gridStateService) === null || _a === void 0 ? void 0 : _a.needToPreserveRowSelection()) !== null && _b !== void 0 ? _b : false;
806
- if (this.grid && !isSyncGridSelectionEnabled && ((_c = this.gridOptions) === null || _c === void 0 ? void 0 : _c.backendServiceApi) && (this.gridOptions.enableRowSelection || this.gridOptions.enableCheckboxSelector)) {
807
- this.grid.setSelectedRows([]);
808
- }
809
- const { pageNumber, pageSize } = pagination;
810
- if (this.sharedService) {
811
- if (pageSize !== undefined && pageNumber !== undefined) {
812
- this.sharedService.currentPagination = { pageNumber, pageSize };
813
- }
814
- }
815
- this._eventPubSubService.publish('onGridStateChanged', {
816
- change: { newValues: { pageNumber, pageSize }, type: common_1.GridStateType.pagination },
817
- gridState: this.gridStateService.getCurrentGridState()
818
- });
819
- }
820
- paginationOptionsChanged(newPaginationOptions) {
821
- var _a;
822
- if (newPaginationOptions && this._paginationOptions) {
823
- this._paginationOptions = Object.assign(Object.assign({}, this._paginationOptions), newPaginationOptions);
824
- }
825
- else {
826
- this._paginationOptions = newPaginationOptions;
827
- }
828
- if (this._gridOptions) {
829
- this._gridOptions.pagination = this._paginationOptions;
830
- this.paginationService.updateTotalItems((_a = newPaginationOptions === null || newPaginationOptions === void 0 ? void 0 : newPaginationOptions.totalItems) !== null && _a !== void 0 ? _a : 0, true);
831
- }
832
- }
833
- /**
834
- * When dataset changes, we need to refresh the entire grid UI & possibly resize it as well
835
- * @param dataset
836
- */
837
- refreshGridData(dataset, totalCount) {
838
- var _a, _b, _c, _d, _f, _g, _h, _j;
839
- // local grid, check if we need to show the Pagination
840
- // if so then also check if there's any presets and finally initialize the PaginationService
841
- // a local grid with Pagination presets will potentially have a different total of items, we'll need to get it from the DataView and update our total
842
- if (this.grid && this._gridOptions) {
843
- if (((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.enablePagination) && this._isLocalGrid) {
844
- this.showPagination = true;
845
- this.loadLocalGridPagination(dataset);
846
- }
847
- if (((_b = this._gridOptions) === null || _b === void 0 ? void 0 : _b.enableEmptyDataWarningMessage) && Array.isArray(dataset)) {
848
- const finalTotalCount = totalCount || dataset.length;
849
- this.displayEmptyDataWarning(finalTotalCount < 1);
850
- }
851
- if (Array.isArray(dataset) && this.grid && ((_c = this.dataView) === null || _c === void 0 ? void 0 : _c.setItems)) {
852
- this.dataView.setItems(dataset, (_d = this._gridOptions.datasetIdPropertyName) !== null && _d !== void 0 ? _d : 'id');
853
- if (!this._gridOptions.backendServiceApi && !this._gridOptions.enableTreeData) {
854
- this.dataView.reSort();
855
- }
856
- if (dataset.length > 0) {
857
- if (!this._isDatasetInitialized) {
858
- this.loadFilterPresetsWhenDatasetInitialized();
859
- if (this._gridOptions.enableCheckboxSelector) {
860
- this.loadRowSelectionPresetWhenExists();
861
- }
862
- }
863
- this._isDatasetInitialized = true;
864
- }
865
- if (dataset) {
866
- this.grid.invalidate();
867
- }
868
- // display the Pagination component only after calling this refresh data first, we call it here so that if we preset pagination page number it will be shown correctly
869
- this.showPagination = (this._gridOptions && (this._gridOptions.enablePagination || (this._gridOptions.backendServiceApi && this._gridOptions.enablePagination === undefined))) ? true : false;
870
- if (this._paginationOptions && ((_f = this._gridOptions) === null || _f === void 0 ? void 0 : _f.pagination) && ((_g = this._gridOptions) === null || _g === void 0 ? void 0 : _g.backendServiceApi)) {
871
- const paginationOptions = this.setPaginationOptionsWhenPresetDefined(this._gridOptions, this._paginationOptions);
872
- // when we have a totalCount use it, else we'll take it from the pagination object
873
- // only update the total items if it's different to avoid refreshing the UI
874
- const totalRecords = (totalCount !== undefined) ? totalCount : ((_j = (_h = this._gridOptions) === null || _h === void 0 ? void 0 : _h.pagination) === null || _j === void 0 ? void 0 : _j.totalItems);
875
- if (totalRecords !== undefined && totalRecords !== this.totalItems) {
876
- this.totalItems = +totalRecords;
877
- }
878
- // initialize the Pagination Service with new pagination options (which might have presets)
879
- if (!this._isPaginationInitialized) {
880
- this.initializePaginationService(paginationOptions);
881
- }
882
- else {
883
- // update the pagination service with the new total
884
- this.paginationService.updateTotalItems(this.totalItems);
885
- }
886
- }
887
- // resize the grid inside a slight timeout, in case other DOM element changed prior to the resize (like a filter/pagination changed)
888
- if (this.grid && this._gridOptions.enableAutoResize) {
889
- const delay = this._gridOptions.autoResize && this._gridOptions.autoResize.delay;
890
- this.resizerService.resizeGrid(delay || 10);
891
- }
892
- }
893
- }
894
- }
895
- /**
896
- * Show the filter row displayed on first row, we can optionally pass false to hide it.
897
- * @param showing
898
- */
899
- showHeaderRow(showing = true) {
900
- this.grid.setHeaderRowVisibility(showing, false);
901
- if (showing === true && this._isGridInitialized) {
902
- this.grid.setColumns(this.props.columnDefinitions);
903
- }
904
- return showing;
905
- }
906
- /**
907
- * Check if there's any Pagination Presets defined in the Grid Options,
908
- * if there are then load them in the paginationOptions object
909
- */
910
- setPaginationOptionsWhenPresetDefined(gridOptions, paginationOptions) {
911
- var _a;
912
- if (((_a = gridOptions.presets) === null || _a === void 0 ? void 0 : _a.pagination) && gridOptions.pagination) {
913
- paginationOptions.pageSize = gridOptions.presets.pagination.pageSize;
914
- paginationOptions.pageNumber = gridOptions.presets.pagination.pageNumber;
915
- }
916
- return paginationOptions;
917
- }
918
- /**
919
- * Dynamically change or update the column definitions list.
920
- * We will re-render the grid so that the new header and data shows up correctly.
921
- * If using i18n, we also need to trigger a re-translate of the column headers
922
- */
923
- updateColumnDefinitionsList(newColumnDefinitions) {
924
- var _a, _b, _c;
925
- if (this.grid && this._gridOptions && Array.isArray(newColumnDefinitions)) {
926
- // map/swap the internal library Editor to the SlickGrid Editor factory
927
- newColumnDefinitions = this.swapInternalEditorToSlickGridFactoryEditor(newColumnDefinitions);
928
- // if the user wants to automatically add a Custom Editor Formatter, we need to call the auto add function again
929
- if (this._gridOptions.autoAddCustomEditorFormatter) {
930
- (0, common_1.autoAddEditorFormatterToColumnsWithEditor)(newColumnDefinitions, this._gridOptions.autoAddCustomEditorFormatter);
931
- }
932
- if (this._gridOptions.enableTranslate) {
933
- this.extensionService.translateColumnHeaders(false, newColumnDefinitions);
934
- }
935
- else {
936
- this.extensionService.renderColumnHeaders(newColumnDefinitions, true);
937
- }
938
- if ((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.enableAutoSizeColumns) {
939
- this.grid.autosizeColumns();
940
- }
941
- else if (((_b = this._gridOptions) === null || _b === void 0 ? void 0 : _b.enableAutoResizeColumnsByCellContent) && ((_c = this.resizerService) === null || _c === void 0 ? void 0 : _c.resizeColumnsByCellContent)) {
942
- this.resizerService.resizeColumnsByCellContent();
943
- }
944
- }
945
- }
946
- //
947
- // protected functions
948
- // ------------------
949
- /**
950
- * Loop through all column definitions and copy the original optional `width` properties optionally provided by the user.
951
- * We will use this when doing a resize by cell content, if user provided a `width` it won't override it.
952
- */
953
- copyColumnWidthsReference(columnDefinitions) {
954
- columnDefinitions.forEach(col => col.originalWidth = col.width);
955
- }
956
- displayEmptyDataWarning(showWarning = true) {
957
- var _a;
958
- (_a = this.slickEmptyWarning) === null || _a === void 0 ? void 0 : _a.showEmptyDataMessage(showWarning);
959
- }
960
- /** When data changes in the DataView, we'll refresh the metrics and/or display a warning if the dataset is empty */
961
- handleOnItemCountChanged(currentPageRowItemCount, totalItemCount) {
962
- var _a;
963
- this._currentDatasetLength = totalItemCount;
964
- this.metrics = {
965
- startTime: new Date(),
966
- endTime: new Date(),
967
- itemCount: currentPageRowItemCount,
968
- totalItemCount
969
- };
970
- // if custom footer is enabled, then we'll update its metrics
971
- if (this.slickFooter) {
972
- this.slickFooter.metrics = this.metrics;
973
- }
974
- // when using local (in-memory) dataset, we'll display a warning message when filtered data is empty
975
- if (this._isLocalGrid && ((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.enableEmptyDataWarningMessage)) {
976
- this.displayEmptyDataWarning(currentPageRowItemCount === 0);
977
- }
978
- }
979
- /** Initialize the Pagination Service once */
980
- initializePaginationService(paginationOptions) {
981
- if (this.grid && this.gridOptions) {
982
- this.paginationData = {
983
- gridOptions: this.gridOptions,
984
- paginationService: this.paginationService,
985
- };
986
- this.paginationService.totalItems = this.totalItems;
987
- this.paginationService.init(this.grid, paginationOptions, this.backendServiceApi);
988
- this.subscriptions.push(this._eventPubSubService.subscribe('onPaginationChanged', paginationChanges => this.paginationChanged(paginationChanges)), this._eventPubSubService.subscribe('onPaginationOptionsChanged', paginationChanges => this.paginationOptionsChanged(paginationChanges)), this._eventPubSubService.subscribe('onPaginationVisibilityChanged', (visibility) => {
989
- var _a, _b, _c;
990
- this.showPagination = (_a = visibility === null || visibility === void 0 ? void 0 : visibility.visible) !== null && _a !== void 0 ? _a : false;
991
- if ((_b = this.gridOptions) === null || _b === void 0 ? void 0 : _b.backendServiceApi) {
992
- (_c = this.backendUtilityService) === null || _c === void 0 ? void 0 : _c.refreshBackendDataset(this.gridOptions);
993
- }
994
- this.renderPagination(this.showPagination);
995
- }));
996
- // also initialize (render) the pagination component
997
- this.renderPagination();
998
- this._isPaginationInitialized = true;
999
- }
1000
- }
1001
- /**
1002
- * Render (or dispose) the Pagination Component, user can optionally provide False (to not show it) which will in term dispose of the Pagination,
1003
- * also while disposing we can choose to omit the disposable of the Pagination Service (if we are simply toggling the Pagination, we want to keep the Service alive)
1004
- * @param {Boolean} showPagination - show (new render) or not (dispose) the Pagination
1005
- * @param {Boolean} shouldDisposePaginationService - when disposing the Pagination, do we also want to dispose of the Pagination Service? (defaults to True)
1006
- */
1007
- renderPagination(showPagination = true) {
1008
- var _a;
1009
- if (((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.enablePagination) && !this._isPaginationInitialized && showPagination) {
1010
- this.slickPagination = new pagination_component_1.SlickPaginationComponent(this.paginationService, this._eventPubSubService, this.sharedService, this.props.translaterService);
1011
- this.slickPagination.renderPagination(this._elm);
1012
- this._isPaginationInitialized = true;
1013
- }
1014
- else if (!showPagination) {
1015
- if (this.slickPagination) {
1016
- this.slickPagination.dispose();
1017
- }
1018
- this._isPaginationInitialized = false;
1019
- }
1020
- }
1021
- /** Load the Editor Collection asynchronously and replace the "collection" property when Promise resolves */
1022
- loadEditorCollectionAsync(column) {
1023
- var _a;
1024
- const collectionAsync = (column === null || column === void 0 ? void 0 : column.editor).collectionAsync;
1025
- (column === null || column === void 0 ? void 0 : column.editor).disabled = true; // disable the Editor DOM element, we'll re-enable it after receiving the collection with "updateEditorCollection()"
1026
- if (collectionAsync instanceof Promise) {
1027
- // wait for the "collectionAsync", once resolved we will save it into the "collection"
1028
- // the collectionAsync can be of 3 types HttpClient, HttpFetch or a Promise
1029
- collectionAsync.then((response) => {
1030
- if (Array.isArray(response)) {
1031
- this.updateEditorCollection(column, response); // from Promise
1032
- }
1033
- else if (response instanceof Response && typeof response.json === 'function') {
1034
- if (response.bodyUsed) {
1035
- console.warn(`[SlickGrid-React] The response body passed to collectionAsync was already read.`
1036
- + `Either pass the dataset from the Response or clone the response first using response.clone()`);
1037
- }
1038
- else {
1039
- // from Fetch
1040
- response.json().then(data => this.updateEditorCollection(column, data));
1041
- }
1042
- }
1043
- else if (response === null || response === void 0 ? void 0 : response.content) {
1044
- this.updateEditorCollection(column, response.content); // from http-client
1045
- }
1046
- });
1047
- }
1048
- else if ((_a = this.rxjs) === null || _a === void 0 ? void 0 : _a.isObservable(collectionAsync)) {
1049
- // wrap this inside a setTimeout to avoid timing issue since updateEditorCollection requires to call SlickGrid getColumns() method
1050
- setTimeout(() => {
1051
- this.subscriptions.push(collectionAsync.subscribe((resolvedCollection) => this.updateEditorCollection(column, resolvedCollection)));
1052
- });
1053
- }
1054
- }
1055
- insertDynamicPresetColumns(columnId, gridPresetColumns) {
1056
- if (this._columnDefinitions) {
1057
- const columnPosition = this._columnDefinitions.findIndex(c => c.id === columnId);
1058
- if (columnPosition >= 0) {
1059
- const dynColumn = this._columnDefinitions[columnPosition];
1060
- if ((dynColumn === null || dynColumn === void 0 ? void 0 : dynColumn.id) === columnId && !gridPresetColumns.some(c => c.id === columnId)) {
1061
- columnPosition > 0
1062
- ? gridPresetColumns.splice(columnPosition, 0, dynColumn)
1063
- : gridPresetColumns.unshift(dynColumn);
1064
- }
1065
- }
1066
- }
1067
- }
1068
- /** Load any possible Columns Grid Presets */
1069
- loadColumnPresetsWhenDatasetInitialized() {
1070
- var _a, _b, _c, _d, _f, _g, _h, _j, _k;
1071
- // if user entered some Columns "presets", we need to reflect them all in the grid
1072
- if (this.grid && this.gridOptions.presets && Array.isArray(this.gridOptions.presets.columns) && this.gridOptions.presets.columns.length > 0) {
1073
- const gridPresetColumns = this.gridStateService.getAssociatedGridColumns(this.grid, this.gridOptions.presets.columns);
1074
- if (gridPresetColumns && Array.isArray(gridPresetColumns) && gridPresetColumns.length > 0 && Array.isArray(this._columnDefinitions)) {
1075
- // make sure that the dynamic columns are included in presets (1.Row Move, 2. Row Selection, 3. Row Detail)
1076
- if (this.gridOptions.enableRowMoveManager) {
1077
- const rmmColId = (_c = (_b = (_a = this.gridOptions) === null || _a === void 0 ? void 0 : _a.rowMoveManager) === null || _b === void 0 ? void 0 : _b.columnId) !== null && _c !== void 0 ? _c : '_move';
1078
- this.insertDynamicPresetColumns(rmmColId, gridPresetColumns);
1079
- }
1080
- if (this.gridOptions.enableCheckboxSelector) {
1081
- const chkColId = (_g = (_f = (_d = this.gridOptions) === null || _d === void 0 ? void 0 : _d.checkboxSelector) === null || _f === void 0 ? void 0 : _f.columnId) !== null && _g !== void 0 ? _g : '_checkbox_selector';
1082
- this.insertDynamicPresetColumns(chkColId, gridPresetColumns);
1083
- }
1084
- if (this.gridOptions.enableRowDetailView) {
1085
- const rdvColId = (_k = (_j = (_h = this.gridOptions) === null || _h === void 0 ? void 0 : _h.rowDetailView) === null || _j === void 0 ? void 0 : _j.columnId) !== null && _k !== void 0 ? _k : '_detail_selector';
1086
- this.insertDynamicPresetColumns(rdvColId, gridPresetColumns);
1087
- }
1088
- // keep copy the original optional `width` properties optionally provided by the user.
1089
- // We will use this when doing a resize by cell content, if user provided a `width` it won't override it.
1090
- gridPresetColumns.forEach(col => col.originalWidth = col.width);
1091
- // finally set the new presets columns (including checkbox selector if need be)
1092
- this.grid.setColumns(gridPresetColumns);
1093
- this.sharedService.visibleColumns = gridPresetColumns;
1094
- }
1095
- }
1096
- }
1097
- /** Load any possible Filters Grid Presets */
1098
- loadFilterPresetsWhenDatasetInitialized() {
1099
- var _a, _b, _c;
1100
- if (this._gridOptions && !this.props.customDataView) {
1101
- // if user entered some Filter "presets", we need to reflect them all in the DOM
1102
- if (this._gridOptions.presets && (Array.isArray(this._gridOptions.presets.filters) || Array.isArray((_b = (_a = this._gridOptions.presets) === null || _a === void 0 ? void 0 : _a.treeData) === null || _b === void 0 ? void 0 : _b.toggledItems))) {
1103
- this.filterService.populateColumnFilterSearchTermPresets(((_c = this._gridOptions.presets) === null || _c === void 0 ? void 0 : _c.filters) || []);
1104
- }
1105
- }
1106
- }
1107
- /**
1108
- * local grid, check if we need to show the Pagination
1109
- * if so then also check if there's any presets and finally initialize the PaginationService
1110
- * a local grid with Pagination presets will potentially have a different total of items, we'll need to get it from the DataView and update our total
1111
- */
1112
- loadLocalGridPagination(dataset) {
1113
- var _a;
1114
- if (this._gridOptions && this._paginationOptions) {
1115
- this.totalItems = Array.isArray(dataset) ? dataset.length : 0;
1116
- if (this._paginationOptions && ((_a = this.dataView) === null || _a === void 0 ? void 0 : _a.getPagingInfo)) {
1117
- const slickPagingInfo = this.dataView.getPagingInfo();
1118
- if ((slickPagingInfo === null || slickPagingInfo === void 0 ? void 0 : slickPagingInfo.hasOwnProperty('totalRows')) && this._paginationOptions.totalItems !== slickPagingInfo.totalRows) {
1119
- this.totalItems = slickPagingInfo.totalRows || 0;
1120
- }
1121
- }
1122
- this._paginationOptions.totalItems = this.totalItems;
1123
- const paginationOptions = this.setPaginationOptionsWhenPresetDefined(this._gridOptions, this._paginationOptions);
1124
- this.initializePaginationService(paginationOptions);
1125
- }
1126
- }
1127
- /** Load any Row Selections into the DataView that were presets by the user */
1128
- loadRowSelectionPresetWhenExists() {
1129
- var _a, _b;
1130
- // if user entered some Row Selections "presets"
1131
- const presets = (_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.presets;
1132
- const enableRowSelection = this._gridOptions && (this._gridOptions.enableCheckboxSelector || this._gridOptions.enableRowSelection);
1133
- if (enableRowSelection && ((_b = this.grid) === null || _b === void 0 ? void 0 : _b.getSelectionModel()) && (presets === null || presets === void 0 ? void 0 : presets.rowSelection) && (Array.isArray(presets.rowSelection.gridRowIndexes) || Array.isArray(presets.rowSelection.dataContextIds))) {
1134
- let dataContextIds = presets.rowSelection.dataContextIds;
1135
- let gridRowIndexes = presets.rowSelection.gridRowIndexes;
1136
- // maps the IDs to the Grid Rows and vice versa, the "dataContextIds" has precedence over the other
1137
- if (Array.isArray(dataContextIds) && dataContextIds.length > 0) {
1138
- gridRowIndexes = this.dataView.mapIdsToRows(dataContextIds) || [];
1139
- }
1140
- else if (Array.isArray(gridRowIndexes) && gridRowIndexes.length > 0) {
1141
- dataContextIds = this.dataView.mapRowsToIds(gridRowIndexes) || [];
1142
- }
1143
- // apply row selection when defined as grid presets
1144
- if (this.grid && Array.isArray(gridRowIndexes)) {
1145
- this.grid.setSelectedRows(gridRowIndexes);
1146
- this.dataView.setSelectedIds(dataContextIds || [], {
1147
- isRowBeingAdded: true,
1148
- shouldTriggerEvent: false,
1149
- applyRowSelectionToGrid: true
1150
- });
1151
- }
1152
- }
1153
- }
1154
- mergeGridOptions(gridOptions) {
1155
- // use jquery extend to deep merge & copy to avoid immutable properties being changed in GlobalGridOptions after a route change
1156
- const options = $.extend(true, {}, global_grid_options_1.GlobalGridOptions, gridOptions);
1157
- options.gridId = this.props.gridId;
1158
- options.gridContainerId = `slickGridContainer-${this.props.gridId}`;
1159
- // also make sure to show the header row if user have enabled filtering
1160
- if (options.enableFiltering && !options.showHeaderRow) {
1161
- options.showHeaderRow = options.enableFiltering;
1162
- }
1163
- // if we have a backendServiceApi and the enablePagination is undefined, we'll assume that we do want to see it, else get that defined value
1164
- options.enablePagination = ((gridOptions.backendServiceApi && gridOptions.enablePagination === undefined) ? true : gridOptions.enablePagination) || false;
1165
- // using jQuery extend to do a deep clone has an unwanted side on objects and pageSizes but ES6 spread has other worst side effects
1166
- // so we will just overwrite the pageSizes when needed, this is the only one causing issues so far.
1167
- // jQuery wrote this on their docs:: On a deep extend, Object and Array are extended, but object wrappers on primitive types such as String, Boolean, and Number are not.
1168
- if ((options === null || options === void 0 ? void 0 : options.pagination) && (gridOptions.enablePagination || gridOptions.backendServiceApi) && gridOptions.pagination && Array.isArray(gridOptions.pagination.pageSizes)) {
1169
- options.pagination.pageSizes = gridOptions.pagination.pageSizes;
1170
- }
1171
- // when we use Pagination on Local Grid, it doesn't seem to work without enableFiltering
1172
- // so we'll enable the filtering but we'll keep the header row hidden
1173
- if (this.sharedService && !options.enableFiltering && options.enablePagination && this._isLocalGrid) {
1174
- options.enableFiltering = true;
1175
- options.showHeaderRow = false;
1176
- this._hideHeaderRowAfterPageLoad = true;
1177
- this.sharedService.hideHeaderRowAfterPageLoad = true;
1178
- }
1179
- return options;
1180
- }
1181
- /** Pre-Register any Resource that don't require SlickGrid to be instantiated (for example RxJS Resource) */
1182
- preRegisterResources() {
1183
- this._registeredResources = this.gridOptions.registerExternalResources || [];
1184
- // bind & initialize all Components/Services that were tagged as enabled
1185
- // register all services by executing their init method and providing them with the Grid object
1186
- if (Array.isArray(this._registeredResources)) {
1187
- for (const resource of this._registeredResources) {
1188
- if ((resource === null || resource === void 0 ? void 0 : resource.className) === 'RxJsResource') {
1189
- this.registerRxJsResource(resource);
1190
- }
1191
- }
1192
- }
1193
- }
1194
- registerResources() {
1195
- // at this point, we consider all the registered services as external services, anything else registered afterward aren't external
1196
- if (Array.isArray(this._registeredResources)) {
1197
- this.sharedService.externalRegisteredResources = this._registeredResources;
1198
- }
1199
- // push all other Services that we want to be registered
1200
- this._registeredResources.push(this.gridService, this.gridStateService);
1201
- // when using Grouping/DraggableGrouping/Colspan register its Service
1202
- if (this.gridOptions.createPreHeaderPanel && !this.gridOptions.enableDraggableGrouping) {
1203
- this._registeredResources.push(this.groupingService);
1204
- }
1205
- // when using Tree Data View, register its Service
1206
- if (this.gridOptions.enableTreeData) {
1207
- this._registeredResources.push(this.treeDataService);
1208
- }
1209
- // when user enables translation, we need to translate Headers on first pass & subsequently in the bindDifferentHooks
1210
- if (this.gridOptions.enableTranslate) {
1211
- this.extensionService.translateColumnHeaders();
1212
- }
1213
- // also initialize (render) the empty warning component
1214
- this.slickEmptyWarning = new empty_warning_component_1.SlickEmptyWarningComponent();
1215
- this._registeredResources.push(this.slickEmptyWarning);
1216
- // bind & initialize all Components/Services that were tagged as enabled
1217
- // register all services by executing their init method and providing them with the Grid object
1218
- if (Array.isArray(this._registeredResources)) {
1219
- for (const resource of this._registeredResources) {
1220
- if (this.grid && typeof resource.init === 'function') {
1221
- resource.init(this.grid, this.props.containerService);
1222
- }
1223
- }
1224
- }
1225
- }
1226
- /** Register the RxJS Resource in all necessary services which uses */
1227
- registerRxJsResource(resource) {
1228
- this.rxjs = resource;
1229
- this.backendUtilityService.addRxJsResource(this.rxjs);
1230
- this.filterFactory.addRxJsResource(this.rxjs);
1231
- this.filterService.addRxJsResource(this.rxjs);
1232
- this.sortService.addRxJsResource(this.rxjs);
1233
- this.paginationService.addRxJsResource(this.rxjs);
1234
- this.props.containerService.registerInstance('RxJsResource', this.rxjs);
1235
- }
1236
- /**
1237
- * Takes a flat dataset with parent/child relationship, sort it (via its tree structure) and return the sorted flat array
1238
- * @param {Array<Object>} flatDatasetInput - flat dataset input
1239
- * @param {Boolean} forceGridRefresh - optionally force a full grid refresh
1240
- * @returns {Array<Object>} sort flat parent/child dataset
1241
- */
1242
- sortTreeDataset(flatDatasetInput, forceGridRefresh = false) {
1243
- var _a, _b;
1244
- const prevDatasetLn = this._currentDatasetLength;
1245
- let sortedDatasetResult;
1246
- let flatDatasetOutput = [];
1247
- // if the hierarchical dataset was already initialized then no need to re-convert it, we can use it directly from the shared service ref
1248
- if (this._isDatasetHierarchicalInitialized && this.datasetHierarchical) {
1249
- sortedDatasetResult = this.treeDataService.sortHierarchicalDataset(this.datasetHierarchical);
1250
- flatDatasetOutput = sortedDatasetResult.flat;
1251
- }
1252
- else if (Array.isArray(flatDatasetInput) && flatDatasetInput.length > 0) {
1253
- if ((_b = (_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.treeDataOptions) === null || _b === void 0 ? void 0 : _b.initialSort) {
1254
- // else we need to first convert the flat dataset to a hierarchical dataset and then sort
1255
- sortedDatasetResult = this.treeDataService.convertFlatParentChildToTreeDatasetAndSort(flatDatasetInput, this._columnDefinitions, this._gridOptions);
1256
- this.sharedService.hierarchicalDataset = sortedDatasetResult.hierarchical;
1257
- flatDatasetOutput = sortedDatasetResult.flat;
1258
- }
1259
- else {
1260
- // else we assume that the user provided an array that is already sorted (user's responsability)
1261
- // and so we can simply convert the array to a tree structure and we're done, no need to sort
1262
- this.sharedService.hierarchicalDataset = this.treeDataService.convertFlatParentChildToTreeDataset(flatDatasetInput, this.gridOptions);
1263
- flatDatasetOutput = flatDatasetInput || [];
1264
- }
1265
- }
1266
- // if we add/remove item(s) from the dataset, we need to also refresh our tree data filters
1267
- if (flatDatasetInput.length > 0 && (forceGridRefresh || flatDatasetInput.length !== prevDatasetLn)) {
1268
- this.filterService.refreshTreeDataFilters(flatDatasetOutput);
1269
- }
1270
- return flatDatasetOutput;
1271
- }
1272
- /**
1273
- * For convenience to the user, we provide the property "editor" as an Slickgrid-React editor complex object
1274
- * however "editor" is used internally by SlickGrid for it's own Editor Factory
1275
- * so in our lib we will swap "editor" and copy it into a new property called "internalColumnEditor"
1276
- * then take back "editor.model" and make it the new "editor" so that SlickGrid Editor Factory still works
1277
- */
1278
- swapInternalEditorToSlickGridFactoryEditor(columnDefinitions) {
1279
- if (columnDefinitions.some(col => `${col.id}`.includes('.'))) {
1280
- console.error('[Slickgrid-React] Make sure that none of your Column Definition "id" property includes a dot in its name because that will cause some problems with the Editors. For example if your column definition "field" property is "user.firstName" then use "firstName" as the column "id".');
1281
- }
1282
- return columnDefinitions.map((column) => {
1283
- var _a, _b;
1284
- // on every Editor which have a "collection" or a "collectionAsync"
1285
- if ((_a = column.editor) === null || _a === void 0 ? void 0 : _a.collectionAsync) {
1286
- this.loadEditorCollectionAsync(column);
1287
- }
1288
- return Object.assign(Object.assign({}, column), { editor: (_b = column.editor) === null || _b === void 0 ? void 0 : _b.model, internalColumnEditor: Object.assign({}, column.editor) });
1289
- });
1290
- }
1291
- /** translate all columns (including hidden columns) */
1292
- translateColumnHeaderTitleKeys() {
1293
- this.extensionUtility.translateItems(this.sharedService.allColumns, 'nameKey', 'name');
1294
- }
1295
- /** translate all column groups (including hidden columns) */
1296
- translateColumnGroupKeys() {
1297
- this.extensionUtility.translateItems(this.sharedService.allColumns, 'columnGroupKey', 'columnGroup');
1298
- }
1299
- /**
1300
- * Update the "internalColumnEditor.collection" property.
1301
- * Since this is called after the async call resolves, the pointer will not be the same as the "column" argument passed.
1302
- * Once we found the new pointer, we will reassign the "editor" and "collection" to the "internalColumnEditor" so it has newest collection
1303
- */
1304
- updateEditorCollection(column, newCollection) {
1305
- column.editor.collection = newCollection;
1306
- column.editor.disabled = false;
1307
- // find the new column reference pointer & re-assign the new editor to the internalColumnEditor
1308
- if (Array.isArray(this._columnDefinitions)) {
1309
- const columnRef = this._columnDefinitions.find((col) => col.id === column.id);
1310
- if (columnRef) {
1311
- columnRef.internalColumnEditor = column.editor;
1312
- }
1313
- }
1314
- // get current Editor, remove it from the DOM then re-enable it and re-render it with the new collection.
1315
- const currentEditor = this.grid.getCellEditor();
1316
- if ((currentEditor === null || currentEditor === void 0 ? void 0 : currentEditor.disable) && (currentEditor === null || currentEditor === void 0 ? void 0 : currentEditor.renderDomElement)) {
1317
- currentEditor.destroy();
1318
- currentEditor.disable(false);
1319
- currentEditor.renderDomElement(newCollection);
1320
- }
1321
- }
1322
- render() {
1323
- return (react_1.default.createElement("div", { id: `slickGridContainer-${this.props.gridId}`, className: "grid-pane", ref: elm => this._elm = elm },
1324
- this.props.header && react_1.default.createElement("div", { className: "header" }, this.props.header),
1325
- react_1.default.createElement("div", { id: `${this.props.gridId}`, className: "slickgrid-container", style: { width: '100%' }, onBlur: $event => this.commitEdit($event.target) }),
1326
- this.props.footer && react_1.default.createElement("div", { className: "footer" }, this.props.footer)));
1327
- }
1328
- }
1329
- exports.SlickgridReact = SlickgridReact;
1330
- SlickgridReact.defaultProps = {
1331
- reactUtilService: new index_1.ReactUtilService(),
1332
- containerService: singletons_1.GlobalContainerService,
1333
- translaterService: new index_1.TranslaterService(),
1334
- dataset: [],
1335
- gridId: '',
1336
- columnDefinitions: [],
1337
- };
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ var _a;
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.SlickgridReact = void 0;
31
+ // import 3rd party vendor libs
32
+ const i18next_1 = __importDefault(require("i18next"));
33
+ const react_1 = __importDefault(require("react"));
34
+ require("slickgrid/slick.core");
35
+ require("slickgrid/slick.interactions");
36
+ require("slickgrid/slick.grid");
37
+ require("slickgrid/slick.dataview");
38
+ const Sortable_ = __importStar(require("sortablejs"));
39
+ const Sortable = ((_a = Sortable_ === null || Sortable_ === void 0 ? void 0 : Sortable_['default']) !== null && _a !== void 0 ? _a : Sortable_); // patch for rollup
40
+ const common_1 = require("@slickgrid-universal/common");
41
+ const event_pub_sub_1 = require("@slickgrid-universal/event-pub-sub");
42
+ const custom_footer_component_1 = require("@slickgrid-universal/custom-footer-component");
43
+ const empty_warning_component_1 = require("@slickgrid-universal/empty-warning-component");
44
+ const pagination_component_1 = require("@slickgrid-universal/pagination-component");
45
+ const lite_1 = require("dequal/lite");
46
+ const constants_1 = require("../constants");
47
+ const global_grid_options_1 = require("../global-grid-options");
48
+ const index_1 = require("../services/index");
49
+ const singletons_1 = require("../services/singletons");
50
+ // add Sortable to the window object so that SlickGrid lib can use globally
51
+ window.Sortable = Sortable;
52
+ class CustomEventPubSubService extends event_pub_sub_1.EventPubSubService {
53
+ set elementSource(value) {
54
+ this._elementSource = value;
55
+ }
56
+ }
57
+ class SlickgridReact extends react_1.default.Component {
58
+ setStateValue(key, value, callback) {
59
+ var _a;
60
+ if (((_a = this.state) === null || _a === void 0 ? void 0 : _a[key]) === value) {
61
+ return;
62
+ }
63
+ if (!this._mounted) {
64
+ this.state = this.state || {};
65
+ this.state[key] = value;
66
+ return;
67
+ }
68
+ this.setState(() => {
69
+ const result = {};
70
+ result[key] = value;
71
+ return result;
72
+ }, callback);
73
+ }
74
+ get gridOptions() {
75
+ return this._gridOptions || {};
76
+ }
77
+ set gridOptions(options) {
78
+ var _a, _b, _c;
79
+ let mergedOptions;
80
+ // if we already have grid options, when grid was already initialized, we'll merge with those options
81
+ // else we'll merge with global grid options
82
+ if ((_a = this.grid) === null || _a === void 0 ? void 0 : _a.getOptions) {
83
+ mergedOptions = Slick.Utils.extend(true, {}, this.grid.getOptions(), options);
84
+ }
85
+ else {
86
+ mergedOptions = this.mergeGridOptions(options);
87
+ }
88
+ if (((_b = this.sharedService) === null || _b === void 0 ? void 0 : _b.gridOptions) && ((_c = this.grid) === null || _c === void 0 ? void 0 : _c.setOptions)) {
89
+ this.sharedService.gridOptions = mergedOptions;
90
+ this.grid.setOptions(mergedOptions, false, true); // make sure to supressColumnCheck (3rd arg) to avoid problem with changeColumnsArrangement() and custom grid view
91
+ this.grid.reRenderColumns(true); // then call a re-render since we did supressColumnCheck on previous setOptions
92
+ }
93
+ this._gridOptions = mergedOptions;
94
+ }
95
+ get paginationService() {
96
+ var _a;
97
+ return (_a = this.state) === null || _a === void 0 ? void 0 : _a.paginationService;
98
+ }
99
+ set paginationService(value) {
100
+ this.setStateValue('paginationService', value);
101
+ }
102
+ get dataset() {
103
+ var _a;
104
+ return ((_a = this.dataView) === null || _a === void 0 ? void 0 : _a.getItems()) || [];
105
+ }
106
+ set dataset(newDataset) {
107
+ var _a, _b;
108
+ const prevDatasetLn = this._currentDatasetLength;
109
+ const isDatasetEqual = (0, lite_1.dequal)(newDataset, this.dataset || []);
110
+ const isDeepCopyDataOnPageLoadEnabled = !!((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.enableDeepCopyDatasetOnPageLoad);
111
+ let data = isDeepCopyDataOnPageLoadEnabled ? Slick.Utils.extend(true, [], newDataset) : newDataset;
112
+ // when Tree Data is enabled and we don't yet have the hierarchical dataset filled, we can force a convert+sort of the array
113
+ if (this.grid && ((_b = this.gridOptions) === null || _b === void 0 ? void 0 : _b.enableTreeData) && Array.isArray(newDataset) && (newDataset.length > 0 || newDataset.length !== prevDatasetLn || !isDatasetEqual)) {
114
+ this._isDatasetHierarchicalInitialized = false;
115
+ data = this.sortTreeDataset(newDataset, !isDatasetEqual); // if dataset changed, then force a refresh anyway
116
+ }
117
+ this.refreshGridData(data || []);
118
+ this._currentDatasetLength = (newDataset || []).length;
119
+ // expand/autofit columns on first page load
120
+ // we can assume that if the prevDataset was empty then we are on first load
121
+ if (this.grid && this.gridOptions.autoFitColumnsOnFirstLoad && prevDatasetLn === 0) {
122
+ this.grid.autosizeColumns();
123
+ }
124
+ }
125
+ get datasetHierarchical() {
126
+ return this.sharedService.hierarchicalDataset;
127
+ }
128
+ set datasetHierarchical(newHierarchicalDataset) {
129
+ var _a, _b, _c, _d, _f, _g;
130
+ const isDatasetEqual = (0, lite_1.dequal)(newHierarchicalDataset, (_b = (_a = this.sharedService) === null || _a === void 0 ? void 0 : _a.hierarchicalDataset) !== null && _b !== void 0 ? _b : []);
131
+ const prevFlatDatasetLn = this._currentDatasetLength;
132
+ this.sharedService.hierarchicalDataset = newHierarchicalDataset;
133
+ if (newHierarchicalDataset && this.props.columnDefinitions && ((_c = this.filterService) === null || _c === void 0 ? void 0 : _c.clearFilters)) {
134
+ this.filterService.clearFilters();
135
+ }
136
+ // when a hierarchical dataset is set afterward, we can reset the flat dataset and call a tree data sort that will overwrite the flat dataset
137
+ if (this.dataView && newHierarchicalDataset && this.grid && ((_d = this.sortService) === null || _d === void 0 ? void 0 : _d.processTreeDataInitialSort)) {
138
+ this.dataView.setItems([], (_g = (_f = this._gridOptions) === null || _f === void 0 ? void 0 : _f.datasetIdPropertyName) !== null && _g !== void 0 ? _g : 'id');
139
+ this.sortService.processTreeDataInitialSort();
140
+ // we also need to reset/refresh the Tree Data filters because if we inserted new item(s) then it might not show up without doing this refresh
141
+ // however we need 1 cpu cycle before having the DataView refreshed, so we need to wrap this check in a setTimeout
142
+ setTimeout(() => {
143
+ var _a, _b;
144
+ const flatDatasetLn = (_b = (_a = this.dataView) === null || _a === void 0 ? void 0 : _a.getItemCount()) !== null && _b !== void 0 ? _b : 0;
145
+ if (flatDatasetLn > 0 && (flatDatasetLn !== prevFlatDatasetLn || !isDatasetEqual)) {
146
+ this.filterService.refreshTreeDataFilters();
147
+ }
148
+ });
149
+ }
150
+ this._isDatasetHierarchicalInitialized = true;
151
+ }
152
+ constructor(props) {
153
+ var _a, _b, _c, _d, _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;
154
+ super(props);
155
+ this.props = props;
156
+ this._mounted = false;
157
+ this._columnDefinitions = [];
158
+ this._currentDatasetLength = 0;
159
+ this._dataset = null;
160
+ this._hideHeaderRowAfterPageLoad = false;
161
+ this._isGridInitialized = false;
162
+ this._isDatasetInitialized = false;
163
+ this._isDatasetHierarchicalInitialized = false;
164
+ this._isPaginationInitialized = false;
165
+ this._isLocalGrid = true;
166
+ this._registeredResources = [];
167
+ this.showPagination = false;
168
+ this.serviceList = [];
169
+ this.subscriptions = [];
170
+ this.totalItems = 0;
171
+ this.instances = null;
172
+ const slickgridConfig = new common_1.SlickgridConfig();
173
+ this._eventHandler = new Slick.EventHandler();
174
+ this.showPagination = false;
175
+ // check if the user wants to hide the header row from the start
176
+ // we only want to do this check once in the constructor
177
+ this._hideHeaderRowAfterPageLoad = (((_a = props.gridOptions) === null || _a === void 0 ? void 0 : _a.showHeaderRow) === false);
178
+ this._gridOptions = this.mergeGridOptions(props.gridOptions || {});
179
+ // initialize and assign all Service Dependencies
180
+ this._eventPubSubService = (_c = (_b = this.props.externalServices) === null || _b === void 0 ? void 0 : _b.eventPubSubService) !== null && _c !== void 0 ? _c : new CustomEventPubSubService();
181
+ this._eventPubSubService.eventNamingStyle = common_1.EventNamingStyle.camelCase;
182
+ this.backendUtilityService = (_f = (_d = this.props.externalServices) === null || _d === void 0 ? void 0 : _d.backendUtilityService) !== null && _f !== void 0 ? _f : new common_1.BackendUtilityService();
183
+ this.gridEventService = (_h = (_g = this.props.externalServices) === null || _g === void 0 ? void 0 : _g.gridEventService) !== null && _h !== void 0 ? _h : new common_1.GridEventService();
184
+ this.sharedService = (_k = (_j = this.props.externalServices) === null || _j === void 0 ? void 0 : _j.sharedService) !== null && _k !== void 0 ? _k : new common_1.SharedService();
185
+ this.collectionService = (_m = (_l = this.props.externalServices) === null || _l === void 0 ? void 0 : _l.collectionService) !== null && _m !== void 0 ? _m : new common_1.CollectionService(this.props.translaterService);
186
+ this.extensionUtility = (_p = (_o = this.props.externalServices) === null || _o === void 0 ? void 0 : _o.extensionUtility) !== null && _p !== void 0 ? _p : new common_1.ExtensionUtility(this.sharedService, this.backendUtilityService, this.props.translaterService);
187
+ this.filterFactory = new common_1.FilterFactory(slickgridConfig, this.props.translaterService, this.collectionService);
188
+ this.filterService = (_r = (_q = this.props.externalServices) === null || _q === void 0 ? void 0 : _q.filterService) !== null && _r !== void 0 ? _r : new common_1.FilterService(this.filterFactory, this._eventPubSubService, this.sharedService, this.backendUtilityService);
189
+ this.resizerService = (_t = (_s = this.props.externalServices) === null || _s === void 0 ? void 0 : _s.resizerService) !== null && _t !== void 0 ? _t : new common_1.ResizerService(this._eventPubSubService);
190
+ this.sortService = (_v = (_u = this.props.externalServices) === null || _u === void 0 ? void 0 : _u.sortService) !== null && _v !== void 0 ? _v : new common_1.SortService(this.sharedService, this._eventPubSubService, this.backendUtilityService);
191
+ this.treeDataService = (_x = (_w = this.props.externalServices) === null || _w === void 0 ? void 0 : _w.treeDataService) !== null && _x !== void 0 ? _x : new common_1.TreeDataService(this._eventPubSubService, this.sharedService, this.sortService);
192
+ this.paginationService = (_z = (_y = this.props.externalServices) === null || _y === void 0 ? void 0 : _y.paginationService) !== null && _z !== void 0 ? _z : new common_1.PaginationService(this._eventPubSubService, this.sharedService, this.backendUtilityService);
193
+ this.extensionService = (_1 = (_0 = this.props.externalServices) === null || _0 === void 0 ? void 0 : _0.extensionService) !== null && _1 !== void 0 ? _1 : new common_1.ExtensionService(this.extensionUtility, this.filterService, this._eventPubSubService, this.sharedService, this.sortService, this.treeDataService, this.props.translaterService);
194
+ this.gridStateService = (_3 = (_2 = this.props.externalServices) === null || _2 === void 0 ? void 0 : _2.gridStateService) !== null && _3 !== void 0 ? _3 : new common_1.GridStateService(this.extensionService, this.filterService, this._eventPubSubService, this.sharedService, this.sortService, this.treeDataService);
195
+ this.gridService = (_5 = (_4 = this.props.externalServices) === null || _4 === void 0 ? void 0 : _4.gridService) !== null && _5 !== void 0 ? _5 : new common_1.GridService(this.gridStateService, this.filterService, this._eventPubSubService, this.paginationService, this.sharedService, this.sortService, this.treeDataService);
196
+ this.groupingService = (_7 = (_6 = this.props.externalServices) === null || _6 === void 0 ? void 0 : _6.groupingAndColspanService) !== null && _7 !== void 0 ? _7 : new common_1.GroupingAndColspanService(this.extensionUtility, this._eventPubSubService);
197
+ this.serviceList = [
198
+ this.extensionService,
199
+ this.filterService,
200
+ this.gridEventService,
201
+ this.gridService,
202
+ this.gridStateService,
203
+ this.groupingService,
204
+ this.paginationService,
205
+ this.resizerService,
206
+ this.sortService,
207
+ this.treeDataService,
208
+ ];
209
+ if (this.props.datasetHierarchical) {
210
+ this.sharedService.hierarchicalDataset = this.props.datasetHierarchical || [];
211
+ }
212
+ // register all Service instances in the container
213
+ this.props.containerService.registerInstance('PubSubService', this._eventPubSubService);
214
+ this.props.containerService.registerInstance('EventPubSubService', this._eventPubSubService);
215
+ this.props.containerService.registerInstance('ExtensionUtility', this.extensionUtility);
216
+ this.props.containerService.registerInstance('FilterService', this.filterService);
217
+ this.props.containerService.registerInstance('CollectionService', this.collectionService);
218
+ this.props.containerService.registerInstance('ExtensionService', this.extensionService);
219
+ this.props.containerService.registerInstance('GridEventService', this.gridEventService);
220
+ this.props.containerService.registerInstance('GridService', this.gridService);
221
+ this.props.containerService.registerInstance('GridStateService', this.gridStateService);
222
+ this.props.containerService.registerInstance('GroupingAndColspanService', this.groupingService);
223
+ this.props.containerService.registerInstance('PaginationService', this.paginationService);
224
+ this.props.containerService.registerInstance('ResizerService', this.resizerService);
225
+ this.props.containerService.registerInstance('SharedService', this.sharedService);
226
+ this.props.containerService.registerInstance('SortService', this.sortService);
227
+ this.props.containerService.registerInstance('TranslaterService', this.props.translaterService);
228
+ this.props.containerService.registerInstance('TreeDataService', this.treeDataService);
229
+ }
230
+ get eventHandler() {
231
+ return this._eventHandler;
232
+ }
233
+ get isDatasetInitialized() {
234
+ return this._isDatasetInitialized;
235
+ }
236
+ set isDatasetInitialized(isInitialized) {
237
+ this._isDatasetInitialized = isInitialized;
238
+ }
239
+ set isDatasetHierarchicalInitialized(isInitialized) {
240
+ this._isDatasetHierarchicalInitialized = isInitialized;
241
+ }
242
+ get registeredResources() {
243
+ return this._registeredResources;
244
+ }
245
+ componentDidMount() {
246
+ var _a, _b;
247
+ this._mounted = true;
248
+ if (this._elm && this._eventPubSubService instanceof CustomEventPubSubService) {
249
+ this._eventPubSubService.elementSource = this._elm;
250
+ // React doesn't play well with Custom Events & also the render is called after the constructor which brings a second problem
251
+ // to fix both issues, we need to do the following:
252
+ // loop through all component and subscribe to all props that startsWith "on", assuming they are custom event
253
+ // and call their listener with event is dispatching
254
+ for (const prop in this.props) {
255
+ if (prop.startsWith('on')) {
256
+ this.subscriptions.push(this._eventPubSubService.subscribe(prop, (data) => {
257
+ // eslint-disable-next-line @typescript-eslint/ban-types
258
+ const callback = this.props[prop];
259
+ const gridEventName = this._eventPubSubService.getEventNameByNamingConvention(prop, '');
260
+ typeof callback === 'function' && callback.call(null, new CustomEvent(gridEventName, { detail: data }));
261
+ }));
262
+ }
263
+ }
264
+ }
265
+ this.initialization(this._eventHandler);
266
+ this._isGridInitialized = true;
267
+ if (!this._isPaginationInitialized && !this.props.datasetHierarchical && ((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.enablePagination) && this._isLocalGrid) {
268
+ this.showPagination = true;
269
+ this.loadLocalGridPagination(this.dataset);
270
+ }
271
+ // recheck the empty warning message after grid is shown so that it works in every use case
272
+ if ((_b = this._gridOptions) === null || _b === void 0 ? void 0 : _b.enableEmptyDataWarningMessage) {
273
+ const dataset = this.props.dataset || [];
274
+ if (Array.isArray(dataset)) {
275
+ const finalTotalCount = dataset.length;
276
+ this.displayEmptyDataWarning(finalTotalCount < 1);
277
+ }
278
+ }
279
+ }
280
+ initialization(eventHandler) {
281
+ var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
282
+ if (!this._gridOptions || !this._columnDefinitions) {
283
+ throw new Error('Using `<SlickgridReact>` requires columnDefinitions and gridOptions, it seems that you might have forgot to provide them since at least of them is undefined.');
284
+ }
285
+ this._gridOptions.translater = this.props.translaterService;
286
+ this._eventHandler = eventHandler;
287
+ // when detecting a frozen grid, we'll automatically enable the mousewheel scroll handler so that we can scroll from both left/right frozen containers
288
+ if (this._gridOptions && ((this._gridOptions.frozenRow !== undefined && this._gridOptions.frozenRow >= 0) || this._gridOptions.frozenColumn !== undefined && this._gridOptions.frozenColumn >= 0) && this._gridOptions.enableMouseWheelScrollHandler === undefined) {
289
+ this._gridOptions.enableMouseWheelScrollHandler = true;
290
+ }
291
+ this._eventPubSubService.eventNamingStyle = (_b = (_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.eventNamingStyle) !== null && _b !== void 0 ? _b : common_1.EventNamingStyle.camelCase;
292
+ this._eventPubSubService.publish(`onBeforeGridCreate`, true);
293
+ // make sure the dataset is initialized (if not it will throw an error that it cannot getLength of null)
294
+ this._dataset = this._dataset || this.props.dataset || [];
295
+ this._currentDatasetLength = this._dataset.length;
296
+ this._gridOptions = this.mergeGridOptions(this._gridOptions);
297
+ this._paginationOptions = (_c = this._gridOptions) === null || _c === void 0 ? void 0 : _c.pagination;
298
+ this.locales = (_f = (_d = this._gridOptions) === null || _d === void 0 ? void 0 : _d.locales) !== null && _f !== void 0 ? _f : constants_1.Constants.locales;
299
+ this.backendServiceApi = (_g = this._gridOptions) === null || _g === void 0 ? void 0 : _g.backendServiceApi;
300
+ this._isLocalGrid = !this.backendServiceApi; // considered a local grid if it doesn't have a backend service set
301
+ this.createBackendApiInternalPostProcessCallback(this._gridOptions);
302
+ if (!this.props.customDataView) {
303
+ const dataviewInlineFilters = this._gridOptions.dataView && this._gridOptions.dataView.inlineFilters || false;
304
+ let dataViewOptions = { inlineFilters: dataviewInlineFilters };
305
+ if (this._gridOptions.draggableGrouping || this._gridOptions.enableGrouping) {
306
+ this.groupItemMetadataProvider = new common_1.SlickGroupItemMetadataProvider();
307
+ this.sharedService.groupItemMetadataProvider = this.groupItemMetadataProvider;
308
+ dataViewOptions = Object.assign(Object.assign({}, dataViewOptions), { groupItemMetadataProvider: this.groupItemMetadataProvider });
309
+ }
310
+ this.dataView = new Slick.Data.DataView(dataViewOptions);
311
+ this._eventPubSubService.publish(`onDataviewCreated`, this.dataView);
312
+ }
313
+ // get any possible Services that user want to register which don't require SlickGrid to be instantiated
314
+ // RxJS Resource is in this lot because it has to be registered before anything else and doesn't require SlickGrid to be initialized
315
+ this.preRegisterResources();
316
+ // for convenience to the user, we provide the property "editor" as an Slickgrid-React editor complex object
317
+ // however "editor" is used internally by SlickGrid for it's own Editor Factory
318
+ // so in our lib we will swap "editor" and copy it into a new property called "internalColumnEditor"
319
+ // then take back "editor.model" and make it the new "editor" so that SlickGrid Editor Factory still works
320
+ this._columnDefinitions = this.swapInternalEditorToSlickGridFactoryEditor(this.props.columnDefinitions);
321
+ // if the user wants to automatically add a Custom Editor Formatter, we need to call the auto add function again
322
+ if (this._gridOptions.autoAddCustomEditorFormatter) {
323
+ (0, common_1.autoAddEditorFormatterToColumnsWithEditor)(this._columnDefinitions, this._gridOptions.autoAddCustomEditorFormatter);
324
+ }
325
+ // save reference for all columns before they optionally become hidden/visible
326
+ this.sharedService.allColumns = this._columnDefinitions;
327
+ this.sharedService.visibleColumns = this._columnDefinitions;
328
+ // after subscribing to potential columns changed, we are ready to create these optional extensions
329
+ // when we did find some to create (RowMove, RowDetail, RowSelections), it will automatically modify column definitions (by previous subscribe)
330
+ this.extensionService.createExtensionsBeforeGridCreation(this._columnDefinitions, this._gridOptions);
331
+ // if user entered some Pinning/Frozen "presets", we need to apply them in the grid options
332
+ if ((_h = this.gridOptions.presets) === null || _h === void 0 ? void 0 : _h.pinning) {
333
+ this.gridOptions = Object.assign(Object.assign({}, this.gridOptions), this.gridOptions.presets.pinning);
334
+ }
335
+ // build SlickGrid Grid, also user might optionally pass a custom dataview (e.g. remote model)
336
+ this.grid = new Slick.Grid(`#${this.props.gridId}`, this.props.customDataView || this.dataView, this._columnDefinitions, this._gridOptions);
337
+ this.sharedService.dataView = this.dataView;
338
+ this.sharedService.slickGrid = this.grid;
339
+ this.sharedService.gridContainerElement = this._elm;
340
+ this.extensionService.bindDifferentExtensions();
341
+ this.bindDifferentHooks(this.grid, this._gridOptions, this.dataView);
342
+ // when it's a frozen grid, we need to keep the frozen column id for reference if we ever show/hide column from ColumnPicker/GridMenu afterward
343
+ const frozenColumnIndex = (_k = (_j = this._gridOptions) === null || _j === void 0 ? void 0 : _j.frozenColumn) !== null && _k !== void 0 ? _k : -1;
344
+ if (frozenColumnIndex >= 0 && frozenColumnIndex <= this._columnDefinitions.length && this._columnDefinitions.length > 0) {
345
+ this.sharedService.frozenVisibleColumnId = (_m = (_l = this._columnDefinitions[frozenColumnIndex]) === null || _l === void 0 ? void 0 : _l.id) !== null && _m !== void 0 ? _m : '';
346
+ }
347
+ // get any possible Services that user want to register
348
+ this.registerResources();
349
+ // initialize the SlickGrid grid
350
+ this.grid.init();
351
+ // initialized the resizer service only after SlickGrid is initialized
352
+ // if we don't we end up binding our resize to a grid element that doesn't yet exist in the DOM and the resizer service will fail silently (because it has a try/catch that unbinds the resize without throwing back)
353
+ const gridContainerElm = this._elm;
354
+ if (gridContainerElm) {
355
+ this.resizerService.init(this.grid, gridContainerElm);
356
+ }
357
+ // user could show a custom footer with the data metrics (dataset length and last updated timestamp)
358
+ if (!this._gridOptions.enablePagination && this._gridOptions.showCustomFooter && this._gridOptions.customFooterOptions && gridContainerElm) {
359
+ this.slickFooter = new custom_footer_component_1.SlickFooterComponent(this.grid, this._gridOptions.customFooterOptions, this._eventPubSubService, this.props.translaterService);
360
+ this.slickFooter.renderFooter(gridContainerElm);
361
+ }
362
+ if (!this.props.customDataView && this.dataView) {
363
+ const initialDataset = ((_o = this._gridOptions) === null || _o === void 0 ? void 0 : _o.enableTreeData) ? this.sortTreeDataset(this.props.dataset) : this.props.dataset;
364
+ if (Array.isArray(initialDataset)) {
365
+ this.dataView.setItems(initialDataset, (_p = this._gridOptions.datasetIdPropertyName) !== null && _p !== void 0 ? _p : 'id');
366
+ }
367
+ // if you don't want the items that are not visible (due to being filtered out or being on a different page)
368
+ // to stay selected, pass 'false' to the second arg
369
+ if (((_q = this.grid) === null || _q === void 0 ? void 0 : _q.getSelectionModel()) && ((_r = this._gridOptions) === null || _r === void 0 ? void 0 : _r.dataView) && this._gridOptions.dataView.hasOwnProperty('syncGridSelection')) {
370
+ // if we are using a Backend Service, we will do an extra flag check, the reason is because it might have some unintended behaviors
371
+ // with the BackendServiceApi because technically the data in the page changes the DataView on every page change.
372
+ let preservedRowSelectionWithBackend = false;
373
+ if (this._gridOptions.backendServiceApi && this._gridOptions.dataView.hasOwnProperty('syncGridSelectionWithBackendService')) {
374
+ preservedRowSelectionWithBackend = this._gridOptions.dataView.syncGridSelectionWithBackendService;
375
+ }
376
+ const syncGridSelection = this._gridOptions.dataView.syncGridSelection;
377
+ if (typeof syncGridSelection === 'boolean') {
378
+ let preservedRowSelection = syncGridSelection;
379
+ if (!this._isLocalGrid) {
380
+ // when using BackendServiceApi, we'll be using the "syncGridSelectionWithBackendService" flag BUT "syncGridSelection" must also be set to True
381
+ preservedRowSelection = syncGridSelection && preservedRowSelectionWithBackend;
382
+ }
383
+ this.dataView.syncGridSelection(this.grid, preservedRowSelection);
384
+ }
385
+ else if (typeof syncGridSelection === 'object') {
386
+ this.dataView.syncGridSelection(this.grid, syncGridSelection.preserveHidden, syncGridSelection.preserveHiddenOnSelectionChange);
387
+ }
388
+ }
389
+ if (this._dataset.length > 0) {
390
+ if (!this._isDatasetInitialized && (this._gridOptions.enableCheckboxSelector || this._gridOptions.enableRowSelection)) {
391
+ this.loadRowSelectionPresetWhenExists();
392
+ }
393
+ this.loadFilterPresetsWhenDatasetInitialized();
394
+ this._isDatasetInitialized = true;
395
+ }
396
+ }
397
+ // user might want to hide the header row on page load but still have `enableFiltering: true`
398
+ // if that is the case, we need to hide the headerRow ONLY AFTER all filters got created & dataView exist
399
+ if (this._hideHeaderRowAfterPageLoad) {
400
+ this.showHeaderRow(false);
401
+ this.sharedService.hideHeaderRowAfterPageLoad = this._hideHeaderRowAfterPageLoad;
402
+ }
403
+ // publish & dispatch certain events
404
+ this._eventPubSubService.publish(`onGridCreated`, this.grid);
405
+ // after the DataView is created & updated execute some processes & dispatch some events
406
+ if (!this.props.customDataView) {
407
+ this.executeAfterDataviewCreated(this.grid, this._gridOptions);
408
+ }
409
+ // bind resize ONLY after the dataView is ready
410
+ this.bindResizeHook(this.grid, this._gridOptions);
411
+ // bind the Backend Service API callback functions only after the grid is initialized
412
+ // because the preProcess() and onInit() might get triggered
413
+ if ((_s = this._gridOptions) === null || _s === void 0 ? void 0 : _s.backendServiceApi) {
414
+ this.bindBackendCallbackFunctions(this._gridOptions);
415
+ }
416
+ // create the React Grid Instance with reference to all Services
417
+ const reactElementInstance = {
418
+ element: this._elm,
419
+ // Slick Grid & DataView objects
420
+ dataView: this.dataView,
421
+ slickGrid: this.grid,
422
+ // public methods
423
+ dispose: this.dispose.bind(this),
424
+ // return all available Services (non-singleton)
425
+ backendService: (_u = (_t = this._gridOptions) === null || _t === void 0 ? void 0 : _t.backendServiceApi) === null || _u === void 0 ? void 0 : _u.service,
426
+ eventPubSubService: this._eventPubSubService,
427
+ filterService: this.filterService,
428
+ gridEventService: this.gridEventService,
429
+ gridStateService: this.gridStateService,
430
+ gridService: this.gridService,
431
+ groupingService: this.groupingService,
432
+ extensionService: this.extensionService,
433
+ paginationService: this.paginationService,
434
+ resizerService: this.resizerService,
435
+ sortService: this.sortService,
436
+ treeDataService: this.treeDataService,
437
+ };
438
+ // addons (SlickGrid extra plugins/controls)
439
+ this.extensions = (_v = this.extensionService) === null || _v === void 0 ? void 0 : _v.extensionList;
440
+ // all instances (SlickGrid, DataView & all Services)
441
+ this.instances = reactElementInstance;
442
+ this.setStateValue('instances', reactElementInstance);
443
+ this._eventPubSubService.publish(`onReactGridCreated`, reactElementInstance);
444
+ }
445
+ componentWillUnmount(shouldEmptyDomElementContainer = false) {
446
+ var _a, _b, _c, _d, _f;
447
+ this._eventPubSubService.publish(`onBeforeGridDestroy`, this.grid);
448
+ (_a = this._eventHandler) === null || _a === void 0 ? void 0 : _a.unsubscribeAll();
449
+ i18next_1.default.off('languageChanged');
450
+ // we could optionally also empty the content of the grid container DOM element
451
+ if (shouldEmptyDomElementContainer) {
452
+ this.emptyGridContainerElm();
453
+ }
454
+ this._eventPubSubService.publish(`onAfterGridDestroyed`, true);
455
+ // dispose of all Services
456
+ this.serviceList.forEach((service) => {
457
+ if (service === null || service === void 0 ? void 0 : service.dispose) {
458
+ service.dispose();
459
+ }
460
+ });
461
+ this.serviceList = [];
462
+ // dispose all registered external resources
463
+ if (Array.isArray(this._registeredResources)) {
464
+ while (this._registeredResources.length > 0) {
465
+ const resource = this._registeredResources.pop();
466
+ if (resource === null || resource === void 0 ? void 0 : resource.dispose) {
467
+ resource.dispose();
468
+ }
469
+ }
470
+ this._registeredResources = [];
471
+ }
472
+ // dispose the Components
473
+ (_b = this.slickEmptyWarning) === null || _b === void 0 ? void 0 : _b.dispose();
474
+ (_c = this.slickFooter) === null || _c === void 0 ? void 0 : _c.dispose();
475
+ (_d = this.slickPagination) === null || _d === void 0 ? void 0 : _d.dispose();
476
+ if (this.dataView) {
477
+ if (this.dataView.setItems) {
478
+ this.dataView.setItems([]);
479
+ }
480
+ if (this.dataView.destroy) {
481
+ this.dataView.destroy();
482
+ }
483
+ }
484
+ if ((_f = this.grid) === null || _f === void 0 ? void 0 : _f.destroy) {
485
+ this.grid.destroy(shouldEmptyDomElementContainer);
486
+ }
487
+ // also dispose of all Subscriptions
488
+ this.subscriptions = (0, index_1.disposeAllSubscriptions)(this.subscriptions);
489
+ if (this.backendServiceApi) {
490
+ for (const prop of Object.keys(this.backendServiceApi)) {
491
+ this.backendServiceApi[prop] = null;
492
+ }
493
+ this.backendServiceApi = undefined;
494
+ }
495
+ for (const prop of Object.keys(this.props.columnDefinitions)) {
496
+ this.props.columnDefinitions[prop] = null;
497
+ }
498
+ for (const prop of Object.keys(this.sharedService)) {
499
+ this.sharedService[prop] = null;
500
+ }
501
+ this._dataset = null;
502
+ this._columnDefinitions = [];
503
+ }
504
+ emptyGridContainerElm() {
505
+ var _a, _b;
506
+ const gridContainerId = (_b = (_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.gridContainerId) !== null && _b !== void 0 ? _b : 'grid1';
507
+ const gridContainerElm = document.querySelector(`#${gridContainerId}`);
508
+ (0, common_1.emptyElement)(gridContainerElm);
509
+ }
510
+ dispose(shouldEmptyDomElementContainer = false) {
511
+ this.componentWillUnmount(shouldEmptyDomElementContainer);
512
+ }
513
+ componentDidUpdate(prevProps) {
514
+ // get the grid options (order of precedence is Global Options first, then user option which could overwrite the Global options)
515
+ if (this.props.gridOptions !== prevProps.gridOptions) {
516
+ this._gridOptions = Object.assign(Object.assign({}, global_grid_options_1.GlobalGridOptions), this._gridOptions);
517
+ }
518
+ if (this.props.columnDefinitions !== prevProps.columnDefinitions) {
519
+ this._columnDefinitions = this.props.columnDefinitions;
520
+ this.columnDefinitionsChanged();
521
+ }
522
+ if (this.props.dataset !== prevProps.dataset) {
523
+ this.dataset = this.props.dataset || prevProps.dataset;
524
+ }
525
+ if (this.props.datasetHierarchical && this.props.datasetHierarchical !== prevProps.datasetHierarchical) {
526
+ this.datasetHierarchical = this.props.datasetHierarchical;
527
+ }
528
+ }
529
+ columnDefinitionsChanged() {
530
+ this._columnDefinitions = this.props.columnDefinitions;
531
+ if (this._isGridInitialized) {
532
+ this.updateColumnDefinitionsList(this.props.columnDefinitions);
533
+ }
534
+ if (this._columnDefinitions.length > 0) {
535
+ this.copyColumnWidthsReference(this._columnDefinitions);
536
+ }
537
+ }
538
+ /**
539
+ * Commits the current edit to the grid
540
+ */
541
+ commitEdit(target) {
542
+ if (this.grid.getOptions().autoCommitEdit) {
543
+ const activeNode = this.grid.getActiveCellNode();
544
+ // a timeout must be set or this could come into conflict when slickgrid
545
+ // tries to commit the edit when going from one editor to another on the grid
546
+ // through the click event. If the timeout was not here it would
547
+ // try to commit/destroy the twice, which would throw an
548
+ // error about the element not being in the DOM
549
+ setTimeout(() => {
550
+ var _a;
551
+ // make sure the target is the active editor so we do not
552
+ // commit prematurely
553
+ if ((activeNode === null || activeNode === void 0 ? void 0 : activeNode.contains(target)) && this.grid.getEditorLock().isActive() && !((_a = target === null || target === void 0 ? void 0 : target.classList) === null || _a === void 0 ? void 0 : _a.contains('autocomplete'))) {
554
+ this.grid.getEditorLock().commitCurrentEdit();
555
+ }
556
+ });
557
+ }
558
+ }
559
+ /**
560
+ * Define our internal Post Process callback, it will execute internally after we get back result from the Process backend call
561
+ * For now, this is GraphQL Service ONLY feature and it will basically
562
+ * refresh the Dataset & Pagination without having the user to create his own PostProcess every time
563
+ */
564
+ createBackendApiInternalPostProcessCallback(gridOptions) {
565
+ const backendApi = gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.backendServiceApi;
566
+ if (backendApi === null || backendApi === void 0 ? void 0 : backendApi.service) {
567
+ const backendApiService = backendApi.service;
568
+ // internalPostProcess only works (for now) with a GraphQL Service, so make sure it is of that type
569
+ if (typeof backendApiService.getDatasetName === 'function') {
570
+ backendApi.internalPostProcess = (processResult) => {
571
+ const datasetName = (backendApi && backendApiService && typeof backendApiService.getDatasetName === 'function') ? backendApiService.getDatasetName() : '';
572
+ if (processResult === null || processResult === void 0 ? void 0 : processResult.data[datasetName]) {
573
+ const data = processResult.data[datasetName].hasOwnProperty('nodes') ? processResult.data[datasetName].nodes : processResult.data[datasetName];
574
+ const totalCount = processResult.data[datasetName].hasOwnProperty('totalCount') ? processResult.data[datasetName].totalCount : processResult.data[datasetName].length;
575
+ this.refreshGridData(data, totalCount || 0);
576
+ }
577
+ };
578
+ }
579
+ }
580
+ }
581
+ bindDifferentHooks(grid, gridOptions, dataView) {
582
+ var _a, _b, _c;
583
+ // translate some of them on first load, then on each language change
584
+ if (gridOptions.enableTranslate) {
585
+ this.extensionService.translateAllExtensions();
586
+ this.translateColumnHeaderTitleKeys();
587
+ this.translateColumnGroupKeys();
588
+ }
589
+ // on locale change, we have to manually translate the Headers, GridMenu
590
+ i18next_1.default.on('languageChanged', () => {
591
+ // publish event of the same name that Slickgrid-Universal uses on a language change event
592
+ this._eventPubSubService.publish('onLanguageChange');
593
+ if (gridOptions.enableTranslate) {
594
+ this.extensionService.translateAllExtensions();
595
+ this.translateColumnHeaderTitleKeys();
596
+ this.translateColumnGroupKeys();
597
+ if (gridOptions.createPreHeaderPanel && !gridOptions.enableDraggableGrouping) {
598
+ this.groupingService.translateGroupingAndColSpan();
599
+ }
600
+ }
601
+ });
602
+ // if user set an onInit Backend, we'll run it right away (and if so, we also need to run preProcess, internalPostProcess & postProcess)
603
+ if (gridOptions.backendServiceApi) {
604
+ const backendApi = gridOptions.backendServiceApi;
605
+ if ((_a = backendApi === null || backendApi === void 0 ? void 0 : backendApi.service) === null || _a === void 0 ? void 0 : _a.init) {
606
+ backendApi.service.init(backendApi.options, gridOptions.pagination, this.grid, this.sharedService);
607
+ }
608
+ }
609
+ if (dataView && grid) {
610
+ const slickgridEventPrefix = (_c = (_b = this._gridOptions) === null || _b === void 0 ? void 0 : _b.defaultSlickgridEventPrefix) !== null && _c !== void 0 ? _c : '';
611
+ // expose all Slick Grid Events through dispatch
612
+ for (const prop in grid) {
613
+ if (grid.hasOwnProperty(prop) && prop.startsWith('on')) {
614
+ const gridEventName = this._eventPubSubService.getEventNameByNamingConvention(prop, slickgridEventPrefix);
615
+ this._eventHandler.subscribe(grid[prop], (event, args) => {
616
+ if (this.props.hasOwnProperty(prop)) {
617
+ const callback = this.props[prop];
618
+ return typeof callback === 'function' && callback(new CustomEvent(gridEventName, { detail: { eventData: event, args } }));
619
+ }
620
+ return true;
621
+ });
622
+ }
623
+ }
624
+ // expose all Slick DataView Events through dispatch
625
+ for (const prop in dataView) {
626
+ if (dataView.hasOwnProperty(prop) && prop.startsWith('on')) {
627
+ this._eventHandler.subscribe(dataView[prop], (event, args) => {
628
+ const dataViewEventName = this._eventPubSubService.getEventNameByNamingConvention(prop, slickgridEventPrefix);
629
+ if (this.props.hasOwnProperty(prop)) {
630
+ const callback = this.props[prop];
631
+ return typeof callback === 'function' && callback(new CustomEvent(dataViewEventName, { detail: { eventData: event, args } }));
632
+ }
633
+ return true;
634
+ });
635
+ }
636
+ }
637
+ // on cell click, mainly used with the columnDef.action callback
638
+ this.gridEventService.bindOnBeforeEditCell(grid);
639
+ this.gridEventService.bindOnCellChange(grid);
640
+ this.gridEventService.bindOnClick(grid);
641
+ if (dataView && grid) {
642
+ // bind external sorting (backend) when available or default onSort (dataView)
643
+ if (gridOptions.enableSorting) {
644
+ // bind external sorting (backend) unless specified to use the local one
645
+ if (gridOptions.backendServiceApi && !gridOptions.backendServiceApi.useLocalSorting) {
646
+ this.sortService.bindBackendOnSort(grid);
647
+ }
648
+ else {
649
+ this.sortService.bindLocalOnSort(grid);
650
+ }
651
+ }
652
+ // bind external filter (backend) when available or default onFilter (dataView)
653
+ if (gridOptions.enableFiltering) {
654
+ this.filterService.init(grid);
655
+ // bind external filter (backend) unless specified to use the local one
656
+ if (gridOptions.backendServiceApi && !gridOptions.backendServiceApi.useLocalFiltering) {
657
+ this.filterService.bindBackendOnFilter(grid);
658
+ }
659
+ else {
660
+ this.filterService.bindLocalOnFilter(grid);
661
+ }
662
+ }
663
+ // when column are reordered, we need to update the visibleColumn array
664
+ this._eventHandler.subscribe(grid.onColumnsReordered, (_e, args) => {
665
+ this.sharedService.hasColumnsReordered = true;
666
+ this.sharedService.visibleColumns = args.impactedColumns;
667
+ });
668
+ // load any presets if any (after dataset is initialized)
669
+ this.loadColumnPresetsWhenDatasetInitialized();
670
+ this.loadFilterPresetsWhenDatasetInitialized();
671
+ // When data changes in the DataView, we need to refresh the metrics and/or display a warning if the dataset is empty
672
+ this._eventHandler.subscribe(dataView.onRowCountChanged, () => {
673
+ grid.invalidate();
674
+ this.handleOnItemCountChanged(dataView.getFilteredItemCount() || 0, dataView.getItemCount() || 0);
675
+ });
676
+ this._eventHandler.subscribe(dataView.onSetItemsCalled, (_e, args) => {
677
+ var _a;
678
+ this.handleOnItemCountChanged(dataView.getFilteredItemCount() || 0, args.itemCount);
679
+ // when user has resize by content enabled, we'll force a full width calculation since we change our entire dataset
680
+ if (args.itemCount > 0 && (this.gridOptions.autosizeColumnsByCellContentOnFirstLoad || this.gridOptions.enableAutoResizeColumnsByCellContent)) {
681
+ this.resizerService.resizeColumnsByCellContent(!((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.resizeByContentOnlyOnFirstLoad));
682
+ }
683
+ });
684
+ if ((gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.enableFiltering) && !gridOptions.enableRowDetailView) {
685
+ this._eventHandler.subscribe(dataView.onRowsChanged, (_e, args) => {
686
+ // filtering data with local dataset will not always show correctly unless we call this updateRow/render
687
+ // also don't use "invalidateRows" since it destroys the entire row and as bad user experience when updating a row
688
+ // see commit: https://github.com/slickgrid-universal/aurelia-slickgrid/commit/8c503a4d45fba11cbd8d8cc467fae8d177cc4f60
689
+ if ((args === null || args === void 0 ? void 0 : args.rows) && Array.isArray(args.rows)) {
690
+ args.rows.forEach((row) => grid.updateRow(row));
691
+ grid.render();
692
+ }
693
+ });
694
+ }
695
+ }
696
+ }
697
+ // did the user add a colspan callback? If so, hook it into the DataView getItemMetadata
698
+ if ((gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.colspanCallback) && (dataView === null || dataView === void 0 ? void 0 : dataView.getItem) && (dataView === null || dataView === void 0 ? void 0 : dataView.getItemMetadata)) {
699
+ dataView.getItemMetadata = (rowNumber) => {
700
+ let callbackResult = null;
701
+ if (gridOptions.colspanCallback) {
702
+ callbackResult = gridOptions.colspanCallback(dataView.getItem(rowNumber));
703
+ }
704
+ return callbackResult;
705
+ };
706
+ }
707
+ }
708
+ bindBackendCallbackFunctions(gridOptions) {
709
+ var _a, _b, _c, _d, _f;
710
+ const backendApi = gridOptions.backendServiceApi;
711
+ const backendApiService = backendApi === null || backendApi === void 0 ? void 0 : backendApi.service;
712
+ const serviceOptions = (backendApiService === null || backendApiService === void 0 ? void 0 : backendApiService.options) || {};
713
+ const isExecuteCommandOnInit = (!serviceOptions) ? false : ((serviceOptions && serviceOptions.hasOwnProperty('executeProcessCommandOnInit')) ? serviceOptions['executeProcessCommandOnInit'] : true);
714
+ if (backendApiService) {
715
+ // update backend filters (if need be) BEFORE the query runs (via the onInit command a few lines below)
716
+ // if user entered some any "presets", we need to reflect them all in the grid
717
+ if (gridOptions === null || gridOptions === void 0 ? void 0 : gridOptions.presets) {
718
+ // Filters "presets"
719
+ if (backendApiService.updateFilters && Array.isArray(gridOptions.presets.filters) && gridOptions.presets.filters.length > 0) {
720
+ backendApiService.updateFilters(gridOptions.presets.filters, true);
721
+ }
722
+ // Sorters "presets"
723
+ if (backendApiService.updateSorters && Array.isArray(gridOptions.presets.sorters) && gridOptions.presets.sorters.length > 0) {
724
+ // when using multi-column sort, we can have multiple but on single sort then only grab the first sort provided
725
+ const sortColumns = ((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.multiColumnSort) ? gridOptions.presets.sorters : gridOptions.presets.sorters.slice(0, 1);
726
+ backendApiService.updateSorters(undefined, sortColumns);
727
+ }
728
+ // Pagination "presets"
729
+ if (backendApiService.updatePagination && gridOptions.presets.pagination) {
730
+ const { pageNumber, pageSize } = gridOptions.presets.pagination;
731
+ backendApiService.updatePagination(pageNumber, pageSize);
732
+ }
733
+ }
734
+ else {
735
+ const columnFilters = this.filterService.getColumnFilters();
736
+ if (columnFilters && backendApiService.updateFilters) {
737
+ backendApiService.updateFilters(columnFilters, false);
738
+ }
739
+ }
740
+ // execute onInit command when necessary
741
+ if (backendApi && backendApiService && (backendApi.onInit || isExecuteCommandOnInit)) {
742
+ const query = (typeof backendApiService.buildQuery === 'function') ? backendApiService.buildQuery() : '';
743
+ const process = isExecuteCommandOnInit ? ((_c = (_b = backendApi.process) === null || _b === void 0 ? void 0 : _b.call(backendApi, query)) !== null && _c !== void 0 ? _c : null) : ((_f = (_d = backendApi.onInit) === null || _d === void 0 ? void 0 : _d.call(backendApi, query)) !== null && _f !== void 0 ? _f : null);
744
+ // wrap this inside a setTimeout to avoid timing issue since the gridOptions needs to be ready before running this onInit
745
+ setTimeout(() => {
746
+ var _a, _b, _c, _d;
747
+ const backendUtilityService = this.backendUtilityService;
748
+ // keep start time & end timestamps & return it after process execution
749
+ const startTime = new Date();
750
+ // run any pre-process, if defined, for example a spinner
751
+ if (backendApi.preProcess) {
752
+ backendApi.preProcess();
753
+ }
754
+ // the processes can be a Promise (like Http)
755
+ const totalItems = (_c = (_b = (_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.pagination) === null || _b === void 0 ? void 0 : _b.totalItems) !== null && _c !== void 0 ? _c : 0;
756
+ if (process instanceof Promise) {
757
+ process
758
+ .then((processResult) => backendUtilityService.executeBackendProcessesCallback(startTime, processResult, backendApi, totalItems))
759
+ .catch((error) => backendUtilityService.onBackendError(error, backendApi));
760
+ }
761
+ else if (process && ((_d = this.rxjs) === null || _d === void 0 ? void 0 : _d.isObservable(process))) {
762
+ this.subscriptions.push(process.subscribe((processResult) => backendUtilityService.executeBackendProcessesCallback(startTime, processResult, backendApi, totalItems), (error) => backendUtilityService.onBackendError(error, backendApi)));
763
+ }
764
+ });
765
+ }
766
+ }
767
+ }
768
+ bindResizeHook(grid, options) {
769
+ if ((options.autoFitColumnsOnFirstLoad && options.autosizeColumnsByCellContentOnFirstLoad) || (options.enableAutoSizeColumns && options.enableAutoResizeColumnsByCellContent)) {
770
+ throw new Error(`[Slickgrid-React] You cannot enable both autosize/fit viewport & resize by content, you must choose which resize technique to use. You can enable these 2 options ("autoFitColumnsOnFirstLoad" and "enableAutoSizeColumns") OR these other 2 options ("autosizeColumnsByCellContentOnFirstLoad" and "enableAutoResizeColumnsByCellContent").`);
771
+ }
772
+ // expand/autofit columns on first page load
773
+ if (grid && options.autoFitColumnsOnFirstLoad && options.enableAutoSizeColumns && typeof grid.autosizeColumns === 'function') {
774
+ this.grid.autosizeColumns();
775
+ }
776
+ // auto-resize grid on browser resize
777
+ if (options.gridHeight || options.gridWidth) {
778
+ this.resizerService.resizeGrid(0, { height: options.gridHeight, width: options.gridWidth });
779
+ }
780
+ else {
781
+ this.resizerService.resizeGrid();
782
+ }
783
+ if (grid && (options === null || options === void 0 ? void 0 : options.enableAutoResize)) {
784
+ if (options.autoFitColumnsOnFirstLoad && options.enableAutoSizeColumns && typeof grid.autosizeColumns === 'function') {
785
+ grid.autosizeColumns();
786
+ }
787
+ }
788
+ }
789
+ executeAfterDataviewCreated(_grid, gridOptions) {
790
+ var _a;
791
+ // if user entered some Sort "presets", we need to reflect them all in the DOM
792
+ if (gridOptions.enableSorting) {
793
+ if (gridOptions.presets && Array.isArray(gridOptions.presets.sorters)) {
794
+ // when using multi-column sort, we can have multiple but on single sort then only grab the first sort provided
795
+ const sortColumns = ((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.multiColumnSort) ? gridOptions.presets.sorters : gridOptions.presets.sorters.slice(0, 1);
796
+ this.sortService.loadGridSorters(sortColumns);
797
+ }
798
+ }
799
+ }
800
+ /**
801
+ * On a Pagination changed, we will trigger a Grid State changed with the new pagination info
802
+ * Also if we use Row Selection or the Checkbox Selector with a Backend Service (Odata, GraphQL), we need to reset any selection
803
+ */
804
+ paginationChanged(pagination) {
805
+ var _a, _b, _c;
806
+ const isSyncGridSelectionEnabled = (_b = (_a = this.gridStateService) === null || _a === void 0 ? void 0 : _a.needToPreserveRowSelection()) !== null && _b !== void 0 ? _b : false;
807
+ if (this.grid && !isSyncGridSelectionEnabled && ((_c = this.gridOptions) === null || _c === void 0 ? void 0 : _c.backendServiceApi) && (this.gridOptions.enableRowSelection || this.gridOptions.enableCheckboxSelector)) {
808
+ this.grid.setSelectedRows([]);
809
+ }
810
+ const { pageNumber, pageSize } = pagination;
811
+ if (this.sharedService) {
812
+ if (pageSize !== undefined && pageNumber !== undefined) {
813
+ this.sharedService.currentPagination = { pageNumber, pageSize };
814
+ }
815
+ }
816
+ this._eventPubSubService.publish('onGridStateChanged', {
817
+ change: { newValues: { pageNumber, pageSize }, type: common_1.GridStateType.pagination },
818
+ gridState: this.gridStateService.getCurrentGridState()
819
+ });
820
+ }
821
+ paginationOptionsChanged(newPaginationOptions) {
822
+ var _a;
823
+ if (newPaginationOptions && this._paginationOptions) {
824
+ this._paginationOptions = Object.assign(Object.assign({}, this._paginationOptions), newPaginationOptions);
825
+ }
826
+ else {
827
+ this._paginationOptions = newPaginationOptions;
828
+ }
829
+ if (this._gridOptions) {
830
+ this._gridOptions.pagination = this._paginationOptions;
831
+ this.paginationService.updateTotalItems((_a = newPaginationOptions === null || newPaginationOptions === void 0 ? void 0 : newPaginationOptions.totalItems) !== null && _a !== void 0 ? _a : 0, true);
832
+ }
833
+ }
834
+ /**
835
+ * When dataset changes, we need to refresh the entire grid UI & possibly resize it as well
836
+ * @param dataset
837
+ */
838
+ refreshGridData(dataset, totalCount) {
839
+ var _a, _b, _c, _d, _f, _g, _h, _j;
840
+ // local grid, check if we need to show the Pagination
841
+ // if so then also check if there's any presets and finally initialize the PaginationService
842
+ // a local grid with Pagination presets will potentially have a different total of items, we'll need to get it from the DataView and update our total
843
+ if (this.grid && this._gridOptions) {
844
+ if (((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.enablePagination) && this._isLocalGrid) {
845
+ this.showPagination = true;
846
+ this.loadLocalGridPagination(dataset);
847
+ }
848
+ if (((_b = this._gridOptions) === null || _b === void 0 ? void 0 : _b.enableEmptyDataWarningMessage) && Array.isArray(dataset)) {
849
+ const finalTotalCount = totalCount || dataset.length;
850
+ this.displayEmptyDataWarning(finalTotalCount < 1);
851
+ }
852
+ if (Array.isArray(dataset) && this.grid && ((_c = this.dataView) === null || _c === void 0 ? void 0 : _c.setItems)) {
853
+ this.dataView.setItems(dataset, (_d = this._gridOptions.datasetIdPropertyName) !== null && _d !== void 0 ? _d : 'id');
854
+ if (!this._gridOptions.backendServiceApi && !this._gridOptions.enableTreeData) {
855
+ this.dataView.reSort();
856
+ }
857
+ if (dataset.length > 0) {
858
+ if (!this._isDatasetInitialized) {
859
+ this.loadFilterPresetsWhenDatasetInitialized();
860
+ if (this._gridOptions.enableCheckboxSelector) {
861
+ this.loadRowSelectionPresetWhenExists();
862
+ }
863
+ }
864
+ this._isDatasetInitialized = true;
865
+ }
866
+ if (dataset) {
867
+ this.grid.invalidate();
868
+ }
869
+ // display the Pagination component only after calling this refresh data first, we call it here so that if we preset pagination page number it will be shown correctly
870
+ this.showPagination = (this._gridOptions && (this._gridOptions.enablePagination || (this._gridOptions.backendServiceApi && this._gridOptions.enablePagination === undefined))) ? true : false;
871
+ if (this._paginationOptions && ((_f = this._gridOptions) === null || _f === void 0 ? void 0 : _f.pagination) && ((_g = this._gridOptions) === null || _g === void 0 ? void 0 : _g.backendServiceApi)) {
872
+ const paginationOptions = this.setPaginationOptionsWhenPresetDefined(this._gridOptions, this._paginationOptions);
873
+ // when we have a totalCount use it, else we'll take it from the pagination object
874
+ // only update the total items if it's different to avoid refreshing the UI
875
+ const totalRecords = (totalCount !== undefined) ? totalCount : ((_j = (_h = this._gridOptions) === null || _h === void 0 ? void 0 : _h.pagination) === null || _j === void 0 ? void 0 : _j.totalItems);
876
+ if (totalRecords !== undefined && totalRecords !== this.totalItems) {
877
+ this.totalItems = +totalRecords;
878
+ }
879
+ // initialize the Pagination Service with new pagination options (which might have presets)
880
+ if (!this._isPaginationInitialized) {
881
+ this.initializePaginationService(paginationOptions);
882
+ }
883
+ else {
884
+ // update the pagination service with the new total
885
+ this.paginationService.updateTotalItems(this.totalItems);
886
+ }
887
+ }
888
+ // resize the grid inside a slight timeout, in case other DOM element changed prior to the resize (like a filter/pagination changed)
889
+ if (this.grid && this._gridOptions.enableAutoResize) {
890
+ const delay = this._gridOptions.autoResize && this._gridOptions.autoResize.delay;
891
+ this.resizerService.resizeGrid(delay || 10);
892
+ }
893
+ }
894
+ }
895
+ }
896
+ /**
897
+ * Show the filter row displayed on first row, we can optionally pass false to hide it.
898
+ * @param showing
899
+ */
900
+ showHeaderRow(showing = true) {
901
+ this.grid.setHeaderRowVisibility(showing, false);
902
+ if (showing === true && this._isGridInitialized) {
903
+ this.grid.setColumns(this.props.columnDefinitions);
904
+ }
905
+ return showing;
906
+ }
907
+ /**
908
+ * Check if there's any Pagination Presets defined in the Grid Options,
909
+ * if there are then load them in the paginationOptions object
910
+ */
911
+ setPaginationOptionsWhenPresetDefined(gridOptions, paginationOptions) {
912
+ var _a;
913
+ if (((_a = gridOptions.presets) === null || _a === void 0 ? void 0 : _a.pagination) && gridOptions.pagination) {
914
+ paginationOptions.pageSize = gridOptions.presets.pagination.pageSize;
915
+ paginationOptions.pageNumber = gridOptions.presets.pagination.pageNumber;
916
+ }
917
+ return paginationOptions;
918
+ }
919
+ /**
920
+ * Dynamically change or update the column definitions list.
921
+ * We will re-render the grid so that the new header and data shows up correctly.
922
+ * If using i18n, we also need to trigger a re-translate of the column headers
923
+ */
924
+ updateColumnDefinitionsList(newColumnDefinitions) {
925
+ var _a, _b, _c;
926
+ if (this.grid && this._gridOptions && Array.isArray(newColumnDefinitions)) {
927
+ // map/swap the internal library Editor to the SlickGrid Editor factory
928
+ newColumnDefinitions = this.swapInternalEditorToSlickGridFactoryEditor(newColumnDefinitions);
929
+ // if the user wants to automatically add a Custom Editor Formatter, we need to call the auto add function again
930
+ if (this._gridOptions.autoAddCustomEditorFormatter) {
931
+ (0, common_1.autoAddEditorFormatterToColumnsWithEditor)(newColumnDefinitions, this._gridOptions.autoAddCustomEditorFormatter);
932
+ }
933
+ if (this._gridOptions.enableTranslate) {
934
+ this.extensionService.translateColumnHeaders(false, newColumnDefinitions);
935
+ }
936
+ else {
937
+ this.extensionService.renderColumnHeaders(newColumnDefinitions, true);
938
+ }
939
+ if ((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.enableAutoSizeColumns) {
940
+ this.grid.autosizeColumns();
941
+ }
942
+ else if (((_b = this._gridOptions) === null || _b === void 0 ? void 0 : _b.enableAutoResizeColumnsByCellContent) && ((_c = this.resizerService) === null || _c === void 0 ? void 0 : _c.resizeColumnsByCellContent)) {
943
+ this.resizerService.resizeColumnsByCellContent();
944
+ }
945
+ }
946
+ }
947
+ //
948
+ // protected functions
949
+ // ------------------
950
+ /**
951
+ * Loop through all column definitions and copy the original optional `width` properties optionally provided by the user.
952
+ * We will use this when doing a resize by cell content, if user provided a `width` it won't override it.
953
+ */
954
+ copyColumnWidthsReference(columnDefinitions) {
955
+ columnDefinitions.forEach(col => col.originalWidth = col.width);
956
+ }
957
+ displayEmptyDataWarning(showWarning = true) {
958
+ var _a;
959
+ (_a = this.slickEmptyWarning) === null || _a === void 0 ? void 0 : _a.showEmptyDataMessage(showWarning);
960
+ }
961
+ /** When data changes in the DataView, we'll refresh the metrics and/or display a warning if the dataset is empty */
962
+ handleOnItemCountChanged(currentPageRowItemCount, totalItemCount) {
963
+ var _a;
964
+ this._currentDatasetLength = totalItemCount;
965
+ this.metrics = {
966
+ startTime: new Date(),
967
+ endTime: new Date(),
968
+ itemCount: currentPageRowItemCount,
969
+ totalItemCount
970
+ };
971
+ // if custom footer is enabled, then we'll update its metrics
972
+ if (this.slickFooter) {
973
+ this.slickFooter.metrics = this.metrics;
974
+ }
975
+ // when using local (in-memory) dataset, we'll display a warning message when filtered data is empty
976
+ if (this._isLocalGrid && ((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.enableEmptyDataWarningMessage)) {
977
+ this.displayEmptyDataWarning(currentPageRowItemCount === 0);
978
+ }
979
+ }
980
+ /** Initialize the Pagination Service once */
981
+ initializePaginationService(paginationOptions) {
982
+ if (this.grid && this.gridOptions) {
983
+ this.paginationData = {
984
+ gridOptions: this.gridOptions,
985
+ paginationService: this.paginationService,
986
+ };
987
+ this.paginationService.totalItems = this.totalItems;
988
+ this.paginationService.init(this.grid, paginationOptions, this.backendServiceApi);
989
+ this.subscriptions.push(this._eventPubSubService.subscribe('onPaginationChanged', paginationChanges => this.paginationChanged(paginationChanges)), this._eventPubSubService.subscribe('onPaginationOptionsChanged', paginationChanges => this.paginationOptionsChanged(paginationChanges)), this._eventPubSubService.subscribe('onPaginationVisibilityChanged', (visibility) => {
990
+ var _a, _b, _c;
991
+ this.showPagination = (_a = visibility === null || visibility === void 0 ? void 0 : visibility.visible) !== null && _a !== void 0 ? _a : false;
992
+ if ((_b = this.gridOptions) === null || _b === void 0 ? void 0 : _b.backendServiceApi) {
993
+ (_c = this.backendUtilityService) === null || _c === void 0 ? void 0 : _c.refreshBackendDataset(this.gridOptions);
994
+ }
995
+ this.renderPagination(this.showPagination);
996
+ }));
997
+ // also initialize (render) the pagination component
998
+ this.renderPagination();
999
+ this._isPaginationInitialized = true;
1000
+ }
1001
+ }
1002
+ /**
1003
+ * Render (or dispose) the Pagination Component, user can optionally provide False (to not show it) which will in term dispose of the Pagination,
1004
+ * also while disposing we can choose to omit the disposable of the Pagination Service (if we are simply toggling the Pagination, we want to keep the Service alive)
1005
+ * @param {Boolean} showPagination - show (new render) or not (dispose) the Pagination
1006
+ * @param {Boolean} shouldDisposePaginationService - when disposing the Pagination, do we also want to dispose of the Pagination Service? (defaults to True)
1007
+ */
1008
+ renderPagination(showPagination = true) {
1009
+ var _a;
1010
+ if (((_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.enablePagination) && !this._isPaginationInitialized && showPagination) {
1011
+ this.slickPagination = new pagination_component_1.SlickPaginationComponent(this.paginationService, this._eventPubSubService, this.sharedService, this.props.translaterService);
1012
+ this.slickPagination.renderPagination(this._elm);
1013
+ this._isPaginationInitialized = true;
1014
+ }
1015
+ else if (!showPagination) {
1016
+ if (this.slickPagination) {
1017
+ this.slickPagination.dispose();
1018
+ }
1019
+ this._isPaginationInitialized = false;
1020
+ }
1021
+ }
1022
+ /** Load the Editor Collection asynchronously and replace the "collection" property when Promise resolves */
1023
+ loadEditorCollectionAsync(column) {
1024
+ var _a;
1025
+ const collectionAsync = (column === null || column === void 0 ? void 0 : column.editor).collectionAsync;
1026
+ (column === null || column === void 0 ? void 0 : column.editor).disabled = true; // disable the Editor DOM element, we'll re-enable it after receiving the collection with "updateEditorCollection()"
1027
+ if (collectionAsync instanceof Promise) {
1028
+ // wait for the "collectionAsync", once resolved we will save it into the "collection"
1029
+ // the collectionAsync can be of 3 types HttpClient, HttpFetch or a Promise
1030
+ collectionAsync.then((response) => {
1031
+ if (Array.isArray(response)) {
1032
+ this.updateEditorCollection(column, response); // from Promise
1033
+ }
1034
+ else if (response instanceof Response && typeof response.json === 'function') {
1035
+ if (response.bodyUsed) {
1036
+ console.warn(`[SlickGrid-React] The response body passed to collectionAsync was already read.`
1037
+ + `Either pass the dataset from the Response or clone the response first using response.clone()`);
1038
+ }
1039
+ else {
1040
+ // from Fetch
1041
+ response.json().then(data => this.updateEditorCollection(column, data));
1042
+ }
1043
+ }
1044
+ else if (response === null || response === void 0 ? void 0 : response.content) {
1045
+ this.updateEditorCollection(column, response.content); // from http-client
1046
+ }
1047
+ });
1048
+ }
1049
+ else if ((_a = this.rxjs) === null || _a === void 0 ? void 0 : _a.isObservable(collectionAsync)) {
1050
+ // wrap this inside a setTimeout to avoid timing issue since updateEditorCollection requires to call SlickGrid getColumns() method
1051
+ setTimeout(() => {
1052
+ this.subscriptions.push(collectionAsync.subscribe((resolvedCollection) => this.updateEditorCollection(column, resolvedCollection)));
1053
+ });
1054
+ }
1055
+ }
1056
+ insertDynamicPresetColumns(columnId, gridPresetColumns) {
1057
+ if (this._columnDefinitions) {
1058
+ const columnPosition = this._columnDefinitions.findIndex(c => c.id === columnId);
1059
+ if (columnPosition >= 0) {
1060
+ const dynColumn = this._columnDefinitions[columnPosition];
1061
+ if ((dynColumn === null || dynColumn === void 0 ? void 0 : dynColumn.id) === columnId && !gridPresetColumns.some(c => c.id === columnId)) {
1062
+ columnPosition > 0
1063
+ ? gridPresetColumns.splice(columnPosition, 0, dynColumn)
1064
+ : gridPresetColumns.unshift(dynColumn);
1065
+ }
1066
+ }
1067
+ }
1068
+ }
1069
+ /** Load any possible Columns Grid Presets */
1070
+ loadColumnPresetsWhenDatasetInitialized() {
1071
+ var _a, _b, _c, _d, _f, _g, _h, _j, _k;
1072
+ // if user entered some Columns "presets", we need to reflect them all in the grid
1073
+ if (this.grid && this.gridOptions.presets && Array.isArray(this.gridOptions.presets.columns) && this.gridOptions.presets.columns.length > 0) {
1074
+ const gridPresetColumns = this.gridStateService.getAssociatedGridColumns(this.grid, this.gridOptions.presets.columns);
1075
+ if (gridPresetColumns && Array.isArray(gridPresetColumns) && gridPresetColumns.length > 0 && Array.isArray(this._columnDefinitions)) {
1076
+ // make sure that the dynamic columns are included in presets (1.Row Move, 2. Row Selection, 3. Row Detail)
1077
+ if (this.gridOptions.enableRowMoveManager) {
1078
+ const rmmColId = (_c = (_b = (_a = this.gridOptions) === null || _a === void 0 ? void 0 : _a.rowMoveManager) === null || _b === void 0 ? void 0 : _b.columnId) !== null && _c !== void 0 ? _c : '_move';
1079
+ this.insertDynamicPresetColumns(rmmColId, gridPresetColumns);
1080
+ }
1081
+ if (this.gridOptions.enableCheckboxSelector) {
1082
+ const chkColId = (_g = (_f = (_d = this.gridOptions) === null || _d === void 0 ? void 0 : _d.checkboxSelector) === null || _f === void 0 ? void 0 : _f.columnId) !== null && _g !== void 0 ? _g : '_checkbox_selector';
1083
+ this.insertDynamicPresetColumns(chkColId, gridPresetColumns);
1084
+ }
1085
+ if (this.gridOptions.enableRowDetailView) {
1086
+ const rdvColId = (_k = (_j = (_h = this.gridOptions) === null || _h === void 0 ? void 0 : _h.rowDetailView) === null || _j === void 0 ? void 0 : _j.columnId) !== null && _k !== void 0 ? _k : '_detail_selector';
1087
+ this.insertDynamicPresetColumns(rdvColId, gridPresetColumns);
1088
+ }
1089
+ // keep copy the original optional `width` properties optionally provided by the user.
1090
+ // We will use this when doing a resize by cell content, if user provided a `width` it won't override it.
1091
+ gridPresetColumns.forEach(col => col.originalWidth = col.width);
1092
+ // finally set the new presets columns (including checkbox selector if need be)
1093
+ this.grid.setColumns(gridPresetColumns);
1094
+ this.sharedService.visibleColumns = gridPresetColumns;
1095
+ }
1096
+ }
1097
+ }
1098
+ /** Load any possible Filters Grid Presets */
1099
+ loadFilterPresetsWhenDatasetInitialized() {
1100
+ var _a, _b, _c;
1101
+ if (this._gridOptions && !this.props.customDataView) {
1102
+ // if user entered some Filter "presets", we need to reflect them all in the DOM
1103
+ if (this._gridOptions.presets && (Array.isArray(this._gridOptions.presets.filters) || Array.isArray((_b = (_a = this._gridOptions.presets) === null || _a === void 0 ? void 0 : _a.treeData) === null || _b === void 0 ? void 0 : _b.toggledItems))) {
1104
+ this.filterService.populateColumnFilterSearchTermPresets(((_c = this._gridOptions.presets) === null || _c === void 0 ? void 0 : _c.filters) || []);
1105
+ }
1106
+ }
1107
+ }
1108
+ /**
1109
+ * local grid, check if we need to show the Pagination
1110
+ * if so then also check if there's any presets and finally initialize the PaginationService
1111
+ * a local grid with Pagination presets will potentially have a different total of items, we'll need to get it from the DataView and update our total
1112
+ */
1113
+ loadLocalGridPagination(dataset) {
1114
+ var _a;
1115
+ if (this._gridOptions && this._paginationOptions) {
1116
+ this.totalItems = Array.isArray(dataset) ? dataset.length : 0;
1117
+ if (this._paginationOptions && ((_a = this.dataView) === null || _a === void 0 ? void 0 : _a.getPagingInfo)) {
1118
+ const slickPagingInfo = this.dataView.getPagingInfo();
1119
+ if ((slickPagingInfo === null || slickPagingInfo === void 0 ? void 0 : slickPagingInfo.hasOwnProperty('totalRows')) && this._paginationOptions.totalItems !== slickPagingInfo.totalRows) {
1120
+ this.totalItems = slickPagingInfo.totalRows || 0;
1121
+ }
1122
+ }
1123
+ this._paginationOptions.totalItems = this.totalItems;
1124
+ const paginationOptions = this.setPaginationOptionsWhenPresetDefined(this._gridOptions, this._paginationOptions);
1125
+ this.initializePaginationService(paginationOptions);
1126
+ }
1127
+ }
1128
+ /** Load any Row Selections into the DataView that were presets by the user */
1129
+ loadRowSelectionPresetWhenExists() {
1130
+ var _a, _b;
1131
+ // if user entered some Row Selections "presets"
1132
+ const presets = (_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.presets;
1133
+ const enableRowSelection = this._gridOptions && (this._gridOptions.enableCheckboxSelector || this._gridOptions.enableRowSelection);
1134
+ if (enableRowSelection && ((_b = this.grid) === null || _b === void 0 ? void 0 : _b.getSelectionModel()) && (presets === null || presets === void 0 ? void 0 : presets.rowSelection) && (Array.isArray(presets.rowSelection.gridRowIndexes) || Array.isArray(presets.rowSelection.dataContextIds))) {
1135
+ let dataContextIds = presets.rowSelection.dataContextIds;
1136
+ let gridRowIndexes = presets.rowSelection.gridRowIndexes;
1137
+ // maps the IDs to the Grid Rows and vice versa, the "dataContextIds" has precedence over the other
1138
+ if (Array.isArray(dataContextIds) && dataContextIds.length > 0) {
1139
+ gridRowIndexes = this.dataView.mapIdsToRows(dataContextIds) || [];
1140
+ }
1141
+ else if (Array.isArray(gridRowIndexes) && gridRowIndexes.length > 0) {
1142
+ dataContextIds = this.dataView.mapRowsToIds(gridRowIndexes) || [];
1143
+ }
1144
+ // apply row selection when defined as grid presets
1145
+ if (this.grid && Array.isArray(gridRowIndexes)) {
1146
+ this.grid.setSelectedRows(gridRowIndexes);
1147
+ this.dataView.setSelectedIds(dataContextIds || [], {
1148
+ isRowBeingAdded: true,
1149
+ shouldTriggerEvent: false,
1150
+ applyRowSelectionToGrid: true
1151
+ });
1152
+ }
1153
+ }
1154
+ }
1155
+ mergeGridOptions(gridOptions) {
1156
+ // use extend to deep merge & copy to avoid immutable properties being changed in GlobalGridOptions after a route change
1157
+ const options = Slick.Utils.extend(true, {}, global_grid_options_1.GlobalGridOptions, gridOptions);
1158
+ options.gridId = this.props.gridId;
1159
+ options.gridContainerId = `slickGridContainer-${this.props.gridId}`;
1160
+ // also make sure to show the header row if user have enabled filtering
1161
+ if (options.enableFiltering && !options.showHeaderRow) {
1162
+ options.showHeaderRow = options.enableFiltering;
1163
+ }
1164
+ // if we have a backendServiceApi and the enablePagination is undefined, we'll assume that we do want to see it, else get that defined value
1165
+ options.enablePagination = ((gridOptions.backendServiceApi && gridOptions.enablePagination === undefined) ? true : gridOptions.enablePagination) || false;
1166
+ // using copy extend to do a deep clone has an unwanted side on objects and pageSizes but ES6 spread has other worst side effects
1167
+ // so we will just overwrite the pageSizes when needed, this is the only one causing issues so far.
1168
+ // On a deep extend, Object and Array are extended, but object wrappers on primitive types such as String, Boolean, and Number are not.
1169
+ if ((options === null || options === void 0 ? void 0 : options.pagination) && (gridOptions.enablePagination || gridOptions.backendServiceApi) && gridOptions.pagination && Array.isArray(gridOptions.pagination.pageSizes)) {
1170
+ options.pagination.pageSizes = gridOptions.pagination.pageSizes;
1171
+ }
1172
+ // when we use Pagination on Local Grid, it doesn't seem to work without enableFiltering
1173
+ // so we'll enable the filtering but we'll keep the header row hidden
1174
+ if (this.sharedService && !options.enableFiltering && options.enablePagination && this._isLocalGrid) {
1175
+ options.enableFiltering = true;
1176
+ options.showHeaderRow = false;
1177
+ this._hideHeaderRowAfterPageLoad = true;
1178
+ this.sharedService.hideHeaderRowAfterPageLoad = true;
1179
+ }
1180
+ return options;
1181
+ }
1182
+ /** Pre-Register any Resource that don't require SlickGrid to be instantiated (for example RxJS Resource) */
1183
+ preRegisterResources() {
1184
+ this._registeredResources = this.gridOptions.registerExternalResources || [];
1185
+ // bind & initialize all Components/Services that were tagged as enabled
1186
+ // register all services by executing their init method and providing them with the Grid object
1187
+ if (Array.isArray(this._registeredResources)) {
1188
+ for (const resource of this._registeredResources) {
1189
+ if ((resource === null || resource === void 0 ? void 0 : resource.className) === 'RxJsResource') {
1190
+ this.registerRxJsResource(resource);
1191
+ }
1192
+ }
1193
+ }
1194
+ }
1195
+ registerResources() {
1196
+ // at this point, we consider all the registered services as external services, anything else registered afterward aren't external
1197
+ if (Array.isArray(this._registeredResources)) {
1198
+ this.sharedService.externalRegisteredResources = this._registeredResources;
1199
+ }
1200
+ // push all other Services that we want to be registered
1201
+ this._registeredResources.push(this.gridService, this.gridStateService);
1202
+ // when using Grouping/DraggableGrouping/Colspan register its Service
1203
+ if (this.gridOptions.createPreHeaderPanel && !this.gridOptions.enableDraggableGrouping) {
1204
+ this._registeredResources.push(this.groupingService);
1205
+ }
1206
+ // when using Tree Data View, register its Service
1207
+ if (this.gridOptions.enableTreeData) {
1208
+ this._registeredResources.push(this.treeDataService);
1209
+ }
1210
+ // when user enables translation, we need to translate Headers on first pass & subsequently in the bindDifferentHooks
1211
+ if (this.gridOptions.enableTranslate) {
1212
+ this.extensionService.translateColumnHeaders();
1213
+ }
1214
+ // also initialize (render) the empty warning component
1215
+ this.slickEmptyWarning = new empty_warning_component_1.SlickEmptyWarningComponent();
1216
+ this._registeredResources.push(this.slickEmptyWarning);
1217
+ // bind & initialize all Components/Services that were tagged as enabled
1218
+ // register all services by executing their init method and providing them with the Grid object
1219
+ if (Array.isArray(this._registeredResources)) {
1220
+ for (const resource of this._registeredResources) {
1221
+ if (this.grid && typeof resource.init === 'function') {
1222
+ resource.init(this.grid, this.props.containerService);
1223
+ }
1224
+ }
1225
+ }
1226
+ }
1227
+ /** Register the RxJS Resource in all necessary services which uses */
1228
+ registerRxJsResource(resource) {
1229
+ this.rxjs = resource;
1230
+ this.backendUtilityService.addRxJsResource(this.rxjs);
1231
+ this.filterFactory.addRxJsResource(this.rxjs);
1232
+ this.filterService.addRxJsResource(this.rxjs);
1233
+ this.sortService.addRxJsResource(this.rxjs);
1234
+ this.paginationService.addRxJsResource(this.rxjs);
1235
+ this.props.containerService.registerInstance('RxJsResource', this.rxjs);
1236
+ }
1237
+ /**
1238
+ * Takes a flat dataset with parent/child relationship, sort it (via its tree structure) and return the sorted flat array
1239
+ * @param {Array<Object>} flatDatasetInput - flat dataset input
1240
+ * @param {Boolean} forceGridRefresh - optionally force a full grid refresh
1241
+ * @returns {Array<Object>} sort flat parent/child dataset
1242
+ */
1243
+ sortTreeDataset(flatDatasetInput, forceGridRefresh = false) {
1244
+ var _a, _b;
1245
+ const prevDatasetLn = this._currentDatasetLength;
1246
+ let sortedDatasetResult;
1247
+ let flatDatasetOutput = [];
1248
+ // if the hierarchical dataset was already initialized then no need to re-convert it, we can use it directly from the shared service ref
1249
+ if (this._isDatasetHierarchicalInitialized && this.datasetHierarchical) {
1250
+ sortedDatasetResult = this.treeDataService.sortHierarchicalDataset(this.datasetHierarchical);
1251
+ flatDatasetOutput = sortedDatasetResult.flat;
1252
+ }
1253
+ else if (Array.isArray(flatDatasetInput) && flatDatasetInput.length > 0) {
1254
+ if ((_b = (_a = this._gridOptions) === null || _a === void 0 ? void 0 : _a.treeDataOptions) === null || _b === void 0 ? void 0 : _b.initialSort) {
1255
+ // else we need to first convert the flat dataset to a hierarchical dataset and then sort
1256
+ sortedDatasetResult = this.treeDataService.convertFlatParentChildToTreeDatasetAndSort(flatDatasetInput, this._columnDefinitions, this._gridOptions);
1257
+ this.sharedService.hierarchicalDataset = sortedDatasetResult.hierarchical;
1258
+ flatDatasetOutput = sortedDatasetResult.flat;
1259
+ }
1260
+ else {
1261
+ // else we assume that the user provided an array that is already sorted (user's responsability)
1262
+ // and so we can simply convert the array to a tree structure and we're done, no need to sort
1263
+ this.sharedService.hierarchicalDataset = this.treeDataService.convertFlatParentChildToTreeDataset(flatDatasetInput, this.gridOptions);
1264
+ flatDatasetOutput = flatDatasetInput || [];
1265
+ }
1266
+ }
1267
+ // if we add/remove item(s) from the dataset, we need to also refresh our tree data filters
1268
+ if (flatDatasetInput.length > 0 && (forceGridRefresh || flatDatasetInput.length !== prevDatasetLn)) {
1269
+ this.filterService.refreshTreeDataFilters(flatDatasetOutput);
1270
+ }
1271
+ return flatDatasetOutput;
1272
+ }
1273
+ /**
1274
+ * For convenience to the user, we provide the property "editor" as an Slickgrid-React editor complex object
1275
+ * however "editor" is used internally by SlickGrid for it's own Editor Factory
1276
+ * so in our lib we will swap "editor" and copy it into a new property called "internalColumnEditor"
1277
+ * then take back "editor.model" and make it the new "editor" so that SlickGrid Editor Factory still works
1278
+ */
1279
+ swapInternalEditorToSlickGridFactoryEditor(columnDefinitions) {
1280
+ if (columnDefinitions.some(col => `${col.id}`.includes('.'))) {
1281
+ console.error('[Slickgrid-React] Make sure that none of your Column Definition "id" property includes a dot in its name because that will cause some problems with the Editors. For example if your column definition "field" property is "user.firstName" then use "firstName" as the column "id".');
1282
+ }
1283
+ return columnDefinitions.map((column) => {
1284
+ var _a, _b;
1285
+ // on every Editor which have a "collection" or a "collectionAsync"
1286
+ if ((_a = column.editor) === null || _a === void 0 ? void 0 : _a.collectionAsync) {
1287
+ this.loadEditorCollectionAsync(column);
1288
+ }
1289
+ return Object.assign(Object.assign({}, column), { editor: (_b = column.editor) === null || _b === void 0 ? void 0 : _b.model, internalColumnEditor: Object.assign({}, column.editor) });
1290
+ });
1291
+ }
1292
+ /** translate all columns (including hidden columns) */
1293
+ translateColumnHeaderTitleKeys() {
1294
+ this.extensionUtility.translateItems(this.sharedService.allColumns, 'nameKey', 'name');
1295
+ }
1296
+ /** translate all column groups (including hidden columns) */
1297
+ translateColumnGroupKeys() {
1298
+ this.extensionUtility.translateItems(this.sharedService.allColumns, 'columnGroupKey', 'columnGroup');
1299
+ }
1300
+ /**
1301
+ * Update the "internalColumnEditor.collection" property.
1302
+ * Since this is called after the async call resolves, the pointer will not be the same as the "column" argument passed.
1303
+ * Once we found the new pointer, we will reassign the "editor" and "collection" to the "internalColumnEditor" so it has newest collection
1304
+ */
1305
+ updateEditorCollection(column, newCollection) {
1306
+ column.editor.collection = newCollection;
1307
+ column.editor.disabled = false;
1308
+ // find the new column reference pointer & re-assign the new editor to the internalColumnEditor
1309
+ if (Array.isArray(this._columnDefinitions)) {
1310
+ const columnRef = this._columnDefinitions.find((col) => col.id === column.id);
1311
+ if (columnRef) {
1312
+ columnRef.internalColumnEditor = column.editor;
1313
+ }
1314
+ }
1315
+ // get current Editor, remove it from the DOM then re-enable it and re-render it with the new collection.
1316
+ const currentEditor = this.grid.getCellEditor();
1317
+ if ((currentEditor === null || currentEditor === void 0 ? void 0 : currentEditor.disable) && (currentEditor === null || currentEditor === void 0 ? void 0 : currentEditor.renderDomElement)) {
1318
+ currentEditor.destroy();
1319
+ currentEditor.disable(false);
1320
+ currentEditor.renderDomElement(newCollection);
1321
+ }
1322
+ }
1323
+ render() {
1324
+ return (react_1.default.createElement("div", { id: `slickGridContainer-${this.props.gridId}`, className: "grid-pane", ref: elm => this._elm = elm },
1325
+ this.props.header && react_1.default.createElement("div", { className: "header" }, this.props.header),
1326
+ react_1.default.createElement("div", { id: `${this.props.gridId}`, className: "slickgrid-container", style: { width: '100%' }, onBlur: $event => this.commitEdit($event.target) }),
1327
+ this.props.footer && react_1.default.createElement("div", { className: "footer" }, this.props.footer)));
1328
+ }
1329
+ }
1330
+ SlickgridReact.defaultProps = {
1331
+ reactUtilService: new index_1.ReactUtilService(),
1332
+ containerService: singletons_1.GlobalContainerService,
1333
+ translaterService: new index_1.TranslaterService(),
1334
+ dataset: [],
1335
+ gridId: '',
1336
+ columnDefinitions: [],
1337
+ };
1338
+ exports.SlickgridReact = SlickgridReact;
1338
1339
  //# sourceMappingURL=slickgrid-react.js.map