@slickgrid-universal/vanilla-bundle 2.4.1 → 2.6.0

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