slickgrid-react 5.14.1 → 9.0.2

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