angular-slickgrid 9.0.0 → 9.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (395) hide show
  1. package/LICENSE +1 -1
  2. package/{dist/fesm2022 → fesm2022}/angular-slickgrid.mjs +16 -16
  3. package/package.json +27 -14
  4. package/.gitbook.yaml +0 -5
  5. package/CHANGELOG.md +0 -1691
  6. package/CONTRIBUTING.md +0 -17
  7. package/angular.json +0 -133
  8. package/coverage/base.css +0 -224
  9. package/coverage/block-navigation.js +0 -87
  10. package/coverage/clover.xml +0 -1620
  11. package/coverage/coverage-final.json +0 -9
  12. package/coverage/favicon.png +0 -0
  13. package/coverage/index.html +0 -176
  14. package/coverage/library/components/angular-slickgrid.component.ts.html +0 -5074
  15. package/coverage/library/components/index.html +0 -116
  16. package/coverage/library/constants.ts.html +0 -397
  17. package/coverage/library/extensions/index.html +0 -116
  18. package/coverage/library/extensions/slickRowDetailView.ts.html +0 -1261
  19. package/coverage/library/index.html +0 -116
  20. package/coverage/library/modules/angular-slickgrid.module.ts.html +0 -166
  21. package/coverage/library/modules/index.html +0 -116
  22. package/coverage/library/services/angularUtil.service.ts.html +0 -445
  23. package/coverage/library/services/container.service.ts.html +0 -163
  24. package/coverage/library/services/index.html +0 -161
  25. package/coverage/library/services/translater.service.ts.html +0 -199
  26. package/coverage/library/services/utilities.ts.html +0 -142
  27. package/coverage/prettify.css +0 -1
  28. package/coverage/prettify.js +0 -2
  29. package/coverage/sort-arrow-sprite.png +0 -0
  30. package/coverage/sorter.js +0 -196
  31. package/dist/LICENSE +0 -21
  32. package/dist/README.md +0 -142
  33. package/docs/README.md +0 -5
  34. package/docs/TOC.md +0 -105
  35. package/docs/backend-services/Custom-Backend-Service.md +0 -50
  36. package/docs/backend-services/GraphQL.md +0 -276
  37. package/docs/backend-services/OData.md +0 -245
  38. package/docs/backend-services/graphql/GraphQL-Filtering.md +0 -156
  39. package/docs/backend-services/graphql/GraphQL-JSON-Result.md +0 -85
  40. package/docs/backend-services/graphql/GraphQL-Pagination.md +0 -77
  41. package/docs/backend-services/graphql/GraphQL-Sorting.md +0 -78
  42. package/docs/column-functionalities/cell-menu.md +0 -212
  43. package/docs/column-functionalities/editors/autocomplete-editor.md +0 -466
  44. package/docs/column-functionalities/editors/date-editor-flatpickr.md +0 -71
  45. package/docs/column-functionalities/editors/date-editor-vanilla-calendar.md +0 -91
  46. package/docs/column-functionalities/editors/longtext-editor-textarea.md +0 -80
  47. package/docs/column-functionalities/editors/select-dropdown-editor.md +0 -227
  48. package/docs/column-functionalities/editors.md +0 -604
  49. package/docs/column-functionalities/filters/autocomplete-filter.md +0 -183
  50. package/docs/column-functionalities/filters/compound-filters.md +0 -234
  51. package/docs/column-functionalities/filters/custom-filter.md +0 -117
  52. package/docs/column-functionalities/filters/filter-intro.md +0 -81
  53. package/docs/column-functionalities/filters/input-filter.md +0 -260
  54. package/docs/column-functionalities/filters/range-filters.md +0 -188
  55. package/docs/column-functionalities/filters/select-filter.md +0 -695
  56. package/docs/column-functionalities/filters/single-search-filter.md +0 -77
  57. package/docs/column-functionalities/filters/styling-filled-filters.md +0 -45
  58. package/docs/column-functionalities/formatters.md +0 -325
  59. package/docs/column-functionalities/sorting.md +0 -200
  60. package/docs/developer-guides/csp-compliance.md +0 -64
  61. package/docs/events/Available-Events.md +0 -223
  62. package/docs/events/Grid-&-DataView-Events.md +0 -211
  63. package/docs/getting-started/quick-start.md +0 -230
  64. package/docs/getting-started/troubleshooting.md +0 -80
  65. package/docs/grid-functionalities/Column-Picker.md +0 -22
  66. package/docs/grid-functionalities/Composite-Editor-Modal.md +0 -627
  67. package/docs/grid-functionalities/Context-Menu.md +0 -226
  68. package/docs/grid-functionalities/Custom-Footer.md +0 -80
  69. package/docs/grid-functionalities/Custom-Tooltip-(plugin).md +0 -258
  70. package/docs/grid-functionalities/Export-to-Excel.md +0 -457
  71. package/docs/grid-functionalities/Export-to-Text-File.md +0 -165
  72. package/docs/grid-functionalities/FAQ.md +0 -53
  73. package/docs/grid-functionalities/Global-Options.md +0 -29
  74. package/docs/grid-functionalities/Grid-Auto-Resize.md +0 -218
  75. package/docs/grid-functionalities/Grid-Menu.md +0 -134
  76. package/docs/grid-functionalities/Grid-State-&-Preset.md +0 -245
  77. package/docs/grid-functionalities/Header-Menu-&-Header-Buttons.md +0 -125
  78. package/docs/grid-functionalities/Resize-by-Cell-Content.md +0 -138
  79. package/docs/grid-functionalities/Row-Selection.md +0 -247
  80. package/docs/grid-functionalities/Row-based-edit.md +0 -71
  81. package/docs/grid-functionalities/add-update-highlight.md +0 -258
  82. package/docs/grid-functionalities/column-row-spanning.md +0 -74
  83. package/docs/grid-functionalities/dynamic-item-metadata.md +0 -124
  84. package/docs/grid-functionalities/excel-copy-buffer.md +0 -145
  85. package/docs/grid-functionalities/frozen-columns-rows.md +0 -164
  86. package/docs/grid-functionalities/grouping-and-aggregators.md +0 -269
  87. package/docs/grid-functionalities/header-footer-slots.md +0 -22
  88. package/docs/grid-functionalities/infinite-scroll.md +0 -150
  89. package/docs/grid-functionalities/providing-grid-data.md +0 -61
  90. package/docs/grid-functionalities/row-detail.md +0 -530
  91. package/docs/grid-functionalities/tree-data-grid.md +0 -391
  92. package/docs/localization/Localization---Component-Sample.md +0 -87
  93. package/docs/localization/Localization-with-Custom-Locales.md +0 -66
  94. package/docs/localization/Localization-with-ngx-translate.md +0 -148
  95. package/docs/migrations/migration-to-2.x.md +0 -304
  96. package/docs/migrations/migration-to-3.x.md +0 -295
  97. package/docs/migrations/migration-to-4.x.md +0 -83
  98. package/docs/migrations/migration-to-5.x.md +0 -160
  99. package/docs/migrations/migration-to-6.x.md +0 -128
  100. package/docs/migrations/migration-to-7.x.md +0 -294
  101. package/docs/migrations/migration-to-8.x.md +0 -316
  102. package/docs/migrations/migration-to-9.x.md +0 -219
  103. package/docs/slick-grid-dataview-objects/slickgrid-dataview-objects.md +0 -79
  104. package/docs/styling/dark-mode.md +0 -100
  105. package/docs/styling/styling.md +0 -250
  106. package/docs/testing/testing-patterns.md +0 -73
  107. package/eslint.config.mjs +0 -60
  108. package/ng-package.json +0 -10
  109. package/src/assets/angular-logo.png +0 -0
  110. package/src/assets/angular-logo2.png +0 -0
  111. package/src/assets/data/collection_100_numbers.json +0 -12
  112. package/src/assets/data/collection_500_numbers.json +0 -52
  113. package/src/assets/data/countries.json +0 -245
  114. package/src/assets/data/country_names.json +0 -245
  115. package/src/assets/data/customers_100.json +0 -102
  116. package/src/assets/data/users.csv +0 -5
  117. package/src/assets/i18n/en.json +0 -102
  118. package/src/assets/i18n/fr.json +0 -103
  119. package/src/demos/app-routing.module.ts +0 -108
  120. package/src/demos/app.component.html +0 -187
  121. package/src/demos/app.component.scss +0 -79
  122. package/src/demos/app.component.ts +0 -11
  123. package/src/demos/app.module.ts +0 -196
  124. package/src/demos/environments/environment.dev.ts +0 -3
  125. package/src/demos/environments/environment.prod.ts +0 -3
  126. package/src/demos/environments/environment.ts +0 -8
  127. package/src/demos/examples/custom-angularComponentEditor.ts +0 -187
  128. package/src/demos/examples/custom-angularComponentFilter.ts +0 -123
  129. package/src/demos/examples/custom-buttonFormatter.component.ts +0 -13
  130. package/src/demos/examples/custom-inputEditor.ts +0 -132
  131. package/src/demos/examples/custom-inputFilter.ts +0 -134
  132. package/src/demos/examples/custom-titleFormatter.component.ts +0 -9
  133. package/src/demos/examples/data/collection_100_numbers.json +0 -12
  134. package/src/demos/examples/data/collection_500_numbers.json +0 -52
  135. package/src/demos/examples/data/countries.json +0 -245
  136. package/src/demos/examples/data/country_names.json +0 -245
  137. package/src/demos/examples/data/customers_100.json +0 -102
  138. package/src/demos/examples/data/users.csv +0 -5
  139. package/src/demos/examples/editor-ng-select.component.ts +0 -38
  140. package/src/demos/examples/example01.component.html +0 -48
  141. package/src/demos/examples/example01.component.ts +0 -109
  142. package/src/demos/examples/example02.component.html +0 -45
  143. package/src/demos/examples/example02.component.ts +0 -218
  144. package/src/demos/examples/example03.component.html +0 -118
  145. package/src/demos/examples/example03.component.ts +0 -694
  146. package/src/demos/examples/example04.component.html +0 -87
  147. package/src/demos/examples/example04.component.ts +0 -326
  148. package/src/demos/examples/example05.component.html +0 -151
  149. package/src/demos/examples/example05.component.ts +0 -474
  150. package/src/demos/examples/example06.component.html +0 -163
  151. package/src/demos/examples/example06.component.ts +0 -446
  152. package/src/demos/examples/example07.component.html +0 -56
  153. package/src/demos/examples/example07.component.scss +0 -10
  154. package/src/demos/examples/example07.component.ts +0 -216
  155. package/src/demos/examples/example08.component.html +0 -51
  156. package/src/demos/examples/example08.component.scss +0 -23
  157. package/src/demos/examples/example08.component.ts +0 -195
  158. package/src/demos/examples/example09.component.html +0 -55
  159. package/src/demos/examples/example09.component.scss +0 -22
  160. package/src/demos/examples/example09.component.ts +0 -302
  161. package/src/demos/examples/example10.component.html +0 -103
  162. package/src/demos/examples/example10.component.ts +0 -309
  163. package/src/demos/examples/example11.component.html +0 -91
  164. package/src/demos/examples/example11.component.ts +0 -276
  165. package/src/demos/examples/example12.component.html +0 -98
  166. package/src/demos/examples/example12.component.ts +0 -317
  167. package/src/demos/examples/example13.component.html +0 -96
  168. package/src/demos/examples/example13.component.ts +0 -370
  169. package/src/demos/examples/example14.component.html +0 -50
  170. package/src/demos/examples/example14.component.scss +0 -11
  171. package/src/demos/examples/example14.component.ts +0 -156
  172. package/src/demos/examples/example15.component.html +0 -56
  173. package/src/demos/examples/example15.component.ts +0 -304
  174. package/src/demos/examples/example16.component.html +0 -77
  175. package/src/demos/examples/example16.component.ts +0 -277
  176. package/src/demos/examples/example17.component.html +0 -50
  177. package/src/demos/examples/example17.component.ts +0 -109
  178. package/src/demos/examples/example18.component.html +0 -132
  179. package/src/demos/examples/example18.component.ts +0 -445
  180. package/src/demos/examples/example19-rowdetail.component.html +0 -40
  181. package/src/demos/examples/example19-rowdetail.component.ts +0 -54
  182. package/src/demos/examples/example19.component.html +0 -79
  183. package/src/demos/examples/example19.component.ts +0 -316
  184. package/src/demos/examples/example20.component.html +0 -76
  185. package/src/demos/examples/example20.component.scss +0 -11
  186. package/src/demos/examples/example20.component.ts +0 -341
  187. package/src/demos/examples/example21.component.html +0 -86
  188. package/src/demos/examples/example21.component.scss +0 -16
  189. package/src/demos/examples/example21.component.ts +0 -140
  190. package/src/demos/examples/example22.component.html +0 -41
  191. package/src/demos/examples/example22.component.ts +0 -117
  192. package/src/demos/examples/example23.component.html +0 -111
  193. package/src/demos/examples/example23.component.ts +0 -323
  194. package/src/demos/examples/example24.component.html +0 -120
  195. package/src/demos/examples/example24.component.scss +0 -62
  196. package/src/demos/examples/example24.component.ts +0 -641
  197. package/src/demos/examples/example25.component.html +0 -60
  198. package/src/demos/examples/example25.component.scss +0 -8
  199. package/src/demos/examples/example25.component.ts +0 -255
  200. package/src/demos/examples/example26.component.html +0 -98
  201. package/src/demos/examples/example26.component.scss +0 -42
  202. package/src/demos/examples/example26.component.ts +0 -383
  203. package/src/demos/examples/example27.component.html +0 -138
  204. package/src/demos/examples/example27.component.scss +0 -10
  205. package/src/demos/examples/example27.component.ts +0 -369
  206. package/src/demos/examples/example28.component.html +0 -143
  207. package/src/demos/examples/example28.component.scss +0 -54
  208. package/src/demos/examples/example28.component.ts +0 -453
  209. package/src/demos/examples/example29.component.html +0 -30
  210. package/src/demos/examples/example29.component.ts +0 -70
  211. package/src/demos/examples/example30.component.html +0 -116
  212. package/src/demos/examples/example30.component.scss +0 -20
  213. package/src/demos/examples/example30.component.ts +0 -1070
  214. package/src/demos/examples/example32.component.html +0 -77
  215. package/src/demos/examples/example32.component.scss +0 -8
  216. package/src/demos/examples/example32.component.ts +0 -905
  217. package/src/demos/examples/example33.component.html +0 -50
  218. package/src/demos/examples/example33.component.scss +0 -46
  219. package/src/demos/examples/example33.component.ts +0 -571
  220. package/src/demos/examples/example34.component.html +0 -82
  221. package/src/demos/examples/example34.component.scss +0 -77
  222. package/src/demos/examples/example34.component.ts +0 -434
  223. package/src/demos/examples/example35.component.html +0 -77
  224. package/src/demos/examples/example35.component.scss +0 -18
  225. package/src/demos/examples/example35.component.ts +0 -264
  226. package/src/demos/examples/example36.component.html +0 -56
  227. package/src/demos/examples/example36.component.scss +0 -26
  228. package/src/demos/examples/example36.component.ts +0 -504
  229. package/src/demos/examples/example37.component.html +0 -30
  230. package/src/demos/examples/example37.component.ts +0 -123
  231. package/src/demos/examples/example38.component.html +0 -104
  232. package/src/demos/examples/example38.component.scss +0 -8
  233. package/src/demos/examples/example38.component.ts +0 -420
  234. package/src/demos/examples/example39.component.html +0 -112
  235. package/src/demos/examples/example39.component.scss +0 -8
  236. package/src/demos/examples/example39.component.ts +0 -371
  237. package/src/demos/examples/example40.component.html +0 -76
  238. package/src/demos/examples/example40.component.ts +0 -226
  239. package/src/demos/examples/example41.component.html +0 -50
  240. package/src/demos/examples/example41.component.scss +0 -42
  241. package/src/demos/examples/example41.component.ts +0 -229
  242. package/src/demos/examples/example42.component.html +0 -47
  243. package/src/demos/examples/example42.component.ts +0 -203
  244. package/src/demos/examples/example43.component.html +0 -94
  245. package/src/demos/examples/example43.component.scss +0 -30
  246. package/src/demos/examples/example43.component.ts +0 -449
  247. package/src/demos/examples/example44.component.html +0 -78
  248. package/src/demos/examples/example44.component.scss +0 -50
  249. package/src/demos/examples/example44.component.ts +0 -375
  250. package/src/demos/examples/example45-detail.component.html +0 -15
  251. package/src/demos/examples/example45-detail.component.ts +0 -97
  252. package/src/demos/examples/example45.component.html +0 -110
  253. package/src/demos/examples/example45.component.scss +0 -50
  254. package/src/demos/examples/example45.component.ts +0 -243
  255. package/src/demos/examples/filter-ng-select.component.ts +0 -33
  256. package/src/demos/examples/grid-custom-pager.component.html +0 -60
  257. package/src/demos/examples/grid-custom-pager.component.scss +0 -57
  258. package/src/demos/examples/grid-custom-pager.component.ts +0 -107
  259. package/src/demos/examples/grid-remote.component.html +0 -44
  260. package/src/demos/examples/grid-remote.component.ts +0 -164
  261. package/src/demos/examples/home.component.html +0 -39
  262. package/src/demos/examples/home.component.ts +0 -10
  263. package/src/demos/examples/jsonp.ts +0 -89
  264. package/src/demos/examples/rowdetail-preload.component.ts +0 -10
  265. package/src/demos/examples/swt-common-grid-pagination.component.ts +0 -160
  266. package/src/demos/examples/swt-common-grid-test.component.html +0 -37
  267. package/src/demos/examples/swt-common-grid-test.component.ts +0 -214
  268. package/src/demos/examples/swt-common-grid.component.ts +0 -436
  269. package/src/demos/examples/swt-logger.service.ts +0 -173
  270. package/src/demos/examples/utilities.ts +0 -9
  271. package/src/favicon.ico +0 -0
  272. package/src/index.html +0 -17
  273. package/src/library/components/__tests__/angular-slickgrid.component.spec.ts +0 -2638
  274. package/src/library/components/angular-slickgrid.component.html +0 -5
  275. package/src/library/components/angular-slickgrid.component.ts +0 -1662
  276. package/src/library/constants.ts +0 -105
  277. package/src/library/extensions/__tests__/slickRowDetailView.spec.ts +0 -751
  278. package/src/library/extensions/index.ts +0 -1
  279. package/src/library/extensions/slickRowDetailView.ts +0 -395
  280. package/src/library/global-grid-options.ts +0 -273
  281. package/src/library/index.ts +0 -11
  282. package/src/library/models/angularComponentOutput.interface.ts +0 -6
  283. package/src/library/models/angularGridInstance.interface.ts +0 -76
  284. package/src/library/models/externalTestingDependencies.interface.ts +0 -37
  285. package/src/library/models/gridOption.interface.ts +0 -15
  286. package/src/library/models/index.ts +0 -5
  287. package/src/library/models/rowDetailView.interface.ts +0 -16
  288. package/src/library/modules/angular-slickgrid.module.spec.ts +0 -25
  289. package/src/library/modules/angular-slickgrid.module.ts +0 -27
  290. package/src/library/services/__tests__/angularUtilService.spec.ts +0 -156
  291. package/src/library/services/__tests__/container.service.spec.ts +0 -25
  292. package/src/library/services/__tests__/translater.service.spec.ts +0 -43
  293. package/src/library/services/__tests__/utilities.spec.ts +0 -22
  294. package/src/library/services/angularUtil.service.ts +0 -120
  295. package/src/library/services/container.service.ts +0 -26
  296. package/src/library/services/index.ts +0 -4
  297. package/src/library/services/translater.service.ts +0 -38
  298. package/src/library/services/utilities.ts +0 -19
  299. package/src/library/slickgrid-config.ts +0 -10
  300. package/src/main.ts +0 -13
  301. package/src/public_api.ts +0 -1
  302. package/src/styles.scss +0 -178
  303. package/test/cypress/e2e/example01.cy.ts +0 -367
  304. package/test/cypress/e2e/example02.cy.ts +0 -60
  305. package/test/cypress/e2e/example03.cy.ts +0 -268
  306. package/test/cypress/e2e/example04.cy.ts +0 -254
  307. package/test/cypress/e2e/example05.cy.ts +0 -804
  308. package/test/cypress/e2e/example06.cy.ts +0 -890
  309. package/test/cypress/e2e/example07.cy.ts +0 -384
  310. package/test/cypress/e2e/example08.cy.ts +0 -190
  311. package/test/cypress/e2e/example09.cy.ts +0 -392
  312. package/test/cypress/e2e/example10.cy.ts +0 -650
  313. package/test/cypress/e2e/example11.cy.ts +0 -86
  314. package/test/cypress/e2e/example12.cy.ts +0 -269
  315. package/test/cypress/e2e/example13.cy.ts +0 -246
  316. package/test/cypress/e2e/example14.cy.ts +0 -122
  317. package/test/cypress/e2e/example15.cy.ts +0 -598
  318. package/test/cypress/e2e/example16.cy.ts +0 -427
  319. package/test/cypress/e2e/example17.cy.ts +0 -83
  320. package/test/cypress/e2e/example18.cy.ts +0 -431
  321. package/test/cypress/e2e/example19.cy.ts +0 -263
  322. package/test/cypress/e2e/example20.cy.ts +0 -264
  323. package/test/cypress/e2e/example21.cy.ts +0 -77
  324. package/test/cypress/e2e/example22.cy.ts +0 -94
  325. package/test/cypress/e2e/example23.cy.ts +0 -259
  326. package/test/cypress/e2e/example24.cy.ts +0 -707
  327. package/test/cypress/e2e/example25.cy.ts +0 -193
  328. package/test/cypress/e2e/example26.cy.ts +0 -111
  329. package/test/cypress/e2e/example27.cy.ts +0 -261
  330. package/test/cypress/e2e/example28.cy.ts +0 -740
  331. package/test/cypress/e2e/example29.cy.ts +0 -30
  332. package/test/cypress/e2e/example30.cy.ts +0 -757
  333. package/test/cypress/e2e/example31.cy.ts +0 -69
  334. package/test/cypress/e2e/example32.cy.ts +0 -272
  335. package/test/cypress/e2e/example33.cy.ts +0 -278
  336. package/test/cypress/e2e/example34.cy.ts +0 -84
  337. package/test/cypress/e2e/example35.cy.ts +0 -178
  338. package/test/cypress/e2e/example36.cy.ts +0 -219
  339. package/test/cypress/e2e/example37.cy.ts +0 -52
  340. package/test/cypress/e2e/example38.cy.ts +0 -160
  341. package/test/cypress/e2e/example39.cy.ts +0 -150
  342. package/test/cypress/e2e/example40.cy.ts +0 -126
  343. package/test/cypress/e2e/example41.cy.ts +0 -90
  344. package/test/cypress/e2e/example42.cy.ts +0 -82
  345. package/test/cypress/e2e/example43.cy.ts +0 -482
  346. package/test/cypress/e2e/example44.cy.ts +0 -458
  347. package/test/cypress/e2e/example45.cy.ts +0 -455
  348. package/test/cypress/e2e/home.cy.ts +0 -7
  349. package/test/cypress/fixtures/example.json +0 -5
  350. package/test/cypress/plugins/index.ts +0 -17
  351. package/test/cypress/plugins/utilities.ts +0 -28
  352. package/test/cypress/support/commands.ts +0 -88
  353. package/test/cypress/support/common.ts +0 -47
  354. package/test/cypress/support/drag.ts +0 -101
  355. package/test/cypress/support/index.ts +0 -20
  356. package/test/cypress/tsconfig.json +0 -9
  357. package/test/cypress.config.ts +0 -34
  358. package/test/mockSlickEvent.ts +0 -77
  359. package/test/rxjsResourceStub.ts +0 -69
  360. package/test/test-setup.ts +0 -6
  361. package/test/translateServiceStub.ts +0 -230
  362. package/test/translaterServiceStub.ts +0 -239
  363. package/test/tsconfig.json +0 -17
  364. package/test/vitest-global-mocks.ts +0 -41
  365. package/test/vitest-global-setup.ts +0 -3
  366. package/test/vitest-pretest.ts +0 -5
  367. package/tsconfig.app.json +0 -14
  368. package/tsconfig.json +0 -31
  369. package/tsconfig.spec.json +0 -11
  370. package/types/sortablejs.d.ts +0 -4
  371. package/vite.config.mts +0 -51
  372. /package/{dist/fesm2022 → fesm2022}/angular-slickgrid.mjs.map +0 -0
  373. /package/{dist/i18n → i18n}/en.json +0 -0
  374. /package/{dist/i18n → i18n}/fr.json +0 -0
  375. /package/{dist/index.d.ts → index.d.ts} +0 -0
  376. /package/{dist/library → library}/components/angular-slickgrid.component.d.ts +0 -0
  377. /package/{dist/library → library}/constants.d.ts +0 -0
  378. /package/{dist/library → library}/extensions/index.d.ts +0 -0
  379. /package/{dist/library → library}/extensions/slickRowDetailView.d.ts +0 -0
  380. /package/{dist/library → library}/global-grid-options.d.ts +0 -0
  381. /package/{dist/library → library}/index.d.ts +0 -0
  382. /package/{dist/library → library}/models/angularComponentOutput.interface.d.ts +0 -0
  383. /package/{dist/library → library}/models/angularGridInstance.interface.d.ts +0 -0
  384. /package/{dist/library → library}/models/externalTestingDependencies.interface.d.ts +0 -0
  385. /package/{dist/library → library}/models/gridOption.interface.d.ts +0 -0
  386. /package/{dist/library → library}/models/index.d.ts +0 -0
  387. /package/{dist/library → library}/models/rowDetailView.interface.d.ts +0 -0
  388. /package/{dist/library → library}/modules/angular-slickgrid.module.d.ts +0 -0
  389. /package/{dist/library → library}/services/angularUtil.service.d.ts +0 -0
  390. /package/{dist/library → library}/services/container.service.d.ts +0 -0
  391. /package/{dist/library → library}/services/index.d.ts +0 -0
  392. /package/{dist/library → library}/services/translater.service.d.ts +0 -0
  393. /package/{dist/library → library}/services/utilities.d.ts +0 -0
  394. /package/{dist/library → library}/slickgrid-config.d.ts +0 -0
  395. /package/{dist/public_api.d.ts → public_api.d.ts} +0 -0
@@ -1,1662 +0,0 @@
1
- import {
2
- AfterViewInit,
3
- ApplicationRef,
4
- ChangeDetectorRef,
5
- Component,
6
- ContentChild,
7
- ElementRef,
8
- EventEmitter,
9
- Inject,
10
- Input,
11
- OnDestroy,
12
- Optional,
13
- Output,
14
- TemplateRef,
15
- } from '@angular/core';
16
- import {
17
- AutocompleterEditor,
18
- BackendService,
19
- BackendServiceApi,
20
- BackendServiceOption,
21
- BasePaginationComponent,
22
- Column,
23
- DataViewOption,
24
- EventSubscription,
25
- ExternalResource,
26
- isColumnDateType,
27
- Locale,
28
- Metrics,
29
- Pagination,
30
- PaginationMetadata,
31
- RxJsFacade,
32
- SelectEditor,
33
- SlickDataView,
34
- SlickEventHandler,
35
- SlickGrid,
36
- } from '@slickgrid-universal/common';
37
- import {
38
- ExtensionName,
39
- ExtensionUtility,
40
- SlickGroupItemMetadataProvider,
41
-
42
- // services
43
- BackendUtilityService,
44
- CollectionService,
45
- EventNamingStyle,
46
- ExtensionService,
47
- FilterFactory,
48
- FilterService,
49
- GridEventService,
50
- GridService,
51
- GridStateService,
52
- HeaderGroupingService,
53
- PaginationService,
54
- ResizerService,
55
- SharedService,
56
- SlickgridConfig,
57
- SortService,
58
- TreeDataService,
59
-
60
- // utilities
61
- autoAddEditorFormatterToColumnsWithEditor,
62
- emptyElement,
63
- unsubscribeAll,
64
- } from '@slickgrid-universal/common';
65
- import { EventPubSubService } from '@slickgrid-universal/event-pub-sub';
66
- import { SlickEmptyWarningComponent } from '@slickgrid-universal/empty-warning-component';
67
- import { SlickFooterComponent } from '@slickgrid-universal/custom-footer-component';
68
- import { SlickPaginationComponent } from '@slickgrid-universal/pagination-component';
69
- import { RxJsResource } from '@slickgrid-universal/rxjs-observable';
70
- import { extend } from '@slickgrid-universal/utils';
71
- import { TranslateService } from '@ngx-translate/core';
72
- import { dequal } from 'dequal/lite';
73
- import { Observable } from 'rxjs';
74
-
75
- import { Constants } from '../constants';
76
- import type { AngularGridInstance, ExternalTestingDependencies, GridOption } from '../models/index';
77
- import { GlobalGridOptions } from '../global-grid-options';
78
- import { TranslaterService } from '../services/translater.service';
79
-
80
- // Services
81
- import { AngularUtilService } from '../services/angularUtil.service';
82
- import { SlickRowDetailView } from '../extensions/slickRowDetailView';
83
- import { ContainerService } from '../services/container.service';
84
-
85
- const WARN_NO_PREPARSE_DATE_SIZE = 10000; // data size to warn user when pre-parse isn't enabled
86
-
87
- @Component({
88
- selector: 'angular-slickgrid',
89
- templateUrl: './angular-slickgrid.component.html',
90
- providers: [
91
- // make everything transient (non-singleton)
92
- AngularUtilService,
93
- TranslaterService,
94
- ],
95
- standalone: false,
96
- })
97
- export class AngularSlickgridComponent<TData = any> implements AfterViewInit, OnDestroy {
98
- protected _dataset?: TData[] | null;
99
- protected _columnDefinitions!: Column[];
100
- protected _currentDatasetLength = 0;
101
- protected _darkMode = false;
102
- protected _eventHandler: SlickEventHandler = new SlickEventHandler();
103
- protected _eventPubSubService!: EventPubSubService;
104
- protected _angularGridInstances: AngularGridInstance | undefined;
105
- protected _hideHeaderRowAfterPageLoad = false;
106
- protected _isAutosizeColsCalled = false;
107
- protected _isGridInitialized = false;
108
- protected _isDatasetInitialized = false;
109
- protected _isDatasetHierarchicalInitialized = false;
110
- protected _isPaginationInitialized = false;
111
- protected _isLocalGrid = true;
112
- protected _paginationOptions: Pagination | undefined;
113
- protected _registeredResources: ExternalResource[] = [];
114
- protected _scrollEndCalled = false;
115
- dataView!: SlickDataView;
116
- slickGrid!: SlickGrid;
117
- groupingDefinition: any = {};
118
- groupItemMetadataProvider?: SlickGroupItemMetadataProvider;
119
- backendServiceApi?: BackendServiceApi;
120
- locales!: Locale;
121
- metrics?: Metrics;
122
- showPagination = false;
123
- serviceList: any[] = [];
124
- totalItems = 0;
125
- paginationData?: {
126
- gridOptions: GridOption;
127
- paginationService: PaginationService;
128
- };
129
- subscriptions: EventSubscription[] = [];
130
-
131
- // components / plugins
132
- slickEmptyWarning?: SlickEmptyWarningComponent;
133
- slickFooter?: SlickFooterComponent;
134
- slickPagination?: BasePaginationComponent;
135
- paginationComponent: BasePaginationComponent | undefined;
136
- slickRowDetailView?: SlickRowDetailView;
137
-
138
- // services
139
- backendUtilityService!: BackendUtilityService;
140
- collectionService: CollectionService;
141
- extensionService: ExtensionService;
142
- extensionUtility: ExtensionUtility;
143
- filterFactory!: FilterFactory;
144
- filterService: FilterService;
145
- gridEventService: GridEventService;
146
- gridService: GridService;
147
- gridStateService: GridStateService;
148
- headerGroupingService: HeaderGroupingService;
149
- paginationService: PaginationService;
150
- resizerService!: ResizerService;
151
- rxjs?: RxJsFacade;
152
- sharedService: SharedService;
153
- sortService: SortService;
154
- treeDataService: TreeDataService;
155
-
156
- @Input() customDataView: any;
157
- @Input() gridId = '';
158
- @Input() options: GridOption = {};
159
-
160
- @Input()
161
- get paginationOptions(): Pagination | undefined {
162
- return this._paginationOptions;
163
- }
164
- set paginationOptions(newPaginationOptions: Pagination | undefined) {
165
- if (newPaginationOptions && this._paginationOptions) {
166
- this._paginationOptions = { ...this.options.pagination, ...this._paginationOptions, ...newPaginationOptions };
167
- } else {
168
- this._paginationOptions = newPaginationOptions;
169
- }
170
- this.options.pagination = this._paginationOptions ?? this.options.pagination;
171
- this.paginationService.updateTotalItems(this.options.pagination?.totalItems ?? 0, true);
172
- }
173
-
174
- @Input()
175
- get columns(): Column[] {
176
- return this._columnDefinitions;
177
- }
178
- set columns(columns: Column[]) {
179
- this._columnDefinitions = columns;
180
- if (this._isGridInitialized) {
181
- this.updateColumnDefinitionsList(columns);
182
- }
183
- if (columns.length > 0) {
184
- this.copyColumnWidthsReference(columns);
185
- }
186
- }
187
-
188
- // make the columnDefinitions a 2-way binding so that plugin adding cols
189
- // are synched on user's side as well (RowMove, RowDetail, RowSelections)
190
- @Output() columnsChange = new EventEmitter(true);
191
-
192
- @Input()
193
- get dataset(): any[] {
194
- return (this.customDataView ? this.slickGrid?.getData?.() : this.dataView?.getItems()) || [];
195
- }
196
- set dataset(newDataset: any[]) {
197
- const prevDatasetLn = this._currentDatasetLength;
198
- const isDatasetEqual = dequal(newDataset, this._dataset || []);
199
- let data = newDataset;
200
-
201
- // when Tree Data is enabled and we don't yet have the hierarchical dataset filled, we can force a convert+sort of the array
202
- if (
203
- this.slickGrid &&
204
- this.options?.enableTreeData &&
205
- Array.isArray(newDataset) &&
206
- (newDataset.length > 0 || newDataset.length !== prevDatasetLn || !isDatasetEqual)
207
- ) {
208
- this._isDatasetHierarchicalInitialized = false;
209
- data = this.sortTreeDataset(newDataset, !isDatasetEqual); // if dataset changed, then force a refresh anyway
210
- }
211
- this._dataset = data;
212
- this.refreshGridData(data || []);
213
- this._currentDatasetLength = (newDataset || []).length;
214
-
215
- // expand/autofit columns on first page load
216
- // we can assume that if the prevDataset was empty then we are on first load
217
- if (this.slickGrid && this.options?.autoFitColumnsOnFirstLoad && prevDatasetLn === 0 && !this._isAutosizeColsCalled) {
218
- this.slickGrid.autosizeColumns();
219
- this._isAutosizeColsCalled = true;
220
- }
221
- this.suggestDateParsingWhenHelpful();
222
- }
223
-
224
- @Input()
225
- get datasetHierarchical(): any[] | undefined {
226
- return this.sharedService.hierarchicalDataset;
227
- }
228
- set datasetHierarchical(newHierarchicalDataset: any[] | undefined) {
229
- const isDatasetEqual = dequal(newHierarchicalDataset, this.sharedService?.hierarchicalDataset ?? []);
230
- const prevFlatDatasetLn = this._currentDatasetLength;
231
- this.sharedService.hierarchicalDataset = newHierarchicalDataset;
232
-
233
- if (newHierarchicalDataset && this.columns && this.filterService?.clearFilters) {
234
- this.filterService.clearFilters();
235
- }
236
-
237
- // 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
238
- if (newHierarchicalDataset && this.slickGrid && this.sortService?.processTreeDataInitialSort) {
239
- this.sortService.processTreeDataInitialSort();
240
-
241
- // 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
242
- // however we need to queue our process until the flat dataset is ready, so we can queue a microtask to execute the DataView refresh only after everything is ready
243
- queueMicrotask(() => {
244
- const flatDatasetLn = this.dataView.getItemCount();
245
- if (flatDatasetLn > 0 && (flatDatasetLn !== prevFlatDatasetLn || !isDatasetEqual)) {
246
- this.filterService.refreshTreeDataFilters();
247
- }
248
- });
249
- this._isDatasetHierarchicalInitialized = true;
250
- }
251
- }
252
-
253
- get elementRef(): ElementRef {
254
- return this.elm;
255
- }
256
-
257
- get backendService(): BackendService | undefined {
258
- return this.options?.backendServiceApi?.service;
259
- }
260
-
261
- get eventHandler(): SlickEventHandler {
262
- return this._eventHandler;
263
- }
264
-
265
- get gridContainerElement(): HTMLElement | null {
266
- return document.querySelector(`#${this.options.gridContainerId || ''}`);
267
- }
268
-
269
- /** GETTER to know if dataset was initialized or not */
270
- get isDatasetInitialized(): boolean {
271
- return this._isDatasetInitialized;
272
- }
273
- /** SETTER to change if dataset was initialized or not (stringly used for unit testing purposes) */
274
- set isDatasetInitialized(isInitialized: boolean) {
275
- this._isDatasetInitialized = isInitialized;
276
- }
277
- set isDatasetHierarchicalInitialized(isInitialized: boolean) {
278
- this._isDatasetHierarchicalInitialized = isInitialized;
279
- }
280
-
281
- get registeredResources(): ExternalResource[] {
282
- return this._registeredResources;
283
- }
284
-
285
- @ContentChild('slickgridHeader', { static: true }) slickgridHeader?: TemplateRef<any>;
286
- @ContentChild('slickgridFooter', { static: true }) slickgridFooter?: TemplateRef<any>;
287
-
288
- constructor(
289
- protected readonly angularUtilService: AngularUtilService,
290
- protected readonly appRef: ApplicationRef,
291
- protected readonly cd: ChangeDetectorRef,
292
- protected readonly containerService: ContainerService,
293
- protected readonly elm: ElementRef,
294
- @Optional() protected readonly translate: TranslateService,
295
- @Optional() protected readonly translaterService: TranslaterService,
296
- @Inject('config') protected forRootConfig: GridOption,
297
- @Inject('externalService') externalServices: ExternalTestingDependencies
298
- ) {
299
- const slickgridConfig = new SlickgridConfig();
300
-
301
- // initialize and assign all Service Dependencies
302
- this._eventPubSubService = externalServices?.eventPubSubService ?? new EventPubSubService(this.elm.nativeElement);
303
- this._eventPubSubService.eventNamingStyle = EventNamingStyle.camelCase;
304
-
305
- this.backendUtilityService = externalServices?.backendUtilityService ?? new BackendUtilityService();
306
- this.gridEventService = externalServices?.gridEventService ?? new GridEventService();
307
- this.sharedService = externalServices?.sharedService ?? new SharedService();
308
- this.collectionService = externalServices?.collectionService ?? new CollectionService(this.translaterService);
309
- // prettier-ignore
310
- this.extensionUtility = externalServices?.extensionUtility ?? new ExtensionUtility(this.sharedService, this.backendUtilityService, this.translaterService);
311
- this.filterFactory = new FilterFactory(slickgridConfig, this.translaterService, this.collectionService);
312
- // prettier-ignore
313
- this.filterService = externalServices?.filterService ?? new FilterService(this.filterFactory as any, this._eventPubSubService, this.sharedService, this.backendUtilityService);
314
- this.resizerService = externalServices?.resizerService ?? new ResizerService(this._eventPubSubService);
315
- // prettier-ignore
316
- this.sortService = externalServices?.sortService ?? new SortService(this.collectionService, this.sharedService, this._eventPubSubService, this.backendUtilityService);
317
- this.treeDataService =
318
- externalServices?.treeDataService ?? new TreeDataService(this._eventPubSubService, this.sharedService, this.sortService);
319
- // prettier-ignore
320
- this.paginationService = externalServices?.paginationService ?? new PaginationService(this._eventPubSubService, this.sharedService, this.backendUtilityService);
321
-
322
- this.extensionService =
323
- externalServices?.extensionService ??
324
- new ExtensionService(
325
- this.extensionUtility,
326
- this.filterService,
327
- this._eventPubSubService,
328
- this.sharedService,
329
- this.sortService,
330
- this.treeDataService,
331
- this.translaterService,
332
- () => this.gridService
333
- );
334
-
335
- // prettier-ignore
336
- /* v8 ignore next 8 */
337
- this.gridStateService = externalServices?.gridStateService ?? new GridStateService(
338
- this.extensionService,
339
- this.filterService,
340
- this._eventPubSubService,
341
- this.sharedService,
342
- this.sortService,
343
- this.treeDataService
344
- );
345
-
346
- // prettier-ignore
347
- /* v8 ignore next 9 */
348
- this.gridService = externalServices?.gridService ?? new GridService(
349
- this.gridStateService,
350
- this.filterService,
351
- this._eventPubSubService,
352
- this.paginationService,
353
- this.sharedService,
354
- this.sortService,
355
- this.treeDataService
356
- );
357
- this.headerGroupingService = externalServices?.headerGroupingService ?? new HeaderGroupingService(this.extensionUtility);
358
-
359
- this.serviceList = [
360
- this.containerService,
361
- this.extensionService,
362
- this.filterService,
363
- this.gridEventService,
364
- this.gridService,
365
- this.gridStateService,
366
- this.headerGroupingService,
367
- this.paginationService,
368
- this.resizerService,
369
- this.sortService,
370
- this.treeDataService,
371
- ];
372
-
373
- // register all Service instances in the container
374
- this.containerService.registerInstance('ExtensionUtility', this.extensionUtility);
375
- this.containerService.registerInstance('FilterService', this.filterService);
376
- this.containerService.registerInstance('CollectionService', this.collectionService);
377
- this.containerService.registerInstance('ExtensionService', this.extensionService);
378
- this.containerService.registerInstance('GridEventService', this.gridEventService);
379
- this.containerService.registerInstance('GridService', this.gridService);
380
- this.containerService.registerInstance('GridStateService', this.gridStateService);
381
- this.containerService.registerInstance('HeaderGroupingService', this.headerGroupingService);
382
- this.containerService.registerInstance('PaginationService', this.paginationService);
383
- this.containerService.registerInstance('ResizerService', this.resizerService);
384
- this.containerService.registerInstance('SharedService', this.sharedService);
385
- this.containerService.registerInstance('SortService', this.sortService);
386
- this.containerService.registerInstance('EventPubSubService', this._eventPubSubService);
387
- this.containerService.registerInstance('PubSubService', this._eventPubSubService);
388
- this.containerService.registerInstance('TranslaterService', this.translaterService);
389
- this.containerService.registerInstance('TreeDataService', this.treeDataService);
390
- }
391
-
392
- ngAfterViewInit() {
393
- if (!this.columns) {
394
- throw new Error(
395
- 'Using `<angular-slickgrid>` requires [columns], it seems that you might have forgot to provide the missing bindable input.'
396
- );
397
- }
398
- this.initialization(this._eventHandler);
399
- this._isGridInitialized = true;
400
-
401
- // recheck the empty warning message after grid is shown so that it works in every use case
402
- if (this.options?.enableEmptyDataWarningMessage && Array.isArray(this.dataset)) {
403
- const finalTotalCount = this.dataset.length;
404
- this.displayEmptyDataWarning(finalTotalCount < 1);
405
- }
406
-
407
- // add dark mode CSS class when enabled
408
- if (this.options.darkMode) {
409
- this.setDarkMode(true);
410
- }
411
-
412
- this.suggestDateParsingWhenHelpful();
413
- }
414
-
415
- ngOnDestroy(): void {
416
- this._eventPubSubService.publish('onBeforeGridDestroy', this.slickGrid);
417
- this.destroy();
418
- this._eventPubSubService.publish('onAfterGridDestroyed', true);
419
- }
420
-
421
- destroy(shouldEmptyDomElementContainer = false) {
422
- // dispose of all Services
423
- this.serviceList.forEach((service: any) => {
424
- if (typeof service?.dispose === 'function') {
425
- service.dispose();
426
- }
427
- });
428
- this.serviceList = [];
429
-
430
- // dispose backend service when defined and a dispose method exists
431
- this.backendService?.dispose?.();
432
-
433
- // dispose all registered external resources
434
- this.disposeExternalResources();
435
-
436
- // dispose the Components
437
- this.slickEmptyWarning?.dispose();
438
- this.slickFooter?.dispose();
439
- this.slickPagination?.dispose();
440
-
441
- if (this._eventHandler?.unsubscribeAll) {
442
- this._eventHandler.unsubscribeAll();
443
- }
444
- this._eventPubSubService?.unsubscribeAll();
445
- if (this.dataView) {
446
- this.dataView.setItems([]);
447
- this.dataView.destroy();
448
- }
449
- if (this.slickGrid?.destroy) {
450
- this.slickGrid.destroy(shouldEmptyDomElementContainer);
451
- }
452
-
453
- if (this.backendServiceApi) {
454
- for (const prop of Object.keys(this.backendServiceApi)) {
455
- delete this.backendServiceApi[prop as keyof BackendServiceApi];
456
- }
457
- this.backendServiceApi = undefined;
458
- }
459
- if (this.columns) {
460
- for (const prop of Object.keys(this.columns)) {
461
- (this.columns as any)[prop] = null;
462
- }
463
- }
464
- for (const prop of Object.keys(this.sharedService)) {
465
- (this.sharedService as any)[prop] = null;
466
- }
467
-
468
- // we could optionally also empty the content of the grid container DOM element
469
- if (shouldEmptyDomElementContainer) {
470
- this.emptyGridContainerElm();
471
- }
472
-
473
- // also unsubscribe all RxJS subscriptions
474
- this.subscriptions = unsubscribeAll(this.subscriptions);
475
-
476
- this._dataset = null;
477
- this.datasetHierarchical = undefined;
478
- this._columnDefinitions = [];
479
- this._angularGridInstances = undefined;
480
- this.slickGrid = undefined as any;
481
- }
482
-
483
- disposeExternalResources() {
484
- if (Array.isArray(this._registeredResources)) {
485
- while (this._registeredResources.length > 0) {
486
- const res = this._registeredResources.pop();
487
- if (res?.dispose) {
488
- res.dispose();
489
- }
490
- }
491
- }
492
- this._registeredResources = [];
493
- }
494
-
495
- emptyGridContainerElm() {
496
- const gridContainerId = this.options?.gridContainerId || 'grid1';
497
- const gridContainerElm = document.querySelector(`#${gridContainerId}`);
498
- emptyElement(gridContainerElm);
499
- }
500
-
501
- /**
502
- * Define our internal Post Process callback, it will execute internally after we get back result from the Process backend call
503
- * Currently ONLY available with the GraphQL Backend Service.
504
- * The behavior is to refresh the Dataset & Pagination without requiring the user to create his own PostProcess every time
505
- */
506
- createBackendApiInternalPostProcessCallback(gridOptions: GridOption) {
507
- const backendApi = gridOptions?.backendServiceApi;
508
- if (backendApi?.service) {
509
- const backendApiService = backendApi.service;
510
-
511
- // internalPostProcess only works (for now) with a GraphQL Service, so make sure it is of that type
512
- if (typeof backendApiService.getDatasetName === 'function') {
513
- backendApi.internalPostProcess = (processResult: any) => {
514
- // prettier-ignore
515
- const datasetName = backendApi && backendApiService && typeof backendApiService.getDatasetName === 'function' ? backendApiService.getDatasetName() : '';
516
- if (processResult?.data[datasetName]) {
517
- const data =
518
- 'nodes' in processResult.data[datasetName]
519
- ? (processResult as any).data[datasetName].nodes
520
- : (processResult as any).data[datasetName];
521
- const totalCount =
522
- 'totalCount' in processResult.data[datasetName]
523
- ? (processResult as any).data[datasetName].totalCount
524
- : (processResult as any).data[datasetName].length;
525
- this.refreshGridData(data, totalCount || 0);
526
- }
527
- };
528
- }
529
- }
530
- }
531
-
532
- initialization(eventHandler: SlickEventHandler) {
533
- this.options.translater = this.translaterService;
534
- this._eventHandler = eventHandler;
535
- this._isAutosizeColsCalled = false;
536
-
537
- // when detecting a frozen grid, we'll automatically enable the mousewheel scroll handler so that we can scroll from both left/right frozen containers
538
- if (
539
- this.options &&
540
- ((this.options.frozenRow !== undefined && this.options.frozenRow >= 0) ||
541
- (this.options.frozenColumn !== undefined && this.options.frozenColumn >= 0)) &&
542
- this.options.enableMouseWheelScrollHandler === undefined
543
- ) {
544
- this.options.enableMouseWheelScrollHandler = true;
545
- }
546
-
547
- this._eventPubSubService.eventNamingStyle = this.options?.eventNamingStyle ?? EventNamingStyle.camelCase;
548
- this._eventPubSubService.publish('onBeforeGridCreate', true);
549
-
550
- // make sure the dataset is initialized (if not it will throw an error that it cannot getLength of null)
551
- this._dataset ||= [];
552
- this.options = this.mergeGridOptions(this.options);
553
- this._paginationOptions = this.options?.pagination;
554
- this.locales = this.options?.locales ?? Constants.locales;
555
- this.backendServiceApi = this.options?.backendServiceApi;
556
- this._isLocalGrid = !this.backendServiceApi; // considered a local grid if it doesn't have a backend service set
557
-
558
- // unless specified, we'll create an internal postProcess callback (currently only available for GraphQL)
559
- if (this.options.backendServiceApi && !this.options.backendServiceApi?.disableInternalPostProcess) {
560
- this.createBackendApiInternalPostProcessCallback(this.options);
561
- }
562
-
563
- if (!this.customDataView) {
564
- const dataviewInlineFilters = this.options?.dataView?.inlineFilters ?? false;
565
- let dataViewOptions: Partial<DataViewOption> = { ...this.options.dataView, inlineFilters: dataviewInlineFilters };
566
-
567
- if (this.options.draggableGrouping || this.options.enableGrouping) {
568
- this.groupItemMetadataProvider = new SlickGroupItemMetadataProvider();
569
- this.sharedService.groupItemMetadataProvider = this.groupItemMetadataProvider;
570
- dataViewOptions = { ...dataViewOptions, groupItemMetadataProvider: this.groupItemMetadataProvider };
571
- }
572
- this.dataView = new SlickDataView<TData>(dataViewOptions, this._eventPubSubService);
573
- this._eventPubSubService.publish('onDataviewCreated', this.dataView);
574
- }
575
-
576
- // get any possible Services that user want to register which don't require SlickGrid to be instantiated
577
- // RxJS Resource is in this lot because it has to be registered before anything else and doesn't require SlickGrid to be initialized
578
- this.preRegisterResources();
579
-
580
- // prepare and load all SlickGrid editors, if an async editor is found then we'll also execute it.
581
- this._columnDefinitions = this.loadSlickGridEditors(this._columnDefinitions || []);
582
-
583
- // if the user wants to automatically add a Custom Editor Formatter, we need to call the auto add function again
584
- if (this.options.autoAddCustomEditorFormatter) {
585
- autoAddEditorFormatterToColumnsWithEditor(this._columnDefinitions, this.options.autoAddCustomEditorFormatter);
586
- }
587
-
588
- // save reference for all columns before they optionally become hidden/visible
589
- this.sharedService.allColumns = this._columnDefinitions;
590
- this.sharedService.visibleColumns = this._columnDefinitions;
591
-
592
- // before certain extentions/plugins potentially adds extra columns not created by the user itself (RowMove, RowDetail, RowSelections)
593
- // 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
594
- this.subscriptions.push(
595
- this._eventPubSubService.subscribe<{ columns: Column[]; grid: SlickGrid }>('onPluginColumnsChanged', (data) => {
596
- this._columnDefinitions = data.columns;
597
- this.columnsChange.emit(this._columnDefinitions);
598
- })
599
- );
600
-
601
- // after subscribing to potential columns changed, we are ready to create these optional extensions
602
- // when we did find some to create (RowMove, RowDetail, RowSelections), it will automatically modify column definitions (by previous subscribe)
603
- this.extensionService.createExtensionsBeforeGridCreation(this._columnDefinitions, this.options);
604
-
605
- // if user entered some Pinning/Frozen "presets", we need to apply them in the grid options
606
- if (this.options.presets?.pinning) {
607
- this.options = { ...this.options, ...this.options.presets.pinning };
608
- }
609
-
610
- // build SlickGrid Grid, also user might optionally pass a custom dataview (e.g. remote model)
611
- this.slickGrid = new SlickGrid<TData, Column<TData>, GridOption<Column<TData>>>(
612
- `#${this.gridId}`,
613
- this.customDataView || (this.dataView as SlickDataView<TData>),
614
- this._columnDefinitions,
615
- this.options,
616
- this._eventPubSubService
617
- );
618
- this.sharedService.dataView = this.dataView;
619
- this.sharedService.slickGrid = this.slickGrid;
620
- this.sharedService.gridContainerElement = this.elm.nativeElement as HTMLDivElement;
621
- if (this.groupItemMetadataProvider) {
622
- this.slickGrid.registerPlugin(this.groupItemMetadataProvider); // register GroupItemMetadataProvider when Grouping is enabled
623
- }
624
-
625
- this.extensionService.bindDifferentExtensions();
626
- this.bindDifferentHooks(this.slickGrid, this.options, this.dataView);
627
-
628
- // 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
629
- const frozenColumnIndex = this.options.frozenColumn !== undefined ? this.options.frozenColumn : -1;
630
- if (frozenColumnIndex >= 0 && frozenColumnIndex <= this._columnDefinitions.length) {
631
- this.sharedService.frozenVisibleColumnId = this._columnDefinitions[frozenColumnIndex].id || '';
632
- }
633
-
634
- // get any possible Services that user want to register
635
- this.registerResources();
636
-
637
- // initialize the SlickGrid grid
638
- this.slickGrid.init();
639
-
640
- // initialized the resizer service only after SlickGrid is initialized
641
- // 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)
642
- if (this.gridContainerElement) {
643
- this.resizerService.init(this.slickGrid, this.gridContainerElement as HTMLDivElement);
644
- }
645
-
646
- // user could show a custom footer with the data metrics (dataset length and last updated timestamp)
647
- if (!this.options.enablePagination && this.options.showCustomFooter && this.options.customFooterOptions && this.gridContainerElement) {
648
- this.slickFooter = new SlickFooterComponent(
649
- this.slickGrid,
650
- this.options.customFooterOptions,
651
- this._eventPubSubService,
652
- this.translaterService
653
- );
654
- this.slickFooter.renderFooter(this.gridContainerElement);
655
- }
656
-
657
- if (!this.customDataView && this.dataView) {
658
- // load the data in the DataView (unless it's a hierarchical dataset, if so it will be loaded after the initial tree sort)
659
- const initialDataset = this.options?.enableTreeData ? this.sortTreeDataset(this._dataset) : this._dataset;
660
- this.dataView.beginUpdate();
661
- this.dataView.setItems(initialDataset || [], this.options.datasetIdPropertyName ?? 'id');
662
- this.dataView.endUpdate();
663
-
664
- // if you don't want the items that are not visible (due to being filtered out or being on a different page)
665
- // to stay selected, pass 'false' to the second arg
666
- if (this.slickGrid?.getSelectionModel() && this.options?.dataView && 'syncGridSelection' in this.options.dataView) {
667
- // if we are using a Backend Service, we will do an extra flag check, the reason is because it might have some unintended behaviors
668
- // with the BackendServiceApi because technically the data in the page changes the DataView on every page change.
669
- let preservedRowSelectionWithBackend = false;
670
- if (this.options.backendServiceApi && 'syncGridSelectionWithBackendService' in this.options.dataView) {
671
- preservedRowSelectionWithBackend = this.options.dataView.syncGridSelectionWithBackendService as boolean;
672
- }
673
-
674
- const syncGridSelection = this.options.dataView.syncGridSelection;
675
- if (typeof syncGridSelection === 'boolean') {
676
- let preservedRowSelection = syncGridSelection;
677
- if (!this._isLocalGrid) {
678
- // when using BackendServiceApi, we'll be using the "syncGridSelectionWithBackendService" flag BUT "syncGridSelection" must also be set to True
679
- preservedRowSelection = syncGridSelection && preservedRowSelectionWithBackend;
680
- }
681
- this.dataView.syncGridSelection(this.slickGrid, preservedRowSelection);
682
- } else if (typeof syncGridSelection === 'object') {
683
- this.dataView.syncGridSelection(
684
- this.slickGrid,
685
- syncGridSelection.preserveHidden,
686
- syncGridSelection.preserveHiddenOnSelectionChange
687
- );
688
- }
689
- }
690
-
691
- const datasetLn = this.dataView.getLength() || this._dataset?.length || 0;
692
- if (datasetLn > 0) {
693
- if (!this._isDatasetInitialized && (this.options.enableCheckboxSelector || this.options.enableRowSelection)) {
694
- this.loadRowSelectionPresetWhenExists();
695
- }
696
- this.loadFilterPresetsWhenDatasetInitialized();
697
- this._isDatasetInitialized = true;
698
- }
699
- }
700
-
701
- // user might want to hide the header row on page load but still have `enableFiltering: true`
702
- // if that is the case, we need to hide the headerRow ONLY AFTER all filters got created & dataView exist
703
- if (this._hideHeaderRowAfterPageLoad) {
704
- this.showHeaderRow(false);
705
- this.sharedService.hideHeaderRowAfterPageLoad = this._hideHeaderRowAfterPageLoad;
706
- }
707
-
708
- // publish & dispatch certain events
709
- this._eventPubSubService.publish('onGridCreated', this.slickGrid);
710
-
711
- // after the DataView is created & updated execute some processes
712
- if (!this.customDataView) {
713
- this.executeAfterDataviewCreated(this.slickGrid, this.options);
714
- }
715
-
716
- // bind resize ONLY after the dataView is ready
717
- this.bindResizeHook(this.slickGrid, this.options);
718
-
719
- // bind the Backend Service API callback functions only after the grid is initialized
720
- // because the preProcess() and onInit() might get triggered
721
- if (this.options?.backendServiceApi) {
722
- this.bindBackendCallbackFunctions(this.options);
723
- }
724
-
725
- // local grid, check if we need to show the Pagination
726
- // if so then also check if there's any presets and finally initialize the PaginationService
727
- // 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
728
- if (this.options?.enablePagination && this._isLocalGrid) {
729
- this.showPagination = true;
730
- this.loadLocalGridPagination(this.dataset);
731
- }
732
-
733
- this._angularGridInstances = {
734
- // Slick Grid & DataView objects
735
- dataView: this.dataView,
736
- slickGrid: this.slickGrid,
737
- extensions: this.extensionService?.extensionList,
738
-
739
- // public methods
740
- destroy: this.destroy.bind(this),
741
-
742
- // return all available Services (non-singleton)
743
- backendService: this.backendService,
744
- eventPubSubService: this._eventPubSubService,
745
- filterService: this.filterService,
746
- gridEventService: this.gridEventService,
747
- gridStateService: this.gridStateService,
748
- gridService: this.gridService,
749
- headerGroupingService: this.headerGroupingService,
750
- extensionService: this.extensionService,
751
- paginationComponent: this.slickPagination,
752
- paginationService: this.paginationService,
753
- resizerService: this.resizerService,
754
- sortService: this.sortService,
755
- treeDataService: this.treeDataService,
756
- };
757
-
758
- // all instances (SlickGrid, DataView & all Services)
759
- this._eventPubSubService.publish('onAngularGridCreated', this._angularGridInstances);
760
- }
761
-
762
- /**
763
- * On a Pagination changed, we will trigger a Grid State changed with the new pagination info
764
- * Also if we use Row Selection or the Checkbox Selector with a Backend Service (Odata, GraphQL), we need to reset any selection
765
- */
766
- paginationChanged(pagination: PaginationMetadata) {
767
- const isSyncGridSelectionEnabled = this.gridStateService?.needToPreserveRowSelection() ?? false;
768
- if (
769
- this.slickGrid &&
770
- !isSyncGridSelectionEnabled &&
771
- this.options?.backendServiceApi &&
772
- (this.options.enableRowSelection || this.options.enableCheckboxSelector)
773
- ) {
774
- this.slickGrid.setSelectedRows([]);
775
- }
776
- const { pageNumber, pageSize } = pagination;
777
- if (this.sharedService) {
778
- if (pageSize !== undefined && pageNumber !== undefined) {
779
- this.sharedService.currentPagination = { pageNumber, pageSize };
780
- }
781
- }
782
- this._eventPubSubService.publish('onGridStateChanged', {
783
- change: { newValues: { pageNumber, pageSize }, type: 'pagination' },
784
- gridState: this.gridStateService.getCurrentGridState(),
785
- });
786
- this.cd.markForCheck();
787
- }
788
-
789
- /**
790
- * When dataset changes, we need to refresh the entire grid UI & possibly resize it as well
791
- * @param dataset
792
- */
793
- refreshGridData(dataset: any[], totalCount?: number) {
794
- if (this.options?.enableEmptyDataWarningMessage && Array.isArray(dataset)) {
795
- const finalTotalCount = totalCount || dataset.length;
796
- this.displayEmptyDataWarning(finalTotalCount < 1);
797
- }
798
-
799
- if (Array.isArray(dataset) && this.slickGrid && this.dataView?.setItems) {
800
- this.dataView.setItems(dataset, this.options.datasetIdPropertyName ?? 'id');
801
- if (!this.options.backendServiceApi && !this.options.enableTreeData) {
802
- this.dataView.reSort();
803
- }
804
-
805
- if (dataset.length > 0) {
806
- if (!this._isDatasetInitialized) {
807
- this.loadFilterPresetsWhenDatasetInitialized();
808
-
809
- if (this.options.enableCheckboxSelector) {
810
- this.loadRowSelectionPresetWhenExists();
811
- }
812
- }
813
- this._isDatasetInitialized = true;
814
- }
815
-
816
- if (dataset) {
817
- this.slickGrid.invalidate();
818
- }
819
-
820
- // 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
821
- this.showPagination = !!(
822
- this.options &&
823
- (this.options.enablePagination || (this.options.backendServiceApi && this.options.enablePagination === undefined))
824
- );
825
-
826
- if (this._paginationOptions && this.options?.pagination && this.options?.backendServiceApi) {
827
- const paginationOptions = this.setPaginationOptionsWhenPresetDefined(this.options, this._paginationOptions as Pagination);
828
- // when we have a totalCount use it, else we'll take it from the pagination object
829
- // only update the total items if it's different to avoid refreshing the UI
830
- const totalRecords = totalCount !== undefined ? totalCount : this.options?.pagination?.totalItems;
831
- if (totalRecords !== undefined && totalRecords !== this.totalItems) {
832
- this.totalItems = +totalRecords;
833
- }
834
-
835
- // initialize the Pagination Service with new pagination options (which might have presets)
836
- if (!this._isPaginationInitialized) {
837
- this.initializePaginationService(paginationOptions);
838
- } else {
839
- // update the pagination service with the new total
840
- this.paginationService.updateTotalItems(this.totalItems);
841
- }
842
- }
843
-
844
- // resize the grid inside a slight timeout, in case other DOM element changed prior to the resize (like a filter/pagination changed)
845
- if (this.slickGrid && this.options.enableAutoResize) {
846
- const delay = this.options.autoResize && this.options.autoResize.delay;
847
- this.resizerService.resizeGrid(delay || 10);
848
- }
849
- }
850
- }
851
-
852
- setData(data: TData[], shouldAutosizeColumns = false) {
853
- if (shouldAutosizeColumns) {
854
- this._isAutosizeColsCalled = false;
855
- this._currentDatasetLength = 0;
856
- }
857
- this.dataset = data || [];
858
- }
859
-
860
- /**
861
- * Check if there's any Pagination Presets defined in the Grid Options,
862
- * if there are then load them in the paginationOptions object
863
- */
864
- protected setPaginationOptionsWhenPresetDefined(gridOptions: GridOption, paginationOptions: Pagination): Pagination {
865
- if (gridOptions.presets?.pagination && paginationOptions && !this._isPaginationInitialized) {
866
- if (this.hasBackendInfiniteScroll()) {
867
- console.warn('[Angular-Slickgrid] `presets.pagination` is not supported with Infinite Scroll, reverting to first page.');
868
- } else {
869
- paginationOptions.pageSize = gridOptions.presets.pagination.pageSize;
870
- paginationOptions.pageNumber = gridOptions.presets.pagination.pageNumber;
871
- }
872
- }
873
- return paginationOptions;
874
- }
875
-
876
- setDarkMode(dark = false) {
877
- if (dark) {
878
- this.sharedService.gridContainerElement?.classList.add('slick-dark-mode');
879
- } else {
880
- this.sharedService.gridContainerElement?.classList.remove('slick-dark-mode');
881
- }
882
- }
883
-
884
- /**
885
- * Dynamically change or update the column definitions list.
886
- * We will re-render the grid so that the new header and data shows up correctly.
887
- * If using i18n, we also need to trigger a re-translate of the column headers
888
- */
889
- updateColumnDefinitionsList(newColumns: Column[]) {
890
- // map the Editor model to editorClass and load editor collectionAsync
891
- newColumns = this.loadSlickGridEditors(newColumns);
892
-
893
- if (this.options.enableTranslate) {
894
- this.extensionService.translateColumnHeaders(undefined, newColumns);
895
- } else {
896
- this.extensionService.renderColumnHeaders(newColumns, true);
897
- }
898
-
899
- if (this.options?.enableAutoSizeColumns) {
900
- this.slickGrid.autosizeColumns();
901
- } else if (this.options?.enableAutoResizeColumnsByCellContent && this.resizerService?.resizeColumnsByCellContent) {
902
- this.resizerService.resizeColumnsByCellContent();
903
- }
904
- }
905
-
906
- /**
907
- * Show the filter row displayed on first row, we can optionally pass false to hide it.
908
- * @param showing
909
- */
910
- showHeaderRow(showing = true) {
911
- this.slickGrid.setHeaderRowVisibility(showing);
912
- if (showing === true && this._isGridInitialized) {
913
- this.slickGrid.setColumns(this.columns);
914
- }
915
- return showing;
916
- }
917
-
918
- /**
919
- * Toggle the empty data warning message visibility.
920
- * @param showWarning
921
- */
922
- displayEmptyDataWarning(showWarning = true) {
923
- this.slickEmptyWarning?.showEmptyDataMessage(showWarning);
924
- }
925
- //
926
- // protected functions
927
- // ------------------
928
-
929
- /**
930
- * Loop through all column definitions and copy the original optional `width` properties optionally provided by the user.
931
- * We will use this when doing a resize by cell content, if user provided a `width` it won't override it.
932
- */
933
- protected copyColumnWidthsReference(columns: Column[]) {
934
- columns.forEach((col) => (col.originalWidth = col.width));
935
- }
936
-
937
- protected bindDifferentHooks(grid: SlickGrid, gridOptions: GridOption, dataView: SlickDataView) {
938
- // on locale change, we have to manually translate the Headers, GridMenu
939
- if (this.translate?.onLangChange) {
940
- // translate some of them on first load, then on each language change
941
- if (gridOptions.enableTranslate) {
942
- this.extensionService.translateAllExtensions();
943
- }
944
-
945
- this.subscriptions.push(
946
- this.translate.onLangChange.subscribe(({ lang }) => {
947
- // publish event of the same name that Slickgrid-Universal uses on a language change event
948
- this._eventPubSubService.publish('onLanguageChange');
949
-
950
- if (gridOptions.enableTranslate) {
951
- this.extensionService.translateAllExtensions(lang);
952
- if (
953
- (gridOptions.createPreHeaderPanel && gridOptions.createTopHeaderPanel) ||
954
- (gridOptions.createPreHeaderPanel && !gridOptions.enableDraggableGrouping)
955
- ) {
956
- this.headerGroupingService.translateHeaderGrouping();
957
- }
958
- }
959
- })
960
- );
961
- }
962
-
963
- // if user set an onInit Backend, we'll run it right away (and if so, we also need to run preProcess, internalPostProcess & postProcess)
964
- if (gridOptions.backendServiceApi) {
965
- const backendApi = gridOptions.backendServiceApi;
966
-
967
- if (backendApi?.service?.init) {
968
- backendApi.service.init(backendApi.options, gridOptions.pagination, this.slickGrid, this.sharedService);
969
- }
970
- }
971
-
972
- if (dataView && grid) {
973
- // on cell click, mainly used with the columnDef.action callback
974
- this.gridEventService.bindOnCellChange(grid);
975
- this.gridEventService.bindOnClick(grid);
976
-
977
- // bind external sorting (backend) when available or default onSort (dataView)
978
- if (gridOptions.enableSorting) {
979
- // bind external sorting (backend) unless specified to use the local one
980
- if (gridOptions.backendServiceApi && !gridOptions.backendServiceApi.useLocalSorting) {
981
- this.sortService.bindBackendOnSort(grid);
982
- } else {
983
- this.sortService.bindLocalOnSort(grid);
984
- }
985
- }
986
-
987
- // bind external filter (backend) when available or default onFilter (dataView)
988
- if (gridOptions.enableFiltering) {
989
- this.filterService.init(grid);
990
-
991
- // bind external filter (backend) unless specified to use the local one
992
- if (gridOptions.backendServiceApi && !gridOptions.backendServiceApi.useLocalFiltering) {
993
- this.filterService.bindBackendOnFilter(grid);
994
- } else {
995
- this.filterService.bindLocalOnFilter(grid);
996
- }
997
- }
998
-
999
- // when column are reordered, we need to update the visibleColumn array
1000
- this._eventHandler.subscribe(grid.onColumnsReordered, (_e, args) => {
1001
- this.sharedService.hasColumnsReordered = true;
1002
- this.sharedService.visibleColumns = args.impactedColumns;
1003
- });
1004
-
1005
- this._eventHandler.subscribe(grid.onSetOptions, (_e, args) => {
1006
- // add/remove dark mode CSS class when enabled
1007
- if (args.optionsBefore.darkMode !== args.optionsAfter.darkMode && this.gridContainerElement) {
1008
- this.setDarkMode(args.optionsAfter.darkMode);
1009
- }
1010
- });
1011
-
1012
- // load any presets if any (after dataset is initialized)
1013
- this.loadColumnPresetsWhenDatasetInitialized();
1014
- this.loadFilterPresetsWhenDatasetInitialized();
1015
-
1016
- // When data changes in the DataView, we need to refresh the metrics and/or display a warning if the dataset is empty
1017
- this._eventHandler.subscribe(dataView.onRowCountChanged, (_e, args) => {
1018
- if (!gridOptions.enableRowDetailView || !Array.isArray(args.changedRows) || args.changedRows.length === args.itemCount) {
1019
- grid.invalidate();
1020
- } else {
1021
- grid.invalidateRows(args.changedRows);
1022
- grid.render();
1023
- }
1024
- this.handleOnItemCountChanged(dataView.getFilteredItemCount() || 0, dataView.getItemCount() || 0);
1025
- });
1026
- this._eventHandler.subscribe(dataView.onSetItemsCalled, (_e, args) => {
1027
- this.sharedService.isItemsDateParsed = false;
1028
- this.handleOnItemCountChanged(dataView.getFilteredItemCount() || 0, args.itemCount);
1029
-
1030
- // when user has resize by content enabled, we'll force a full width calculation since we change our entire dataset
1031
- if (
1032
- args.itemCount > 0 &&
1033
- (this.options.autosizeColumnsByCellContentOnFirstLoad || this.options.enableAutoResizeColumnsByCellContent)
1034
- ) {
1035
- this.resizerService.resizeColumnsByCellContent(!this.options?.resizeByContentOnlyOnFirstLoad);
1036
- }
1037
- });
1038
-
1039
- if (gridOptions?.enableFiltering && !gridOptions.enableRowDetailView) {
1040
- this._eventHandler.subscribe(dataView.onRowsChanged, (_e, { calledOnRowCountChanged, rows }) => {
1041
- // filtering data with local dataset will not always show correctly unless we call this updateRow/render
1042
- // also don't use "invalidateRows" since it destroys the entire row and as bad user experience when updating a row
1043
- // see commit: https://github.com/ghiscoding/aurelia-slickgrid/commit/8c503a4d45fba11cbd8d8cc467fae8d177cc4f60
1044
- if (!calledOnRowCountChanged && Array.isArray(rows)) {
1045
- const ranges = grid.getRenderedRange();
1046
- rows.filter((row) => row >= ranges.top && row <= ranges.bottom).forEach((row: number) => grid.updateRow(row));
1047
- grid.render();
1048
- }
1049
- });
1050
- }
1051
- }
1052
- }
1053
-
1054
- protected bindBackendCallbackFunctions(gridOptions: GridOption) {
1055
- const backendApi = gridOptions.backendServiceApi;
1056
- const backendApiService = backendApi?.service;
1057
- const serviceOptions: BackendServiceOption = backendApiService?.options ?? {};
1058
- // prettier-ignore
1059
- const isExecuteCommandOnInit = (!serviceOptions) ? false : ((serviceOptions && 'executeProcessCommandOnInit' in serviceOptions) ? serviceOptions['executeProcessCommandOnInit'] : true);
1060
-
1061
- if (backendApiService) {
1062
- // update backend filters (if need be) BEFORE the query runs (via the onInit command a few lines below)
1063
- // if user entered some any "presets", we need to reflect them all in the grid
1064
- if (gridOptions?.presets) {
1065
- // Filters "presets"
1066
- if (backendApiService.updateFilters && Array.isArray(gridOptions.presets.filters) && gridOptions.presets.filters.length > 0) {
1067
- backendApiService.updateFilters(gridOptions.presets.filters, true);
1068
- }
1069
- // Sorters "presets"
1070
- if (backendApiService.updateSorters && Array.isArray(gridOptions.presets.sorters) && gridOptions.presets.sorters.length > 0) {
1071
- // when using multi-column sort, we can have multiple but on single sort then only grab the first sort provided
1072
- const sortColumns = this.options.multiColumnSort ? gridOptions.presets.sorters : gridOptions.presets.sorters.slice(0, 1);
1073
- backendApiService.updateSorters(undefined, sortColumns);
1074
- }
1075
- // Pagination "presets"
1076
- if (backendApiService.updatePagination && gridOptions.presets.pagination && !this.hasBackendInfiniteScroll()) {
1077
- const { pageNumber, pageSize } = gridOptions.presets.pagination;
1078
- backendApiService.updatePagination(pageNumber, pageSize);
1079
- }
1080
- } else {
1081
- const columnFilters = this.filterService.getColumnFilters();
1082
- if (columnFilters && backendApiService.updateFilters) {
1083
- backendApiService.updateFilters(columnFilters, false);
1084
- }
1085
- }
1086
-
1087
- // execute onInit command when necessary
1088
- if (backendApi && backendApiService && (backendApi.onInit || isExecuteCommandOnInit)) {
1089
- const query = typeof backendApiService.buildQuery === 'function' ? backendApiService.buildQuery() : '';
1090
- // prettier-ignore
1091
- const process = (isExecuteCommandOnInit) ? (backendApi.process && backendApi.process(query) || null) : (backendApi.onInit && backendApi.onInit(query) || null);
1092
-
1093
- // wrap this inside a microtask to be executed at the end of the task and avoid timing issue since the gridOptions needs to be ready before running this onInit
1094
- queueMicrotask(() => {
1095
- const backendUtilityService = this.backendUtilityService as BackendUtilityService;
1096
-
1097
- // keep start time & end timestamps & return it after process execution
1098
- const startTime = new Date();
1099
-
1100
- // run any pre-process, if defined, for example a spinner
1101
- if (backendApi.preProcess) {
1102
- backendApi.preProcess();
1103
- }
1104
-
1105
- // the processes can be a Promise (like Http)
1106
- const totalItems = this.options?.pagination?.totalItems ?? 0;
1107
- if (process instanceof Promise) {
1108
- process
1109
- .then((processResult: any) =>
1110
- backendUtilityService.executeBackendProcessesCallback(startTime, processResult, backendApi, totalItems)
1111
- )
1112
- .catch((error) => backendUtilityService.onBackendError(error, backendApi));
1113
- } else if (process && this.rxjs?.isObservable(process)) {
1114
- this.subscriptions.push(
1115
- (process as Observable<any>).subscribe({
1116
- next: (processResult: any) =>
1117
- backendUtilityService.executeBackendProcessesCallback(startTime, processResult, backendApi, totalItems),
1118
- error: (error: any) => backendUtilityService.onBackendError(error, backendApi),
1119
- })
1120
- );
1121
- }
1122
- });
1123
- }
1124
-
1125
- // when user enables Infinite Scroll
1126
- if (backendApi.service.options?.infiniteScroll) {
1127
- this.addBackendInfiniteScrollCallback();
1128
- }
1129
- }
1130
- }
1131
-
1132
- protected addBackendInfiniteScrollCallback(): void {
1133
- if (
1134
- this.slickGrid &&
1135
- this.options.backendServiceApi &&
1136
- this.hasBackendInfiniteScroll() &&
1137
- !this.options.backendServiceApi?.onScrollEnd
1138
- ) {
1139
- const onScrollEnd = () => {
1140
- this.backendUtilityService.setInfiniteScrollBottomHit(true);
1141
-
1142
- // even if we're not showing pagination, we still use pagination service behind the scene
1143
- // to keep track of the scroll position and fetch next set of data (aka next page)
1144
- // we also need a flag to know if we reached the of the dataset or not (no more pages)
1145
- this.paginationService.goToNextPage().then((hasNext) => {
1146
- if (!hasNext) {
1147
- this.backendUtilityService.setInfiniteScrollBottomHit(false);
1148
- }
1149
- });
1150
- };
1151
- this.options.backendServiceApi.onScrollEnd = onScrollEnd;
1152
-
1153
- // subscribe to SlickGrid onScroll to determine when reaching the end of the scroll bottom position
1154
- // run onScrollEnd() method when that happens
1155
- this._eventHandler.subscribe(this.slickGrid.onScroll, (_e, args) => {
1156
- const viewportElm = args.grid.getViewportNode()!;
1157
- if (
1158
- ['mousewheel', 'scroll'].includes(args.triggeredBy || '') &&
1159
- this.paginationService?.totalItems &&
1160
- args.scrollTop > 0 &&
1161
- Math.ceil(viewportElm.offsetHeight + args.scrollTop) >= args.scrollHeight
1162
- ) {
1163
- if (!this._scrollEndCalled) {
1164
- onScrollEnd();
1165
- this._scrollEndCalled = true;
1166
- }
1167
- }
1168
- });
1169
-
1170
- // use postProcess to identify when scrollEnd process is finished to avoid calling the scrollEnd multiple times
1171
- // we also need to keep a ref of the user's postProcess and call it after our own postProcess
1172
- const orgPostProcess = this.options.backendServiceApi.postProcess;
1173
- this.options.backendServiceApi.postProcess = (processResult: any) => {
1174
- this._scrollEndCalled = false;
1175
- if (orgPostProcess) {
1176
- orgPostProcess(processResult);
1177
- }
1178
- };
1179
- }
1180
- }
1181
-
1182
- protected bindResizeHook(grid: SlickGrid, options: GridOption) {
1183
- if (
1184
- (options.autoFitColumnsOnFirstLoad && options.autosizeColumnsByCellContentOnFirstLoad) ||
1185
- (options.enableAutoSizeColumns && options.enableAutoResizeColumnsByCellContent)
1186
- ) {
1187
- throw new Error(
1188
- `[Angular-Slickgrid] 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").`
1189
- );
1190
- }
1191
-
1192
- // auto-resize grid on browser resize
1193
- if (options.gridHeight || options.gridWidth) {
1194
- this.resizerService.resizeGrid(0, { height: options.gridHeight, width: options.gridWidth });
1195
- } else {
1196
- this.resizerService.resizeGrid();
1197
- }
1198
-
1199
- // expand/autofit columns on first page load
1200
- if (
1201
- grid &&
1202
- options?.enableAutoResize &&
1203
- options.autoFitColumnsOnFirstLoad &&
1204
- options.enableAutoSizeColumns &&
1205
- !this._isAutosizeColsCalled
1206
- ) {
1207
- grid.autosizeColumns();
1208
- this._isAutosizeColsCalled = true;
1209
- }
1210
- }
1211
-
1212
- protected executeAfterDataviewCreated(_grid: SlickGrid, gridOptions: GridOption) {
1213
- // if user entered some Sort "presets", we need to reflect them all in the DOM
1214
- if (gridOptions.enableSorting && Array.isArray(gridOptions.presets?.sorters)) {
1215
- // when using multi-column sort, we can have multiple but on single sort then only grab the first sort provided
1216
- const sortColumns = this.options.multiColumnSort ? gridOptions.presets.sorters : gridOptions.presets.sorters.slice(0, 1);
1217
- this.sortService.loadGridSorters(sortColumns);
1218
- }
1219
- }
1220
-
1221
- /** When data changes in the DataView, we'll refresh the metrics and/or display a warning if the dataset is empty */
1222
- protected handleOnItemCountChanged(currentPageRowItemCount: number, totalItemCount: number) {
1223
- this._currentDatasetLength = totalItemCount;
1224
- this.metrics = {
1225
- startTime: new Date(),
1226
- endTime: new Date(),
1227
- itemCount: currentPageRowItemCount,
1228
- totalItemCount,
1229
- };
1230
- // if custom footer is enabled, then we'll update its metrics
1231
- if (this.slickFooter) {
1232
- this.slickFooter.metrics = this.metrics;
1233
- }
1234
-
1235
- // when using local (in-memory) dataset, we'll display a warning message when filtered data is empty
1236
- if (this._isLocalGrid && this.options?.enableEmptyDataWarningMessage) {
1237
- this.displayEmptyDataWarning(currentPageRowItemCount === 0);
1238
- }
1239
-
1240
- // when autoResize.autoHeight is enabled, we'll want to call a resize
1241
- if (this.options.enableAutoResize && this.resizerService.isAutoHeightEnabled && currentPageRowItemCount > 0) {
1242
- this.resizerService.resizeGrid();
1243
- }
1244
- }
1245
-
1246
- protected initializePaginationService(paginationOptions: Pagination) {
1247
- if (this.options) {
1248
- this.paginationData = {
1249
- gridOptions: this.options,
1250
- paginationService: this.paginationService,
1251
- };
1252
- this.paginationService.totalItems = this.totalItems;
1253
- this.paginationService.init(this.slickGrid, paginationOptions, this.backendServiceApi);
1254
- this.subscriptions.push(
1255
- this._eventPubSubService.subscribe('onPaginationChanged', (paginationChanges: PaginationMetadata) => {
1256
- this.paginationChanged(paginationChanges);
1257
- }),
1258
- this._eventPubSubService.subscribe('onPaginationVisibilityChanged', (visibility: { visible: boolean }) => {
1259
- this.showPagination = visibility?.visible ?? false;
1260
- if (this.options?.backendServiceApi) {
1261
- this.backendUtilityService?.refreshBackendDataset(this.options);
1262
- }
1263
- this.renderPagination(this.showPagination);
1264
- })
1265
- );
1266
- // also initialize (render) the pagination component
1267
- this.renderPagination();
1268
- this._isPaginationInitialized = true;
1269
- }
1270
- this.cd.detectChanges();
1271
- }
1272
-
1273
- /** Load the Editor Collection asynchronously and replace the "collection" property when Observable resolves */
1274
- protected loadEditorCollectionAsync(column: Column) {
1275
- if (column?.editor) {
1276
- const collectionAsync = column.editor.collectionAsync;
1277
- column.editor.disabled = true; // disable the Editor DOM element, we'll re-enable it after receiving the collection with "updateEditorCollection()"
1278
-
1279
- if (collectionAsync instanceof Observable) {
1280
- this.subscriptions.push(collectionAsync.subscribe((resolvedCollection) => this.updateEditorCollection(column, resolvedCollection)));
1281
- } else if (collectionAsync instanceof Promise) {
1282
- // wait for the "collectionAsync", once resolved we will save it into the "collection"
1283
- // the collectionAsync can be of 3 types HttpClient, HttpFetch or a Promise
1284
- collectionAsync.then((response: any | any[]) => {
1285
- if (Array.isArray(response)) {
1286
- this.updateEditorCollection(column, response); // from Promise
1287
- }
1288
- });
1289
- }
1290
- }
1291
- }
1292
-
1293
- protected insertDynamicPresetColumns(columnId: string, gridPresetColumns: Column[]) {
1294
- if (this._columnDefinitions) {
1295
- const columnPosition = this._columnDefinitions.findIndex((c) => c.id === columnId);
1296
- if (columnPosition >= 0) {
1297
- const dynColumn = this._columnDefinitions[columnPosition];
1298
- if (dynColumn?.id === columnId && !gridPresetColumns.some((c) => c.id === columnId)) {
1299
- columnPosition > 0 ? gridPresetColumns.splice(columnPosition, 0, dynColumn) : gridPresetColumns.unshift(dynColumn);
1300
- }
1301
- }
1302
- }
1303
- }
1304
-
1305
- /** Load any possible Columns Grid Presets */
1306
- protected loadColumnPresetsWhenDatasetInitialized() {
1307
- // if user entered some Columns "presets", we need to reflect them all in the grid
1308
- if (Array.isArray(this.options.presets?.columns) && this.options.presets.columns.length > 0) {
1309
- const gridPresetColumns: Column[] = this.gridStateService.getAssociatedGridColumns(this.slickGrid, this.options.presets.columns);
1310
- if (Array.isArray(gridPresetColumns) && gridPresetColumns.length > 0 && Array.isArray(this._columnDefinitions)) {
1311
- // make sure that the dynamic columns are included in presets (1.Row Move, 2. Row Selection, 3. Row Detail)
1312
- if (this.options.enableRowMoveManager) {
1313
- const rmmColId = this.options?.rowMoveManager?.columnId ?? '_move';
1314
- this.insertDynamicPresetColumns(rmmColId, gridPresetColumns);
1315
- }
1316
- if (this.options.enableCheckboxSelector) {
1317
- const chkColId = this.options?.checkboxSelector?.columnId ?? '_checkbox_selector';
1318
- this.insertDynamicPresetColumns(chkColId, gridPresetColumns);
1319
- }
1320
- if (this.options.enableRowDetailView) {
1321
- const rdvColId = this.options?.rowDetailView?.columnId ?? '_detail_selector';
1322
- this.insertDynamicPresetColumns(rdvColId, gridPresetColumns);
1323
- }
1324
-
1325
- // keep copy the original optional `width` properties optionally provided by the user.
1326
- // We will use this when doing a resize by cell content, if user provided a `width` it won't override it.
1327
- gridPresetColumns.forEach((col) => (col.originalWidth = col.width));
1328
-
1329
- // finally set the new presets columns (including checkbox selector if need be)
1330
- this.slickGrid.setColumns(gridPresetColumns);
1331
- this.sharedService.visibleColumns = gridPresetColumns;
1332
- }
1333
- }
1334
- }
1335
-
1336
- /** Load any possible Filters Grid Presets */
1337
- protected loadFilterPresetsWhenDatasetInitialized() {
1338
- if (this.options && !this.customDataView) {
1339
- // if user entered some Filter "presets", we need to reflect them all in the DOM
1340
- // also note that a presets of Tree Data Toggling will also call this method because Tree Data toggling does work with data filtering
1341
- // (collapsing a parent will basically use Filter for hidding (aka collapsing) away the child underneat it)
1342
- if (Array.isArray(this.options.presets?.filters) || Array.isArray(this.options.presets?.treeData?.toggledItems)) {
1343
- this.filterService.populateColumnFilterSearchTermPresets(this.options.presets?.filters || []);
1344
- }
1345
- }
1346
- }
1347
-
1348
- /**
1349
- * local grid, check if we need to show the Pagination
1350
- * if so then also check if there's any presets and finally initialize the PaginationService
1351
- * 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
1352
- */
1353
- protected loadLocalGridPagination(dataset?: any[]) {
1354
- if (this.options && this._paginationOptions) {
1355
- this.totalItems = Array.isArray(dataset) ? dataset.length : 0;
1356
- if (this._paginationOptions && this.dataView?.getPagingInfo) {
1357
- const slickPagingInfo = this.dataView.getPagingInfo();
1358
- if (slickPagingInfo && 'totalRows' in slickPagingInfo && this._paginationOptions.totalItems !== slickPagingInfo.totalRows) {
1359
- this.totalItems = slickPagingInfo.totalRows || 0;
1360
- }
1361
- }
1362
- this._paginationOptions.totalItems = this.totalItems;
1363
- const paginationOptions = this.setPaginationOptionsWhenPresetDefined(this.options, this._paginationOptions);
1364
- this.initializePaginationService(paginationOptions);
1365
- }
1366
- }
1367
-
1368
- /** Load any Row Selections into the DataView that were presets by the user */
1369
- protected loadRowSelectionPresetWhenExists() {
1370
- // if user entered some Row Selections "presets"
1371
- const presets = this.options?.presets;
1372
- const enableRowSelection = this.options && (this.options.enableCheckboxSelector || this.options.enableRowSelection);
1373
- if (
1374
- enableRowSelection &&
1375
- this.slickGrid?.getSelectionModel() &&
1376
- presets?.rowSelection &&
1377
- (Array.isArray(presets.rowSelection.gridRowIndexes) || Array.isArray(presets.rowSelection.dataContextIds))
1378
- ) {
1379
- let dataContextIds = presets.rowSelection.dataContextIds;
1380
- let gridRowIndexes = presets.rowSelection.gridRowIndexes;
1381
-
1382
- // maps the IDs to the Grid Rows and vice versa, the "dataContextIds" has precedence over the other
1383
- if (Array.isArray(dataContextIds) && dataContextIds.length > 0) {
1384
- gridRowIndexes = this.dataView.mapIdsToRows(dataContextIds) || [];
1385
- } else if (Array.isArray(gridRowIndexes) && gridRowIndexes.length > 0) {
1386
- dataContextIds = this.dataView.mapRowsToIds(gridRowIndexes) || [];
1387
- }
1388
-
1389
- // apply row selection when defined as grid presets
1390
- if (this.slickGrid && Array.isArray(gridRowIndexes)) {
1391
- this.slickGrid.setSelectedRows(gridRowIndexes);
1392
- this.dataView!.setSelectedIds(dataContextIds || [], {
1393
- isRowBeingAdded: true,
1394
- shouldTriggerEvent: false, // do not trigger when presetting the grid
1395
- applyRowSelectionToGrid: true,
1396
- });
1397
- }
1398
- }
1399
- }
1400
-
1401
- hasBackendInfiniteScroll(gridOptions?: GridOption): boolean {
1402
- return !!(gridOptions || this.options).backendServiceApi?.service.options?.infiniteScroll;
1403
- }
1404
-
1405
- protected mergeGridOptions(gridOptions: GridOption): GridOption {
1406
- gridOptions.gridId = this.gridId;
1407
- gridOptions.gridContainerId = `slickGridContainer-${this.gridId}`;
1408
-
1409
- // use extend to deep merge & copy to avoid immutable properties being changed in GlobalGridOptions after a route change
1410
- const options = extend(true, {}, GlobalGridOptions, this.forRootConfig, gridOptions) as GridOption;
1411
-
1412
- // if we have a backendServiceApi and the enablePagination is undefined, we'll assume that we do want to see it, else get that defined value
1413
- if (!this.hasBackendInfiniteScroll(gridOptions)) {
1414
- gridOptions.enablePagination = !!(gridOptions.backendServiceApi && gridOptions.enablePagination === undefined
1415
- ? true
1416
- : gridOptions.enablePagination);
1417
- }
1418
-
1419
- // using copy extend to do a deep clone has an unwanted side on objects and pageSizes but ES6 spread has other worst side effects
1420
- // so we will just overwrite the pageSizes when needed, this is the only one causing issues so far.
1421
- // On a deep extend, Object and Array are extended, but object wrappers on primitive types such as String, Boolean, and Number are not.
1422
- if (
1423
- options?.pagination &&
1424
- (gridOptions.enablePagination || gridOptions.backendServiceApi) &&
1425
- (this.forRootConfig.pagination || gridOptions.pagination)
1426
- ) {
1427
- options.pagination.pageSize =
1428
- gridOptions.pagination?.pageSize ?? this.forRootConfig.pagination?.pageSize ?? GlobalGridOptions.pagination!.pageSize;
1429
- options.pagination.pageSizes =
1430
- gridOptions.pagination?.pageSizes ?? this.forRootConfig.pagination?.pageSizes ?? GlobalGridOptions.pagination!.pageSizes;
1431
- }
1432
-
1433
- // also make sure to show the header row if user have enabled filtering
1434
- this._hideHeaderRowAfterPageLoad = options.showHeaderRow === false;
1435
- if (options.enableFiltering && !options.showHeaderRow) {
1436
- options.showHeaderRow = options.enableFiltering;
1437
- }
1438
-
1439
- // when we use Pagination on Local Grid, it doesn't seem to work without enableFiltering
1440
- // so we'll enable the filtering but we'll keep the header row hidden
1441
- if (options && !options.enableFiltering && options.enablePagination && this._isLocalGrid) {
1442
- options.enableFiltering = true;
1443
- options.showHeaderRow = false;
1444
- this._hideHeaderRowAfterPageLoad = true;
1445
- if (this.sharedService) {
1446
- this.sharedService.hideHeaderRowAfterPageLoad = true;
1447
- }
1448
- }
1449
-
1450
- return options;
1451
- }
1452
-
1453
- /** Add a register of a new external resource, user could also optional dispose all previous resources before pushing any new resources to the resources array list. */
1454
- registerExternalResources(resources: ExternalResource[], disposePreviousResources = false) {
1455
- if (disposePreviousResources) {
1456
- this.disposeExternalResources();
1457
- }
1458
- resources.forEach((res) => this._registeredResources.push(res));
1459
- this.initializeExternalResources(resources);
1460
- }
1461
-
1462
- resetExternalResources() {
1463
- this._registeredResources = [];
1464
- }
1465
-
1466
- /** Pre-Register any Resource that don't require SlickGrid to be instantiated (for example RxJS Resource & RowDetail) */
1467
- protected preRegisterResources() {
1468
- this._registeredResources = this.options?.externalResources || [];
1469
-
1470
- // Angular-Slickgrid requires RxJS, so we'll register it as the first resource
1471
- this.registerRxJsResource(new RxJsResource() as RxJsFacade);
1472
-
1473
- if (this.options.enableRowDetailView) {
1474
- this.slickRowDetailView = new SlickRowDetailView(
1475
- this.angularUtilService,
1476
- this.appRef,
1477
- this._eventPubSubService,
1478
- this.elm.nativeElement,
1479
- this.rxjs
1480
- );
1481
- this.slickRowDetailView.create(this.columns, this.options);
1482
- this.extensionService.addExtensionToList(ExtensionName.rowDetailView, {
1483
- name: ExtensionName.rowDetailView,
1484
- instance: this.slickRowDetailView,
1485
- });
1486
- }
1487
- }
1488
-
1489
- protected initializeExternalResources(resources: ExternalResource[]) {
1490
- if (Array.isArray(resources)) {
1491
- for (const resource of resources) {
1492
- if (this.slickGrid && typeof resource.init === 'function') {
1493
- resource.init(this.slickGrid, this.containerService);
1494
- }
1495
- }
1496
- }
1497
- }
1498
-
1499
- protected registerResources() {
1500
- // at this point, we consider all the registered services as external services, anything else registered afterward aren't external
1501
- if (Array.isArray(this._registeredResources)) {
1502
- this.sharedService.externalRegisteredResources = this._registeredResources;
1503
- }
1504
-
1505
- // push all other Services that we want to be registered
1506
- this._registeredResources.push(this.gridService, this.gridStateService);
1507
-
1508
- // when using Grouping/DraggableGrouping/Colspan register its Service
1509
- if (
1510
- (this.options.createPreHeaderPanel && this.options.createTopHeaderPanel) ||
1511
- (this.options.createPreHeaderPanel && !this.options.enableDraggableGrouping)
1512
- ) {
1513
- this._registeredResources.push(this.headerGroupingService);
1514
- }
1515
-
1516
- // when using Tree Data View, register its Service
1517
- if (this.options.enableTreeData) {
1518
- this._registeredResources.push(this.treeDataService);
1519
- }
1520
-
1521
- // when user enables translation, we need to translate Headers on first pass & subsequently in the bindDifferentHooks
1522
- if (this.options.enableTranslate) {
1523
- this.extensionService.translateColumnHeaders();
1524
- }
1525
-
1526
- // also initialize (render) the empty warning component
1527
- this.slickEmptyWarning = new SlickEmptyWarningComponent();
1528
- this._registeredResources.push(this.slickEmptyWarning);
1529
-
1530
- // bind & initialize all Components/Services that were tagged as enabled
1531
- // register all services by executing their init method and providing them with the Grid object
1532
- this.initializeExternalResources(this._registeredResources);
1533
-
1534
- // initialize RowDetail separately since we already added it to the ExtensionList via `addExtensionToList()` but not in external resources,
1535
- // because we don't want to dispose the extension/resource more than once (because externalResources/extensionList are both looping through their list to dispose of them)
1536
- if (this.options.enableRowDetailView && this.slickRowDetailView) {
1537
- this.slickRowDetailView.init(this.slickGrid);
1538
- }
1539
- }
1540
-
1541
- /** Register the RxJS Resource in all necessary services which uses */
1542
- protected registerRxJsResource(resource: RxJsFacade) {
1543
- this.rxjs = resource;
1544
- this.backendUtilityService.addRxJsResource(this.rxjs);
1545
- this.filterFactory.addRxJsResource(this.rxjs);
1546
- this.filterService.addRxJsResource(this.rxjs);
1547
- this.sortService.addRxJsResource(this.rxjs);
1548
- this.paginationService.addRxJsResource(this.rxjs);
1549
- this.containerService.registerInstance('RxJsResource', this.rxjs);
1550
- }
1551
-
1552
- /**
1553
- * Render (or dispose) the Pagination Component, user can optionally provide False (to not show it) which will in term dispose of the Pagination,
1554
- * 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)
1555
- * @param {Boolean} showPagination - show (new render) or not (dispose) the Pagination
1556
- * @param {Boolean} shouldDisposePaginationService - when disposing the Pagination, do we also want to dispose of the Pagination Service? (defaults to True)
1557
- */
1558
- protected renderPagination(showPagination = true) {
1559
- if (this.slickGrid && this.options?.enablePagination && !this._isPaginationInitialized && showPagination) {
1560
- if (this.options.customPaginationComponent) {
1561
- const paginationComp = this.angularUtilService.createAngularComponent(this.options.customPaginationComponent!);
1562
- this.slickPagination = paginationComp.componentRef.instance;
1563
- } else {
1564
- this.slickPagination = new SlickPaginationComponent();
1565
- }
1566
-
1567
- if (this.slickPagination) {
1568
- this.slickPagination.init(this.slickGrid, this.paginationService, this._eventPubSubService, this.translaterService);
1569
- this.slickPagination.renderPagination(this.gridContainerElement as HTMLElement);
1570
- this._isPaginationInitialized = true;
1571
- }
1572
- } else if (!showPagination) {
1573
- this.slickPagination?.dispose();
1574
- this._isPaginationInitialized = false;
1575
- }
1576
- }
1577
-
1578
- /**
1579
- * Takes a flat dataset with parent/child relationship, sort it (via its tree structure) and return the sorted flat array
1580
- * @param {Array<Object>} flatDatasetInput - flat dataset input
1581
- * @param {Boolean} forceGridRefresh - optionally force a full grid refresh
1582
- * @returns {Array<Object>} sort flat parent/child dataset
1583
- */
1584
- protected sortTreeDataset<T>(flatDatasetInput: T[], forceGridRefresh = false): T[] {
1585
- const prevDatasetLn = this._currentDatasetLength;
1586
- let sortedDatasetResult;
1587
- let flatDatasetOutput: any[] = [];
1588
-
1589
- // if the hierarchical dataset was already initialized then no need to re-convert it, we can use it directly from the shared service ref
1590
- if (this._isDatasetHierarchicalInitialized && this.datasetHierarchical) {
1591
- sortedDatasetResult = this.treeDataService.sortHierarchicalDataset(this.datasetHierarchical);
1592
- flatDatasetOutput = sortedDatasetResult.flat;
1593
- } else if (Array.isArray(flatDatasetInput) && flatDatasetInput.length > 0) {
1594
- // we need to first convert the flat dataset to a hierarchical dataset and then sort it
1595
- // we'll also add props, by mutation, required by the TreeDataService on the flat array like `__hasChildren`, `parentId` and anything else to work properly
1596
- sortedDatasetResult = this.treeDataService.convertFlatParentChildToTreeDatasetAndSort(
1597
- flatDatasetInput,
1598
- this._columnDefinitions,
1599
- this.options
1600
- );
1601
- this.sharedService.hierarchicalDataset = sortedDatasetResult.hierarchical;
1602
- flatDatasetOutput = sortedDatasetResult.flat;
1603
- }
1604
-
1605
- // if we add/remove item(s) from the dataset, we need to also refresh our tree data filters
1606
- if (flatDatasetInput.length > 0 && (forceGridRefresh || flatDatasetInput.length !== prevDatasetLn)) {
1607
- this.filterService.refreshTreeDataFilters(flatDatasetOutput);
1608
- }
1609
-
1610
- return flatDatasetOutput;
1611
- }
1612
-
1613
- /** Prepare and load all SlickGrid editors, if an async editor is found then we'll also execute it. */
1614
- protected loadSlickGridEditors(columns: Column<TData>[]): Column<TData>[] {
1615
- if (columns.some((col) => `${col.id}`.includes('.'))) {
1616
- console.error(
1617
- '[Angular-Slickgrid] 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".'
1618
- );
1619
- }
1620
-
1621
- return columns.map((column: Column | any) => {
1622
- // on every Editor that have a "collectionAsync", resolve the data and assign it to the "collection" property
1623
- if (column?.editor?.collectionAsync) {
1624
- this.loadEditorCollectionAsync(column);
1625
- }
1626
- return { ...column, editorClass: column.editor?.model };
1627
- });
1628
- }
1629
-
1630
- protected suggestDateParsingWhenHelpful() {
1631
- if (
1632
- this.dataView?.getItemCount() > WARN_NO_PREPARSE_DATE_SIZE &&
1633
- !this.options.silenceWarnings &&
1634
- !this.options.preParseDateColumns &&
1635
- this.slickGrid.getColumns().some((c) => isColumnDateType(c.type))
1636
- ) {
1637
- console.warn(
1638
- '[Slickgrid-Universal] For getting better perf, we suggest you enable the `preParseDateColumns` grid option, ' +
1639
- 'for more info visit => https://ghiscoding.gitbook.io/angular-slickgrid/column-functionalities/sorting#pre-parse-date-columns-for-better-perf'
1640
- );
1641
- }
1642
- }
1643
-
1644
- /**
1645
- * When the Editor(s) has a "editor.collection" property, we'll load the async collection.
1646
- * Since this is called after the async call resolves, the pointer will not be the same as the "column" argument passed.
1647
- */
1648
- protected updateEditorCollection<T = any>(column: Column<T>, newCollection: T[]) {
1649
- if (this.slickGrid && column.editor) {
1650
- column.editor.collection = newCollection;
1651
- column.editor.disabled = false;
1652
-
1653
- // get current Editor, remove it from the DOM then re-enable it and re-render it with the new collection.
1654
- const currentEditor = this.slickGrid.getCellEditor() as AutocompleterEditor | SelectEditor;
1655
- if (currentEditor?.disable && currentEditor?.renderDomElement) {
1656
- currentEditor.destroy();
1657
- currentEditor.disable(false);
1658
- currentEditor.renderDomElement(newCollection);
1659
- }
1660
- }
1661
- }
1662
- }