angular-slickgrid 4.1.2 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/.browserslistrc +12 -0
  2. package/.codecov.yml +17 -0
  3. package/.editorconfig +18 -0
  4. package/.eslintrc.json +50 -0
  5. package/.github/CODE_OF_CONDUCT.md +76 -0
  6. package/.github/FUNDING.yml +8 -0
  7. package/.github/ISSUE_TEMPLATE/bug_report.yml +54 -0
  8. package/.github/ISSUE_TEMPLATE/config.yml +5 -0
  9. package/.github/ISSUE_TEMPLATE/feature_request.yml +44 -0
  10. package/.github/renovate.json5 +26 -0
  11. package/.github/stale.yml +7 -0
  12. package/.github/workflows/main.yml +83 -0
  13. package/.vscode/extensions.json +9 -0
  14. package/.vscode/launch.json +72 -0
  15. package/.vscode/settings.json +7 -0
  16. package/.vscode/tasks.json +77 -0
  17. package/CHANGELOG.md +1172 -0
  18. package/LICENSE +20 -20
  19. package/README.md +9 -7
  20. package/angular.json +148 -0
  21. package/dist/LICENSE +20 -0
  22. package/dist/README.md +182 -0
  23. package/{angular-slickgrid.d.ts → dist/angular-slickgrid.d.ts} +0 -0
  24. package/{app → dist/app}/modules/angular-slickgrid/components/angular-slickgrid.component.d.ts +0 -0
  25. package/{app → dist/app}/modules/angular-slickgrid/constants.d.ts +0 -0
  26. package/{app → dist/app}/modules/angular-slickgrid/extensions/index.d.ts +0 -0
  27. package/{app → dist/app}/modules/angular-slickgrid/extensions/slickRowDetailView.d.ts +0 -0
  28. package/{app → dist/app}/modules/angular-slickgrid/global-grid-options.d.ts +0 -0
  29. package/{app → dist/app}/modules/angular-slickgrid/index.d.ts +0 -0
  30. package/{app → dist/app}/modules/angular-slickgrid/models/angularComponentOutput.interface.d.ts +0 -0
  31. package/{app → dist/app}/modules/angular-slickgrid/models/angularGridInstance.interface.d.ts +0 -0
  32. package/{app → dist/app}/modules/angular-slickgrid/models/externalTestingDependencies.interface.d.ts +0 -0
  33. package/{app → dist/app}/modules/angular-slickgrid/models/gridOption.interface.d.ts +0 -0
  34. package/{app → dist/app}/modules/angular-slickgrid/models/index.d.ts +0 -0
  35. package/{app → dist/app}/modules/angular-slickgrid/models/rowDetailView.interface.d.ts +0 -0
  36. package/{app → dist/app}/modules/angular-slickgrid/models/slickGrid.interface.d.ts +0 -0
  37. package/{app → dist/app}/modules/angular-slickgrid/modules/angular-slickgrid.module.d.ts +0 -0
  38. package/{app → dist/app}/modules/angular-slickgrid/services/angularUtil.service.d.ts +0 -0
  39. package/{app → dist/app}/modules/angular-slickgrid/services/bsDropdown.service.d.ts +0 -0
  40. package/{app → dist/app}/modules/angular-slickgrid/services/container.service.d.ts +0 -0
  41. package/{app → dist/app}/modules/angular-slickgrid/services/index.d.ts +0 -0
  42. package/{app → dist/app}/modules/angular-slickgrid/services/translater.service.d.ts +0 -0
  43. package/{app → dist/app}/modules/angular-slickgrid/services/utilities.d.ts +0 -0
  44. package/{app → dist/app}/modules/angular-slickgrid/slickgrid-config.d.ts +0 -0
  45. package/{esm2020 → dist/esm2020}/angular-slickgrid.mjs +0 -0
  46. package/dist/esm2020/app/modules/angular-slickgrid/components/angular-slickgrid.component.mjs +1171 -0
  47. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/constants.mjs +1 -1
  48. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/extensions/index.mjs +1 -1
  49. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/extensions/slickRowDetailView.mjs +2 -2
  50. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/global-grid-options.mjs +1 -1
  51. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/index.mjs +1 -1
  52. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/models/angularComponentOutput.interface.mjs +1 -1
  53. package/dist/esm2020/app/modules/angular-slickgrid/models/angularGridInstance.interface.mjs +2 -0
  54. package/dist/esm2020/app/modules/angular-slickgrid/models/externalTestingDependencies.interface.mjs +2 -0
  55. package/dist/esm2020/app/modules/angular-slickgrid/models/gridOption.interface.mjs +2 -0
  56. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/models/index.mjs +1 -1
  57. package/dist/esm2020/app/modules/angular-slickgrid/models/rowDetailView.interface.mjs +2 -0
  58. package/dist/esm2020/app/modules/angular-slickgrid/models/slickGrid.interface.mjs +2 -0
  59. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/modules/angular-slickgrid.module.mjs +5 -5
  60. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/services/angularUtil.service.mjs +4 -4
  61. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/services/bsDropdown.service.mjs +4 -4
  62. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/services/container.service.mjs +4 -4
  63. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/services/index.mjs +1 -1
  64. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/services/translater.service.mjs +4 -4
  65. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/services/utilities.mjs +1 -1
  66. package/{esm2020 → dist/esm2020}/app/modules/angular-slickgrid/slickgrid-config.mjs +1 -1
  67. package/{esm2020 → dist/esm2020}/public_api.mjs +1 -1
  68. package/{fesm2015 → dist/fesm2015}/angular-slickgrid.mjs +25 -22
  69. package/dist/fesm2015/angular-slickgrid.mjs.map +1 -0
  70. package/{fesm2020 → dist/fesm2020}/angular-slickgrid.mjs +25 -22
  71. package/dist/fesm2020/angular-slickgrid.mjs.map +1 -0
  72. package/{i18n → dist/i18n}/en.json +89 -89
  73. package/{i18n → dist/i18n}/fr.json +90 -90
  74. package/dist/package.json +79 -0
  75. package/{public_api.d.ts → dist/public_api.d.ts} +0 -0
  76. package/global.d.ts +1 -0
  77. package/ngcc.config.js +13 -0
  78. package/package.json +124 -37
  79. package/screenshots/column-picker.png +0 -0
  80. package/screenshots/composite-editor.png +0 -0
  81. package/screenshots/draggable-grouping.png +0 -0
  82. package/screenshots/editors.png +0 -0
  83. package/screenshots/export-to-file.png +0 -0
  84. package/screenshots/filter_and_sort.png +0 -0
  85. package/screenshots/formatters.png +0 -0
  86. package/screenshots/frozen.png +0 -0
  87. package/screenshots/multipleSelectFilter.png +0 -0
  88. package/screenshots/pagination.png +0 -0
  89. package/screenshots/selectFilter.png +0 -0
  90. package/screenshots/singleFilter.png +0 -0
  91. package/src/app/app-routing.module.ts +83 -0
  92. package/src/app/app.component.html +160 -0
  93. package/src/app/app.component.scss +65 -0
  94. package/src/app/app.component.ts +10 -0
  95. package/src/app/app.module.ts +175 -0
  96. package/src/app/examples/custom-angularComponentEditor.ts +184 -0
  97. package/src/app/examples/custom-angularComponentFilter.ts +126 -0
  98. package/src/app/examples/custom-inputEditor.ts +124 -0
  99. package/src/app/examples/custom-inputFilter.ts +142 -0
  100. package/src/app/examples/custom-titleFormatter.component.ts +8 -0
  101. package/src/app/examples/editor-ng-select.component.ts +37 -0
  102. package/src/app/examples/filter-ng-select.component.ts +32 -0
  103. package/src/app/examples/grid-additem.component.html +48 -0
  104. package/src/app/examples/grid-additem.component.ts +272 -0
  105. package/src/app/examples/grid-angular.component.html +79 -0
  106. package/src/app/examples/grid-angular.component.scss +28 -0
  107. package/src/app/examples/grid-angular.component.ts +370 -0
  108. package/src/app/examples/grid-autoheight.component.html +52 -0
  109. package/src/app/examples/grid-autoheight.component.ts +147 -0
  110. package/src/app/examples/grid-basic.component.html +29 -0
  111. package/src/app/examples/grid-basic.component.ts +82 -0
  112. package/src/app/examples/grid-clientside.component.html +51 -0
  113. package/src/app/examples/grid-clientside.component.ts +293 -0
  114. package/src/app/examples/grid-colspan.component.html +39 -0
  115. package/src/app/examples/grid-colspan.component.scss +11 -0
  116. package/src/app/examples/grid-colspan.component.ts +155 -0
  117. package/src/app/examples/grid-composite-editor.component.html +79 -0
  118. package/src/app/examples/grid-composite-editor.component.scss +19 -0
  119. package/src/app/examples/grid-composite-editor.component.ts +948 -0
  120. package/src/app/examples/grid-contextmenu.component.html +62 -0
  121. package/src/app/examples/grid-contextmenu.component.scss +44 -0
  122. package/src/app/examples/grid-contextmenu.component.ts +473 -0
  123. package/src/app/examples/grid-custom-tooltip.component.html +25 -0
  124. package/src/app/examples/grid-custom-tooltip.component.scss +77 -0
  125. package/src/app/examples/grid-custom-tooltip.component.ts +483 -0
  126. package/src/app/examples/grid-draggrouping.component.html +93 -0
  127. package/src/app/examples/grid-draggrouping.component.ts +397 -0
  128. package/src/app/examples/grid-editor.component.html +88 -0
  129. package/src/app/examples/grid-editor.component.ts +699 -0
  130. package/src/app/examples/grid-formatter.component.html +26 -0
  131. package/src/app/examples/grid-formatter.component.ts +162 -0
  132. package/src/app/examples/grid-frozen.component.html +65 -0
  133. package/src/app/examples/grid-frozen.component.scss +11 -0
  134. package/src/app/examples/grid-frozen.component.ts +303 -0
  135. package/src/app/examples/grid-graphql-nopage.component.html +33 -0
  136. package/src/app/examples/grid-graphql-nopage.component.scss +9 -0
  137. package/src/app/examples/grid-graphql-nopage.component.ts +242 -0
  138. package/src/app/examples/grid-graphql.component.html +87 -0
  139. package/src/app/examples/grid-graphql.component.ts +304 -0
  140. package/src/app/examples/grid-grouping.component.html +80 -0
  141. package/src/app/examples/grid-grouping.component.ts +313 -0
  142. package/src/app/examples/grid-headerbutton.component.html +31 -0
  143. package/src/app/examples/grid-headerbutton.component.scss +10 -0
  144. package/src/app/examples/grid-headerbutton.component.ts +233 -0
  145. package/src/app/examples/grid-headermenu.component.html +31 -0
  146. package/src/app/examples/grid-headermenu.component.scss +25 -0
  147. package/src/app/examples/grid-headermenu.component.ts +159 -0
  148. package/src/app/examples/grid-localization.component.html +54 -0
  149. package/src/app/examples/grid-localization.component.ts +293 -0
  150. package/src/app/examples/grid-menu.component.html +37 -0
  151. package/src/app/examples/grid-menu.component.scss +28 -0
  152. package/src/app/examples/grid-menu.component.ts +229 -0
  153. package/src/app/examples/grid-odata.component.html +116 -0
  154. package/src/app/examples/grid-odata.component.ts +441 -0
  155. package/src/app/examples/grid-range.component.html +74 -0
  156. package/src/app/examples/grid-range.component.ts +291 -0
  157. package/src/app/examples/grid-remote.component.html +37 -0
  158. package/src/app/examples/grid-remote.component.ts +153 -0
  159. package/src/app/examples/grid-resize-by-content.component.html +62 -0
  160. package/src/app/examples/grid-resize-by-content.component.scss +19 -0
  161. package/src/app/examples/grid-resize-by-content.component.ts +780 -0
  162. package/src/app/examples/grid-rowdetail.component.html +35 -0
  163. package/src/app/examples/grid-rowdetail.component.ts +205 -0
  164. package/src/app/examples/grid-rowmove.component.html +49 -0
  165. package/src/app/examples/grid-rowmove.component.ts +234 -0
  166. package/src/app/examples/grid-rowselection.component.html +76 -0
  167. package/src/app/examples/grid-rowselection.component.ts +267 -0
  168. package/src/app/examples/grid-state.component.html +36 -0
  169. package/src/app/examples/grid-state.component.ts +259 -0
  170. package/src/app/examples/grid-tabs.component.html +35 -0
  171. package/src/app/examples/grid-tabs.component.ts +115 -0
  172. package/src/app/examples/grid-trading.component.html +58 -0
  173. package/src/app/examples/grid-trading.component.scss +49 -0
  174. package/src/app/examples/grid-trading.component.ts +319 -0
  175. package/src/app/examples/grid-tree-data-hierarchical.component.html +79 -0
  176. package/src/app/examples/grid-tree-data-hierarchical.component.scss +47 -0
  177. package/src/app/examples/grid-tree-data-hierarchical.component.ts +311 -0
  178. package/src/app/examples/grid-tree-data-parent-child.component.html +108 -0
  179. package/src/app/examples/grid-tree-data-parent-child.component.scss +10 -0
  180. package/src/app/examples/grid-tree-data-parent-child.component.ts +351 -0
  181. package/src/app/examples/home.component.html +41 -0
  182. package/src/app/examples/home.component.ts +9 -0
  183. package/src/app/examples/rowdetail-preload.component.ts +10 -0
  184. package/src/app/examples/rowdetail-view.component.html +36 -0
  185. package/src/app/examples/rowdetail-view.component.ts +54 -0
  186. package/src/app/examples/swt-common-grid-pagination.component.ts +156 -0
  187. package/src/app/examples/swt-common-grid-test.component.html +30 -0
  188. package/src/app/examples/swt-common-grid-test.component.ts +219 -0
  189. package/src/app/examples/swt-common-grid.component.ts +436 -0
  190. package/src/app/examples/swt-logger.service.ts +165 -0
  191. package/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.html +4 -0
  192. package/src/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts +1395 -0
  193. package/src/app/modules/angular-slickgrid/constants.ts +97 -0
  194. package/src/app/modules/angular-slickgrid/extensions/index.ts +1 -0
  195. package/src/app/modules/angular-slickgrid/extensions/slickRowDetailView.ts +375 -0
  196. package/src/app/modules/angular-slickgrid/global-grid-options.ts +245 -0
  197. package/src/app/modules/angular-slickgrid/index.ts +11 -0
  198. package/src/app/modules/angular-slickgrid/models/angularComponentOutput.interface.ts +6 -0
  199. package/src/app/modules/angular-slickgrid/models/angularGridInstance.interface.ts +68 -0
  200. package/src/app/modules/angular-slickgrid/models/externalTestingDependencies.interface.ts +37 -0
  201. package/src/app/modules/angular-slickgrid/models/gridOption.interface.ts +12 -0
  202. package/src/app/modules/angular-slickgrid/models/index.ts +6 -0
  203. package/src/app/modules/angular-slickgrid/models/rowDetailView.interface.ts +33 -0
  204. package/src/app/modules/angular-slickgrid/models/slickGrid.interface.ts +7 -0
  205. package/src/app/modules/angular-slickgrid/modules/angular-slickgrid.module.ts +37 -0
  206. package/src/app/modules/angular-slickgrid/services/angularUtil.service.ts +48 -0
  207. package/src/app/modules/angular-slickgrid/services/bsDropdown.service.ts +142 -0
  208. package/src/app/modules/angular-slickgrid/services/container.service.ts +24 -0
  209. package/src/app/modules/angular-slickgrid/services/index.ts +5 -0
  210. package/src/app/modules/angular-slickgrid/services/translater.service.ts +38 -0
  211. package/src/app/modules/angular-slickgrid/services/utilities.ts +19 -0
  212. package/src/app/modules/angular-slickgrid/slickgrid-config.ts +10 -0
  213. package/src/app/slickgrid-custom-variables.scss +10 -0
  214. package/src/assets/.gitkeep +0 -0
  215. package/src/assets/data/collection_100_numbers.json +12 -0
  216. package/src/assets/data/collection_500_numbers.json +52 -0
  217. package/src/assets/data/countries.json +245 -0
  218. package/src/assets/data/country_names.json +245 -0
  219. package/src/assets/data/customers_100.json +102 -0
  220. package/src/assets/i18n/en.json +90 -0
  221. package/src/assets/i18n/fr.json +91 -0
  222. package/src/environments/environment.prod.ts +3 -0
  223. package/src/environments/environment.ts +8 -0
  224. package/src/favicon.ico +0 -0
  225. package/src/index.html +18 -0
  226. package/src/main.ts +13 -0
  227. package/src/polyfills.ts +52 -0
  228. package/src/public_api.ts +1 -0
  229. package/src/styles.scss +66 -0
  230. package/src/typings.d.ts +10 -0
  231. package/tsconfig.app.json +25 -0
  232. package/tsconfig.json +40 -0
  233. package/tsconfig.spec.json +23 -0
  234. package/docs/assets/lib/multiple-select/README.md +0 -17
  235. package/esm2020/app/modules/angular-slickgrid/components/angular-slickgrid.component.mjs +0 -1168
  236. package/esm2020/app/modules/angular-slickgrid/models/angularGridInstance.interface.mjs +0 -2
  237. package/esm2020/app/modules/angular-slickgrid/models/externalTestingDependencies.interface.mjs +0 -2
  238. package/esm2020/app/modules/angular-slickgrid/models/gridOption.interface.mjs +0 -2
  239. package/esm2020/app/modules/angular-slickgrid/models/rowDetailView.interface.mjs +0 -2
  240. package/esm2020/app/modules/angular-slickgrid/models/slickGrid.interface.mjs +0 -2
  241. package/fesm2015/angular-slickgrid.mjs.map +0 -1
  242. package/fesm2020/angular-slickgrid.mjs.map +0 -1
@@ -0,0 +1,351 @@
1
+ import { Component, OnInit, ViewEncapsulation } from '@angular/core';
2
+ import { ExcelExportService } from '@slickgrid-universal/excel-export';
3
+
4
+ import {
5
+ AngularGridInstance,
6
+ Column,
7
+ FieldType,
8
+ Filters,
9
+ Formatters,
10
+ GridOption,
11
+ GridStateChange,
12
+ GridStateType,
13
+ TreeToggledItem,
14
+ TreeToggleStateChange,
15
+ } from './../modules/angular-slickgrid';
16
+
17
+ const NB_ITEMS = 500;
18
+
19
+ @Component({
20
+ templateUrl: './grid-tree-data-parent-child.component.html',
21
+ styleUrls: ['grid-tree-data-parent-child.component.scss'],
22
+ encapsulation: ViewEncapsulation.None
23
+ })
24
+ export class GridTreeDataParentChildComponent implements OnInit {
25
+ title = 'Example 28: Tree Data <small> <span class="mdi mdi-file-tree mdi-27px"></span> (from a flat dataset with <code>parentId</code> references - <a href="https://github.com/ghiscoding/Angular-Slickgrid/wiki/Tree-Data-Grid" target="_blank">Wiki</a>)</small>';
26
+ subTitle = `<ul>
27
+ <li>It is assumed that your dataset will have Parent/Child references AND also Tree Level (indent) property.</li>
28
+ <ul>
29
+ <li>If you do not have the Tree Level (indent), you could call "convertParentChildArrayToHierarchicalView()" then call "convertHierarchicalViewToParentChildArray()"</li>
30
+ <li>You could also pass the result of "convertParentChildArrayToHierarchicalView()" to "dataset-hierarchical.bind" as defined in the next Hierarchical Example</li>
31
+ </ul>
32
+ <li><b>Styling - Material Theme</b></li>
33
+ <ul>
34
+ <li>The Material Theme was created with SASS and compiled in CSS (<a href="https://github.com/ghiscoding/Angular-Slickgrid/blob/master/src/app/modules/angular-slickgrid/styles/slickgrid-theme-material.scss" target="_blank">slickgrid-theme-material.scss</a>), you can override any of its SASS variables</li>
35
+ <li>We use a small subset of <a href="https://materialdesignicons.com/" target="_blank">Material Design Icons</a></li>
36
+ <li>you might need to refresh the page to clear the browser cache and see the correct theme</li>
37
+ </ul>
38
+ </ul>`;
39
+
40
+ angularGrid!: AngularGridInstance;
41
+ dataViewObj: any;
42
+ gridObj: any;
43
+ gridOptions!: GridOption;
44
+ columnDefinitions!: Column[];
45
+ dataset!: any[];
46
+ datasetHierarchical: any[] = [];
47
+ loadingClass = '';
48
+ isLargeDataset = false;
49
+ hasNoExpandCollapseChanged = true;
50
+ treeToggleItems: TreeToggledItem[] = [];
51
+
52
+ constructor() { }
53
+
54
+ ngOnInit(): void {
55
+ // define the grid options & columns and then create the grid itself
56
+ this.defineGrid();
57
+
58
+ // mock a dataset
59
+ this.dataset = this.loadData(NB_ITEMS);
60
+ }
61
+
62
+ defineGrid() {
63
+ this.columnDefinitions = [
64
+ {
65
+ id: 'title', name: 'Title', field: 'title', width: 220, cssClass: 'cell-title',
66
+ filterable: true, sortable: true, exportWithFormatter: false,
67
+ queryFieldSorter: 'id', type: FieldType.string,
68
+ formatter: Formatters.tree, exportCustomFormatter: Formatters.treeExport
69
+
70
+ },
71
+ { id: 'duration', name: 'Duration', field: 'duration', minWidth: 90, filterable: true },
72
+ {
73
+ id: 'percentComplete', name: '% Complete', field: 'percentComplete',
74
+ minWidth: 120, maxWidth: 200, exportWithFormatter: false,
75
+ sortable: true, filterable: true, filter: { model: Filters.compoundSlider, operator: '>=' },
76
+ formatter: Formatters.percentCompleteBarWithText, type: FieldType.number,
77
+ },
78
+ {
79
+ id: 'start', name: 'Start', field: 'start', minWidth: 60,
80
+ type: FieldType.dateIso, filterable: true, sortable: true,
81
+ filter: { model: Filters.compoundDate },
82
+ formatter: Formatters.dateIso,
83
+ },
84
+ {
85
+ id: 'finish', name: 'Finish', field: 'finish', minWidth: 60,
86
+ type: FieldType.dateIso, filterable: true, sortable: true,
87
+ filter: { model: Filters.compoundDate },
88
+ formatter: Formatters.dateIso,
89
+ },
90
+ {
91
+ id: 'effortDriven', name: 'Effort Driven', width: 80, minWidth: 20, maxWidth: 80, cssClass: 'cell-effort-driven', field: 'effortDriven',
92
+ exportWithFormatter: false,
93
+ formatter: Formatters.checkmark, cannotTriggerInsert: true,
94
+ filterable: true,
95
+ filter: {
96
+ collection: [{ value: '', label: '' }, { value: true, label: 'True' }, { value: false, label: 'False' }],
97
+ model: Filters.singleSelect
98
+ }
99
+ }
100
+ ];
101
+
102
+ this.gridOptions = {
103
+ autoResize: {
104
+ container: '#demo-container',
105
+ rightPadding: 10
106
+ },
107
+ enableAutoSizeColumns: true,
108
+ enableAutoResize: true,
109
+ enableExcelExport: true,
110
+ excelExportOptions: { exportWithFormatter: true, sanitizeDataExport: true },
111
+ registerExternalResources: [new ExcelExportService()],
112
+ enableFiltering: true,
113
+ showCustomFooter: true, // display some metrics in the bottom custom footer
114
+ enableTreeData: true, // you must enable this flag for the filtering & sorting to work as expected
115
+ treeDataOptions: {
116
+ columnId: 'title',
117
+ parentPropName: 'parentId',
118
+ // this is optional, you can define the tree level property name that will be used for the sorting/indentation, internally it will use "__treeLevel"
119
+ levelPropName: 'treeLevel',
120
+ indentMarginLeft: 15,
121
+ initiallyCollapsed: true,
122
+
123
+ // you can optionally sort by a different column and/or sort direction
124
+ // this is the recommend approach, unless you are 100% that your original array is already sorted (in most cases it's not)
125
+ initialSort: {
126
+ columnId: 'title',
127
+ direction: 'ASC'
128
+ },
129
+ // we can also add a custom Formatter just for the title text portion
130
+ titleFormatter: (_row, _cell, value, _def, dataContext) => {
131
+ let prefix = '';
132
+ if (dataContext.treeLevel > 0) {
133
+ prefix = `<span class="mdi mdi-subdirectory-arrow-right mdi-v-align-sub color-se-secondary"></span>`;
134
+ }
135
+ return `${prefix}<span class="bold">${value}</span> <span style="font-size:11px; margin-left: 15px;">(parentId: ${dataContext.parentId})</span>`;
136
+ },
137
+ },
138
+ multiColumnSort: false, // multi-column sorting is not supported with Tree Data, so you need to disable it
139
+ presets: {
140
+ filters: [{ columnId: 'percentComplete', searchTerms: [25], operator: '>=' }],
141
+ // treeData: { toggledItems: [{ itemId: 1, isCollapsed: false }] },
142
+ },
143
+
144
+ // change header/cell row height for material design theme
145
+ headerRowHeight: 45,
146
+ rowHeight: 40,
147
+ // if you're dealing with lots of data, it is recommended to use the filter debounce
148
+ filterTypingDebounce: 250,
149
+
150
+ // use Material Design SVG icons
151
+ contextMenu: {
152
+ iconCollapseAllGroupsCommand: 'mdi mdi-arrow-collapse',
153
+ iconExpandAllGroupsCommand: 'mdi mdi-arrow-expand',
154
+ iconClearGroupingCommand: 'mdi mdi-close',
155
+ iconCopyCellValueCommand: 'mdi mdi-content-copy',
156
+ iconExportCsvCommand: 'mdi mdi-download',
157
+ iconExportExcelCommand: 'mdi mdi-file-excel-outline',
158
+ iconExportTextDelimitedCommand: 'mdi mdi-download',
159
+ },
160
+ gridMenu: {
161
+ iconCssClass: 'mdi mdi-menu',
162
+ iconClearAllFiltersCommand: 'mdi mdi-filter-remove-outline',
163
+ iconClearAllSortingCommand: 'mdi mdi-swap-vertical',
164
+ iconExportCsvCommand: 'mdi mdi-download',
165
+ iconExportExcelCommand: 'mdi mdi-file-excel-outline',
166
+ iconExportTextDelimitedCommand: 'mdi mdi-download',
167
+ iconRefreshDatasetCommand: 'mdi mdi-sync',
168
+ iconToggleFilterCommand: 'mdi mdi-flip-vertical',
169
+ iconTogglePreHeaderCommand: 'mdi mdi-flip-vertical',
170
+ },
171
+ headerMenu: {
172
+ iconClearFilterCommand: 'mdi mdi mdi-filter-remove-outline',
173
+ iconClearSortCommand: 'mdi mdi-swap-vertical',
174
+ iconSortAscCommand: 'mdi mdi-sort-ascending',
175
+ iconSortDescCommand: 'mdi mdi-flip-v mdi-sort-descending',
176
+ iconColumnHideCommand: 'mdi mdi-close',
177
+ }
178
+ };
179
+ }
180
+
181
+ angularGridReady(angularGrid: AngularGridInstance) {
182
+ this.angularGrid = angularGrid;
183
+ this.gridObj = angularGrid.slickGrid;
184
+ this.dataViewObj = angularGrid.dataView;
185
+ }
186
+
187
+ /**
188
+ * A simple method to add a new item inside the first group that we find (it's random and is only for demo purposes).
189
+ * After adding the item, it will sort by parent/child recursively
190
+ */
191
+ addNewRow() {
192
+ const newId = this.dataViewObj.getItemCount();
193
+ const parentPropName = 'parentId';
194
+ const treeLevelPropName = 'treeLevel'; // if undefined in your options, the default prop name is "__treeLevel"
195
+ const newTreeLevel = 1;
196
+
197
+ // find first parent object and add the new item as a child
198
+ const childItemFound = this.dataViewObj.getItems().find((item: any) => item[treeLevelPropName] === newTreeLevel);
199
+ const parentItemFound = this.dataViewObj.getItemByIdx(childItemFound[parentPropName]);
200
+
201
+ if (childItemFound && parentItemFound) {
202
+ const newItem = {
203
+ id: newId,
204
+ parentId: parentItemFound.id,
205
+ title: `Task ${newId}`,
206
+ duration: '1 day',
207
+ percentComplete: 99,
208
+ start: new Date(),
209
+ finish: new Date(),
210
+ effortDriven: false
211
+ };
212
+
213
+ // use the Grid Service to insert the item,
214
+ // it will also internally take care of updating & resorting the hierarchical dataset
215
+ this.angularGrid.gridService.addItem(newItem);
216
+ }
217
+ }
218
+
219
+ collapseAll() {
220
+ this.angularGrid.treeDataService.toggleTreeDataCollapse(true);
221
+ }
222
+
223
+ collapseAllWithoutEvent() {
224
+ this.angularGrid.treeDataService.toggleTreeDataCollapse(true, false);
225
+ }
226
+
227
+ expandAll() {
228
+ this.angularGrid.treeDataService.toggleTreeDataCollapse(false);
229
+ }
230
+
231
+ dynamicallyChangeFilter() {
232
+ // const randomPercentage = Math.floor((Math.random() * 99));
233
+ this.angularGrid.filterService.updateFilters([{ columnId: 'percentComplete', operator: '<', searchTerms: [40] }]);
234
+ }
235
+
236
+ hideSpinner() {
237
+ setTimeout(() => this.loadingClass = '', 200); // delay the hide spinner a bit to avoid show/hide too quickly
238
+ }
239
+
240
+ showSpinner() {
241
+ if (this.isLargeDataset) {
242
+ this.loadingClass = 'mdi mdi-load mdi-spin-1s mdi-24px color-alt-success';
243
+ }
244
+ }
245
+
246
+ logHierarchicalStructure() {
247
+ console.log('exploded array', this.angularGrid.treeDataService.datasetHierarchical);
248
+ }
249
+
250
+ logFlatStructure() {
251
+ console.log('flat array', this.angularGrid.treeDataService.dataset);
252
+ }
253
+
254
+ loadData(rowCount: number) {
255
+ this.isLargeDataset = rowCount > 5000; // we'll show a spinner when it's large, else don't show show since it should be fast enough
256
+ let indent = 0;
257
+ const parents = [];
258
+ const data = [];
259
+ // prepare the data
260
+ for (let i = 0; i < rowCount; i++) {
261
+ const randomYear = 2000 + Math.floor(Math.random() * 10);
262
+ const randomMonth = Math.floor(Math.random() * 11);
263
+ const randomDay = Math.floor((Math.random() * 29));
264
+ const item: any = (data[i] = {});
265
+ let parentId;
266
+
267
+ /*
268
+ for demo & E2E testing purposes, let's make "Task 0" empty and then "Task 1" a parent that contains at least "Task 2" and "Task 3" which the latter will also contain "Task 4" (as shown below)
269
+ also for all other rows don't go over indent tree level depth of 2
270
+ Task 0
271
+ Task 1
272
+ Task 2
273
+ Task 3
274
+ Task 4
275
+ ...
276
+ */
277
+ if (i === 1 || i === 0) {
278
+ indent = 0;
279
+ parents.pop();
280
+ } if (i === 3) {
281
+ indent = 1;
282
+ } else if (i === 2 || i === 4 || (Math.random() > 0.8 && i > 0 && indent < 3 && i - 1 !== 0 && i - 1 !== 2)) { // also make sure Task 0, 2 remains empty
283
+ indent++;
284
+ parents.push(i - 1);
285
+ } else if ((Math.random() < 0.3 && indent > 0)) {
286
+ indent--;
287
+ parents.pop();
288
+ }
289
+ if (parents.length > 0) {
290
+ parentId = parents[parents.length - 1];
291
+ } else {
292
+ parentId = null;
293
+ }
294
+
295
+ item['id'] = i;
296
+ item['parentId'] = parentId;
297
+ item['title'] = `Task ${i}`;
298
+ item['duration'] = '5 days';
299
+ item['percentComplete'] = Math.round(Math.random() * 100);
300
+ item['start'] = new Date(randomYear, randomMonth, randomDay);
301
+ item['finish'] = new Date(randomYear, (randomMonth + 1), randomDay);
302
+ item['effortDriven'] = (i % 5 === 0);
303
+ }
304
+ this.dataset = data;
305
+ return data;
306
+ }
307
+
308
+ handleOnTreeFullToggleEnd(treeToggleExecution: TreeToggleStateChange) {
309
+ console.log('Tree Data changes', treeToggleExecution);
310
+ this.hideSpinner();
311
+ }
312
+
313
+ /** Whenever a parent is being toggled, we'll keep a reference of all of these changes so that we can reapply them whenever we want */
314
+ handleOnTreeItemToggled(treeToggleExecution: TreeToggleStateChange) {
315
+ this.hasNoExpandCollapseChanged = false;
316
+ this.treeToggleItems = treeToggleExecution.toggledItems as TreeToggledItem[];
317
+ console.log('Tree Data changes', treeToggleExecution);
318
+ }
319
+
320
+ handleOnGridStateChanged(gridStateChange: GridStateChange) {
321
+ this.hasNoExpandCollapseChanged = false;
322
+
323
+ if (gridStateChange?.change?.type === GridStateType.treeData) {
324
+ console.log('Tree Data gridStateChange', gridStateChange?.gridState?.treeData);
325
+ this.treeToggleItems = gridStateChange?.gridState?.treeData?.toggledItems as TreeToggledItem[];
326
+ }
327
+ }
328
+
329
+ logTreeDataToggledItems() {
330
+ console.log(this.angularGrid.treeDataService.getToggledItems());
331
+ }
332
+
333
+ dynamicallyToggledFirstParent() {
334
+ const parentPropName = 'parentId';
335
+ const treeLevelPropName = 'treeLevel'; // if undefined in your options, the default prop name is "__treeLevel"
336
+ const newTreeLevel = 1;
337
+
338
+ // find first parent object and toggle it
339
+ const childItemFound = this.dataset.find((item) => item[treeLevelPropName] === newTreeLevel);
340
+ const parentItemFound = this.angularGrid.dataView.getItemByIdx(childItemFound[parentPropName]);
341
+
342
+ if (childItemFound && parentItemFound) {
343
+ this.angularGrid.treeDataService.dynamicallyToggleItemState([{ itemId: parentItemFound.id, isCollapsed: !parentItemFound.__collapsed }]);
344
+ }
345
+ }
346
+
347
+ reapplyToggledItems() {
348
+ this.angularGrid.treeDataService.applyToggledItemStateChanges(this.treeToggleItems);
349
+ }
350
+
351
+ }
@@ -0,0 +1,41 @@
1
+ <div class="container">
2
+ <h2>{{title}}</h2>
3
+ <div class="subtitle" [innerHTML]="subTitle"></div>
4
+
5
+ <hr />
6
+
7
+ <h4>Description</h4>
8
+ <p>
9
+ One of the best javascript datagrid
10
+ <a href="https://github.com/mleibman/SlickGrid"
11
+ target="_blank">SlickGrid</a> which was originally developed by @mleibman is now available to Angular. I have
12
+ tried and used a few datagrids and SlickGrid beats most of them in terms of functionalities
13
+ and performance (it can easily deal with even a million row).
14
+ </p>
15
+ <h4>Wiki / Documentation</h4>
16
+ <p>
17
+ The Wiki is where all the documentation and instructions will go, so please consult the
18
+ <a href="https://github.com/ghiscoding/Angular-Slickgrid/wiki"
19
+ target="_blank">Angular-Slickgrid - Wiki</a>
20
+ before opening any issues.
21
+ <br />
22
+ The
23
+ <a href="https://github.com/ghiscoding/angular-slickgrid/wiki/HOWTO---Step-by-Step"
24
+ target="_blank">HOWTO - Wiki</a>
25
+ is the best starting point to get going with this library.
26
+ </p>
27
+
28
+ <hr />
29
+ Like my work? You can support me with caffeine :)
30
+
31
+ <br /><br />
32
+
33
+ <a href='https://ko-fi.com/N4N679OT'
34
+ target='_blank'>
35
+ <img height='36'
36
+ style='border:0px;height:36px;'
37
+ src='https://az743702.vo.msecnd.net/cdn/kofi2.png?v=0'
38
+ border='0'
39
+ alt='Buy Me a Coffee at ko-fi.com' />
40
+ </a>
41
+ </div>
@@ -0,0 +1,9 @@
1
+ import { Component } from '@angular/core';
2
+
3
+ @Component({
4
+ templateUrl: './home.component.html'
5
+ })
6
+ export class HomeComponent {
7
+ title = 'Angular-Slickgrid - Demo Site';
8
+ subTitle = 'This site is to demo multiple usage of Angular-Slickgrid, choose an example from left side menu';
9
+ }
@@ -0,0 +1,10 @@
1
+ import { Component } from '@angular/core';
2
+
3
+ @Component({
4
+ template:
5
+ `<h4>
6
+ <i class="fa fa-refresh fa-spin fa-2x fa-fw"></i>
7
+ Loading...
8
+ </h4>`
9
+ })
10
+ export class RowDetailPreloadComponent {}
@@ -0,0 +1,36 @@
1
+ <div class="container-fluid">
2
+ <h3>{{model?.title}}</h3>
3
+ <div class="row">
4
+ <div class="col-3"><label>Assignee:</label> <input class="form-control" [(ngModel)]="model.assignee" /></div>
5
+ <div class="col-3"><label>Reporter:</label> <span>{{model?.reporter}}</span></div>
6
+ <div class="col-2"><label>Duration:</label> <span>{{model?.duration | number : '1.2-2'}}</span></div>
7
+ <div class="col-2"><label>% Complete:</label> <span>{{model?.percentComplete}}</span></div>
8
+ </div>
9
+
10
+ <div class="row">
11
+ <div class="col-3"><label>Start:</label> <span>{{model?.start | date: 'yyyy-MM-dd'}}</span></div>
12
+ <div class="col-3"><label>Finish:</label> <span>{{model?.finish | date: 'yyyy-MM-dd'}}</span></div>
13
+ <div class="col-2"><label>Effort Driven:</label> <i [class]="model?.effortDriven ? 'fa fa-check' : ''"></i></div>
14
+ </div>
15
+
16
+ <hr>
17
+
18
+ <div class="col-sm-8">
19
+ <h4>
20
+ Find out who is the Assignee
21
+ <small>
22
+ <button class="btn btn-primary btn-sm" (click)="alertAssignee(model?.assignee)" data-test="assignee-btn">
23
+ Click Me
24
+ </button>
25
+ </small>
26
+ </h4>
27
+ </div>
28
+ <div class="col-sm-4">
29
+ <button class="btn btn-primary btn-danger btn-sm" (click)="deleteRow(model)" data-test="delete-btn">
30
+ Delete Row
31
+ </button>
32
+ <button class="btn btn-outline-secondary btn-sm" (click)="callParentMethod(model)" data-test="parent-btn">
33
+ Call Parent Method
34
+ </button>
35
+ </div>
36
+ </div>
@@ -0,0 +1,54 @@
1
+ import { Component } from '@angular/core';
2
+ import { SlickDataView, SlickGrid } from '../modules/angular-slickgrid';
3
+ import { GridRowDetailComponent } from './grid-rowdetail.component';
4
+
5
+ @Component({
6
+ templateUrl: './rowdetail-view.component.html'
7
+ })
8
+ export class RowDetailViewComponent {
9
+ model!: {
10
+ duration: Date;
11
+ percentComplete: number;
12
+ reporter: string;
13
+ start: Date;
14
+ finish: Date;
15
+ effortDriven: boolean;
16
+ assignee: string;
17
+ title: string;
18
+ };
19
+
20
+ // you also have access to the following objects (it must match the exact property names shown below)
21
+ addon: any; // row detail addon instance
22
+ grid!: SlickGrid;
23
+ dataView!: SlickDataView;
24
+
25
+ // you can also optionally use the Parent Component reference
26
+ // NOTE that you MUST provide it through the "parent" property in your "rowDetail" grid options
27
+ parent!: GridRowDetailComponent;
28
+
29
+ constructor() { }
30
+
31
+ alertAssignee(name: string) {
32
+ if (typeof name === 'string') {
33
+ alert(`Assignee on this task is: ${name.toUpperCase()}`);
34
+ } else {
35
+ alert('No one is assigned to this task.');
36
+ }
37
+ }
38
+
39
+ deleteRow(model: any) {
40
+ if (confirm(`Are you sure that you want to delete ${model.title}?`)) {
41
+ // you first need to collapse all rows (via the 3rd party addon instance)
42
+ this.addon.collapseAll();
43
+
44
+ // then you can delete the item from the dataView
45
+ this.dataView.deleteItem(model.rowId);
46
+
47
+ this.parent.showFlashMessage(`Deleted row with ${model.title}`, 'danger');
48
+ }
49
+ }
50
+
51
+ callParentMethod(model: any) {
52
+ this.parent.showFlashMessage(`We just called Parent Method from the Row Detail Child Component on ${model.title}`);
53
+ }
54
+ }
@@ -0,0 +1,156 @@
1
+ import { Component, OnInit, Input, } from '@angular/core';
2
+ import { SwtCommonGridComponent } from './swt-common-grid.component';
3
+ import { Logger } from './swt-logger.service';
4
+ import { HttpClient } from '@angular/common/http';
5
+ import { GridOption } from '../modules/angular-slickgrid';
6
+ /**
7
+ * Custom pagination component: It allows editing the page number manually
8
+ * << < Page [1] of 5 > >>
9
+ *
10
+ * @author Saber Chebka, saber.chebka@gmail.com
11
+ */
12
+ @Component({
13
+ selector: 'swt-common-grid-pagination',
14
+ template: `
15
+ <div class="slick-pagination">
16
+ <div class="slick-pagination-nav">
17
+ <nav aria-label="Page navigation">
18
+ <ul class="pagination">
19
+ <li class="page-item" [ngClass]="pageNumber === 1 ? 'disabled' : ''">
20
+ <a class="page-link icon-seek-first fa fa-angle-double-left"
21
+ aria-label="First" (click)="changeToFirstPage($event)"> </a>
22
+ </li>
23
+ <li class="page-item" [ngClass]="pageNumber === 1 ? 'disabled' : ''">
24
+ <a class="page-link icon-seek-prev fa fa-angle-left"
25
+ aria-label="Previous" (click)="changeToPreviousPage($event)"> </a>
26
+ </li>
27
+ </ul>
28
+ </nav>
29
+
30
+ <div class="slick-page-number">
31
+ <span [translate]="'PAGE'"></span>
32
+ <input type="text" value="{{pageNumber}}" size="1" (change)="changeToCurrentPage($event)">
33
+ <span [translate]="'OF'"></span><span> {{pageCount}}</span>
34
+ </div>
35
+
36
+ <nav aria-label="Page navigation">
37
+ <ul class="pagination">
38
+ <li class="page-item"
39
+ [ngClass]="pageNumber === pageCount ? 'disabled' : ''"><a
40
+ class="page-link icon-seek-next text-center fa fa-lg fa-angle-right"
41
+ aria-label="Next" (click)="changeToNextPage($event)"> </a></li>
42
+ <li class="page-item"
43
+ [ngClass]="pageNumber === pageCount ? 'disabled' : ''"><a
44
+ class="page-link icon-seek-end fa fa-lg fa-angle-double-right"
45
+ aria-label="Last" (click)="changeToLastPage($event)"> </a></li>
46
+ </ul>
47
+ </nav>
48
+ <nav>
49
+ <ul class="pagination">
50
+ <li class="">
51
+ <span [hidden]="!processing" class="page-spin">
52
+ <i class="fa fa-refresh fa-spin fa-lg fa-fw"></i>
53
+ </span>
54
+ </li>
55
+ </ul>
56
+ </nav>
57
+ </div>
58
+ </div>
59
+ `,
60
+ styles: [`.page-spin {
61
+ border: none;
62
+ height: 32px;
63
+ background-color: transparent;
64
+ cursor: default;
65
+ animation: fa-spin 1.2s infinite linear !important;
66
+ }
67
+ .page-spin:hover {
68
+ background-color: transparent;
69
+ }
70
+ `]
71
+ })
72
+ export class SwtCommonGridPaginationComponent implements OnInit {
73
+ private logger: Logger;
74
+
75
+ @Input() pageCount = 1;
76
+ @Input() pageNumber = 1;
77
+
78
+ totalItems = 0;
79
+ processing = false;
80
+
81
+ // Reference to the real pagination component
82
+ realPagination = true;
83
+ _gridPaginationOptions!: GridOption;
84
+ commonGrid!: SwtCommonGridComponent;
85
+
86
+ @Input()
87
+ set gridPaginationOptions(gridPaginationOptions: GridOption) {
88
+ this._gridPaginationOptions = gridPaginationOptions;
89
+
90
+ // The backendServiceApi is itself the SwtCommonGridComponent (This is a hack)
91
+ this.commonGrid = <SwtCommonGridComponent>this.gridPaginationOptions!.backendServiceApi!.service;
92
+ }
93
+ get gridPaginationOptions(): GridOption {
94
+ return this._gridPaginationOptions;
95
+ }
96
+
97
+
98
+
99
+ constructor(private httpClient: HttpClient) {
100
+ this.logger = new Logger('grid-pagination', httpClient);
101
+ this.logger.info('method [constructor] - START/END');
102
+ }
103
+
104
+
105
+ ngOnInit() {
106
+ this.logger.info('init: ');
107
+ }
108
+
109
+
110
+
111
+ changeToFirstPage(event: any) {
112
+ this.logger.info('method [changeToFirstPage] - START/END');
113
+ this.pageNumber = 1;
114
+ this.onPageChanged(event, this.pageNumber);
115
+ }
116
+
117
+ changeToLastPage(event: any) {
118
+ this.logger.info('method [changeToLastPage] - START/END');
119
+ this.pageNumber = this.pageCount;
120
+ this.onPageChanged(event, this.pageNumber);
121
+ }
122
+
123
+ changeToNextPage(event: any) {
124
+ this.logger.info('method [changeToNextPage] - START/END');
125
+ if (this.pageNumber < this.pageCount) {
126
+ this.pageNumber++;
127
+ this.onPageChanged(event, this.pageNumber);
128
+ }
129
+ }
130
+
131
+ changeToPreviousPage(event: any) {
132
+ this.logger.info('method [changeToNextPage] - START/END');
133
+ if (this.pageNumber > 1) {
134
+ this.pageNumber--;
135
+ this.onPageChanged(event, this.pageNumber);
136
+ }
137
+ }
138
+
139
+
140
+ changeToCurrentPage(event: any) {
141
+ this.logger.info('method [changeToCurrentPage] - START/END');
142
+ this.pageNumber = event.currentTarget.value;
143
+ if (this.pageNumber < 1) {
144
+ this.pageNumber = 1;
145
+ } else if (this.pageNumber > this.pageCount) {
146
+ this.pageNumber = this.pageCount;
147
+ }
148
+
149
+ this.onPageChanged(event, this.pageNumber);
150
+ }
151
+
152
+ onPageChanged(event?: Event, pageNumber?: number) {
153
+ this.logger.info('method [onPageChanged] - START/END', this.commonGrid);
154
+ this.commonGrid.processOnPaginationChanged(event, { newPage: pageNumber as number, pageSize: -1 });
155
+ }
156
+ }