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,483 @@
1
+ import { Component, OnInit, ViewEncapsulation, } from '@angular/core';
2
+ import { SlickCustomTooltip } from '@slickgrid-universal/custom-tooltip-plugin';
3
+ import { ExcelExportService } from '@slickgrid-universal/excel-export';
4
+ import {
5
+ AngularGridInstance,
6
+ Column,
7
+ EditCommand,
8
+ Editors,
9
+ FieldType,
10
+ Filters,
11
+ Formatter,
12
+ Formatters,
13
+ GridOption,
14
+ MenuCommandItemCallbackArgs,
15
+ OperatorType,
16
+ SlickGrid,
17
+ } from '../modules/angular-slickgrid';
18
+
19
+ const NB_ITEMS = 500;
20
+
21
+ @Component({
22
+ templateUrl: './grid-custom-tooltip.component.html',
23
+ styleUrls: ['./grid-custom-tooltip.component.scss'],
24
+ encapsulation: ViewEncapsulation.None,
25
+ })
26
+ export class GridCustomTooltipComponent implements OnInit {
27
+ title = 'Example 32: Regular & Custom Tooltips';
28
+ subTitle = `
29
+ This demo shows how to create Regular & Custom Tooltips (<a href="https://github.com/ghiscoding/Angular-Slickgrid/wiki/Custom-Tooltip-(plugin)" target="_blank">Wiki docs</a>)
30
+ <br/>
31
+ <ul class="small">
32
+ <li>optionally parse regular [title] attributes and transform them into tooltips</li>
33
+ <li>create your own Custom Tooltip via a Custom Formatter</li>
34
+ <li>create an Async Custom Tooltip (Promise/Observable) to allowing fetching data from an API</li>
35
+ <li>optionally add Custom Tooltip on Column Header & Column Header-Row (filters)</li>
36
+ </ul>
37
+ `;
38
+ angularGrid!: AngularGridInstance;
39
+ columnDefinitions!: Column[];
40
+ editCommandQueue: EditCommand[] = [];
41
+ gridOptions!: GridOption;
42
+ dataset!: any[];
43
+ serverApiDelay = 500;
44
+
45
+ constructor() { }
46
+
47
+ ngOnInit(): void {
48
+ this.initializeGrid();
49
+
50
+ // mock a dataset
51
+ this.dataset = this.loadData(NB_ITEMS);
52
+ }
53
+
54
+ angularGridReady(angularGrid: AngularGridInstance) {
55
+ this.angularGrid = angularGrid;
56
+ }
57
+
58
+ initializeGrid() {
59
+ this.columnDefinitions = [
60
+ {
61
+ id: 'title', name: 'Title', field: 'title', sortable: true, type: FieldType.string,
62
+ editor: {
63
+ model: Editors.longText,
64
+ required: true,
65
+ alwaysSaveOnEnterKey: true,
66
+ minLength: 5,
67
+ maxLength: 255,
68
+ },
69
+ filterable: true,
70
+ customTooltip: {
71
+ position: 'right-align', // defaults to "auto"
72
+ // you can use the Custom Tooltip in 2 ways (synchronous or asynchronous)
73
+ // example 1 (sync):
74
+ // formatter: this.tooltipTaskFormatter,
75
+
76
+ // example 2 (async):
77
+ // when using async, the `formatter` will contain the loading spinner
78
+ // you will need to provide an `asyncPost` function returning a Promise and also `asyncPostFormatter` formatter to display the result once the Promise resolves
79
+ formatter: () => `<div><span class="fa fa-spinner fa-pulse fa-fw"></span> loading...</div>`,
80
+ asyncProcess: () => new Promise(resolve => {
81
+ setTimeout(() => resolve({ ratio: Math.random() * 10 / 10, lifespan: Math.random() * 100 }), this.serverApiDelay);
82
+ }),
83
+ asyncPostFormatter: this.tooltipTaskAsyncFormatter as Formatter,
84
+
85
+ // optional conditional usability callback
86
+ // usabilityOverride: (args) => !!(args.dataContext?.id % 2) // show it only every second row
87
+ },
88
+ },
89
+ {
90
+ id: 'duration', name: 'Duration', field: 'duration', sortable: true, filterable: true,
91
+ editor: {
92
+ model: Editors.float,
93
+ // required: true,
94
+ decimal: 2,
95
+ valueStep: 1,
96
+ maxValue: 10000,
97
+ alwaysSaveOnEnterKey: true,
98
+ },
99
+ formatter: (row, cell, value) => value > 1 ? `${value} days` : `${value} day`,
100
+ type: FieldType.number,
101
+ },
102
+ {
103
+ id: 'desc', name: `<span title='custom title tooltip text'>Description</span>`, field: 'description', width: 100, filterable: true,
104
+ editor: {
105
+ model: Editors.longText,
106
+ required: true,
107
+ alwaysSaveOnEnterKey: true,
108
+ minLength: 5,
109
+ maxLength: 255,
110
+ },
111
+ formatter: (row: number, cell: number, value: any, column: Column, dataContext) => `<span title="regular tooltip (from title attribute)\r${dataContext.title} cell value:\r${value || ''}">${value || ''}</span>`,
112
+ // define tooltip options here OR for the entire grid via the grid options (cell tooltip options will have precedence over grid options)
113
+ customTooltip: {
114
+ useRegularTooltip: true, // note regular tooltip will try to find a "title" attribute in the cell formatter (it won't work without a cell formatter)
115
+ },
116
+ },
117
+ {
118
+ id: 'desc2', name: `<span title='custom title tooltip text'>Description 2</span>`, field: 'description', width: 100, filterable: true,
119
+ editor: {
120
+ model: Editors.longText,
121
+ required: true,
122
+ alwaysSaveOnEnterKey: true,
123
+ minLength: 5,
124
+ maxLength: 255,
125
+ },
126
+ formatter: (row: number, cell: number, value: any, column: Column, dataContext) => `<span title="regular tooltip (from title attribute)\r${dataContext.title} cell value:\r\r${value || ''}">${value || ''}</span>`,
127
+ // define tooltip options here OR for the entire grid via the grid options (cell tooltip options will have precedence over grid options)
128
+ customTooltip: {
129
+ useRegularTooltip: true, // note regular tooltip will try to find a "title" attribute in the cell formatter (it won't work without a cell formatter)
130
+ useRegularTooltipFromFormatterOnly: true,
131
+ // renderRegularTooltipAsHtml: true, // defaults to false, regular "title" tooltip won't be rendered as html unless specified via this flag (also "\r\n" will be replaced by <br>)
132
+ // maxWidth: 75,
133
+ // maxHeight: 30,
134
+ },
135
+ },
136
+ {
137
+ id: 'cost', name: '<span title="custom cost title tooltip text">Cost</span>', field: 'cost',
138
+ width: 90,
139
+ sortable: true,
140
+ filterable: true,
141
+ // filter: { model: Filters.compoundInput },
142
+ // formatter: Formatters.dollar,
143
+ formatter: Formatters.multiple,
144
+ // params: { formatters: [Formatters.dollar, (row, cell, value) => `<span title="regular tooltip, cost: ${value}">${value || ''}</span>`] },
145
+ params: { formatters: [Formatters.dollar, (_row: number, _cell: number, value: any) => `<span title="regular tooltip (from title attribute) -\rcell value:\n\n${value || ''}">${value || ''}</span>`] },
146
+ customTooltip: {
147
+ useRegularTooltip: true,
148
+ useRegularTooltipFromFormatterOnly: true,
149
+ },
150
+ type: FieldType.number,
151
+ },
152
+ {
153
+ id: 'percentComplete', name: '% Complete', field: 'percentComplete', type: FieldType.number,
154
+ editor: {
155
+ model: Editors.slider,
156
+ minValue: 0,
157
+ maxValue: 100,
158
+ // params: { hideSliderNumber: true },
159
+ },
160
+ formatter: Formatters.percentCompleteBar,
161
+ sortable: true, filterable: true,
162
+ filter: { model: Filters.slider, operator: '>=' },
163
+ customTooltip: { useRegularTooltip: true, },
164
+ },
165
+ {
166
+ id: 'start', name: 'Start', field: 'start', sortable: true,
167
+ // formatter: Formatters.dateIso,
168
+ type: FieldType.date, outputType: FieldType.dateIso,
169
+ filterable: true, filter: { model: Filters.compoundDate },
170
+ formatter: Formatters.dateIso,
171
+ editor: { model: Editors.date },
172
+ // we can delay a tooltip via the async process
173
+ customTooltip: {
174
+ // 1- loading formatter
175
+ formatter: () => ``, // return empty so it won't show any pre-tooltip
176
+
177
+ // 2- delay the opening by a simple Promise and `setTimeout`
178
+ asyncProcess: () => new Promise(resolve => {
179
+ setTimeout(() => resolve({}), this.serverApiDelay); // delayed by half a second
180
+ }),
181
+ asyncPostFormatter: this.tooltipFormatter.bind(this) as Formatter,
182
+ },
183
+ },
184
+ {
185
+ id: 'finish', name: 'Finish', field: 'finish', sortable: true,
186
+ editor: { model: Editors.date, editorOptions: { minDate: 'today' }, },
187
+ // formatter: Formatters.dateIso,
188
+ type: FieldType.date, outputType: FieldType.dateIso,
189
+ formatter: Formatters.dateIso,
190
+ filterable: true, filter: { model: Filters.dateRange },
191
+ // you could disable the custom/regular tooltip via either of the following 2 options
192
+ disableTooltip: true,
193
+ // customTooltip: {
194
+ // usabilityOverride: (args) => false,
195
+ // },
196
+ },
197
+ {
198
+ id: 'effortDriven', name: 'Effort Driven', field: 'effortDriven',
199
+ width: 80, minWidth: 20, maxWidth: 100,
200
+ cssClass: 'cell-effort-driven',
201
+ sortable: true,
202
+ filterable: true,
203
+ filter: {
204
+ collection: [{ value: '', label: '' }, { value: true, label: 'True' }, { value: false, label: 'False' }],
205
+ model: Filters.singleSelect
206
+ },
207
+ exportWithFormatter: false,
208
+ formatter: Formatters.checkmarkMaterial,
209
+ },
210
+ {
211
+ id: 'prerequisites', name: 'Prerequisites', field: 'prerequisites', filterable: true,
212
+ formatter: (_row, _cell, value) => {
213
+ if (value && Array.isArray(value)) {
214
+ const values = value.map((val) => `Task ${val}`).join(', ');
215
+ return `<span title="${values}">${values}</span>`;
216
+ }
217
+ return '';
218
+ },
219
+ customTooltip: {
220
+ useRegularTooltip: true,
221
+ maxWidth: 500,
222
+ },
223
+ exportWithFormatter: true,
224
+ sanitizeDataExport: true,
225
+ minWidth: 100,
226
+ sortable: true,
227
+ type: FieldType.string,
228
+ editor: {
229
+ // OR 1- use "fetch client", they are both supported
230
+ // collectionAsync: fetch(URL_SAMPLE_COLLECTION_DATA),
231
+
232
+ // OR 2- use a Promise
233
+ collectionAsync: new Promise<any>((resolve) => {
234
+ setTimeout(() => {
235
+ resolve(Array.from(Array(this.dataset.length).keys()).map(k => ({ value: k, label: k, prefix: 'Task', suffix: 'days' })));
236
+ }, 500);
237
+ }),
238
+ customStructure: {
239
+ label: 'label',
240
+ value: 'value',
241
+ labelPrefix: 'prefix',
242
+ },
243
+ collectionOptions: {
244
+ separatorBetweenTextLabels: ' '
245
+ },
246
+ model: Editors.multipleSelect,
247
+ },
248
+ filter: {
249
+ // collectionAsync: fetch(URL_SAMPLE_COLLECTION_DATA),
250
+ collectionAsync: new Promise((resolve) => {
251
+ setTimeout(() => {
252
+ resolve(Array.from(Array(this.dataset.length).keys()).map(k => ({ value: k, label: `Task ${k}` })));
253
+ });
254
+ }),
255
+ customStructure: {
256
+ label: 'label',
257
+ value: 'value',
258
+ labelPrefix: 'prefix',
259
+ },
260
+ collectionOptions: {
261
+ separatorBetweenTextLabels: ' '
262
+ },
263
+ model: Filters.multipleSelect,
264
+ operator: OperatorType.inContains,
265
+ },
266
+ },
267
+ {
268
+ id: 'action', name: 'Action', field: 'action', width: 70, minWidth: 70, maxWidth: 70,
269
+ formatter: () => `<div class="button-style margin-auto" style="width: 35px;"><span class="fa fa-chevron-down text-primary"></span></div>`,
270
+ excludeFromExport: true,
271
+ cellMenu: {
272
+ hideCloseButton: false,
273
+ commandTitle: 'Commands',
274
+ commandItems: [
275
+ // array of command item objects, you can also use the "positionOrder" that will be used to sort the items in the list
276
+ {
277
+ command: 'command2', title: 'Command 2', positionOrder: 62,
278
+ // you can use the "action" callback and/or use "onCallback" callback from the grid options, they both have the same arguments
279
+ action: (_e, args) => {
280
+ console.log(args.dataContext, args.column);
281
+ // action callback.. do something
282
+ },
283
+ // only enable command when the task is not completed
284
+ itemUsabilityOverride: (args) => {
285
+ return !args.dataContext.completed;
286
+ }
287
+ },
288
+ { command: 'command1', title: 'Command 1', cssClass: 'orange', positionOrder: 61 },
289
+ {
290
+ command: 'delete-row', title: 'Delete Row', positionOrder: 64,
291
+ iconCssClass: 'mdi mdi-close', cssClass: 'red', textCssClass: 'bold',
292
+ // only show command to 'Delete Row' when the task is not completed
293
+ itemVisibilityOverride: (args) => {
294
+ return !args.dataContext.completed;
295
+ }
296
+ },
297
+ // you can pass divider as a string or an object with a boolean (if sorting by position, then use the object)
298
+ // note you should use the "divider" string only when items array is already sorted and positionOrder are not specified
299
+ { divider: true, command: '', positionOrder: 63 },
300
+ // 'divider',
301
+ {
302
+ command: 'help',
303
+ title: 'Help',
304
+ iconCssClass: 'mdi mdi-help-circle-outline',
305
+ positionOrder: 66,
306
+ },
307
+ { command: 'something', title: 'Disabled Command', disabled: true, positionOrder: 67, }
308
+ ],
309
+ }
310
+ },
311
+ ];
312
+
313
+ this.gridOptions = {
314
+ autoEdit: true, // true single click (false for double-click)
315
+ autoCommitEdit: true,
316
+ editable: true,
317
+ autoResize: {
318
+ container: '#demo-container',
319
+ },
320
+ enableAutoSizeColumns: true,
321
+ enableAutoResize: true,
322
+ enableCellNavigation: true,
323
+ enableExcelExport: true,
324
+ excelExportOptions: {
325
+ exportWithFormatter: true
326
+ },
327
+ // Custom Tooltip options can be defined in a Column or Grid Options or a mixed of both (first options found wins)
328
+ registerExternalResources: [new SlickCustomTooltip(), new ExcelExportService()],
329
+ customTooltip: {
330
+ formatter: this.tooltipFormatter.bind(this) as Formatter,
331
+ headerFormatter: this.headerFormatter,
332
+ headerRowFormatter: this.headerRowFormatter,
333
+ usabilityOverride: (args) => (args.cell !== 0 && args?.column?.id !== 'action'), // don't show on first/last columns
334
+ // hideArrow: true, // defaults to False
335
+ },
336
+ presets: {
337
+ filters: [{ columnId: 'prerequisites', searchTerms: [1, 3, 5, 7, 9, 12, 15, 18, 21, 25, 28, 29, 30, 32, 34] }],
338
+ },
339
+ rowHeight: 33,
340
+ enableFiltering: true,
341
+ rowSelectionOptions: {
342
+ // True (Single Selection), False (Multiple Selections)
343
+ selectActiveRow: false
344
+ },
345
+ showCustomFooter: true,
346
+ enableCheckboxSelector: true,
347
+ enableRowSelection: true,
348
+ checkboxSelector: {
349
+ hideInFilterHeaderRow: false,
350
+ hideInColumnTitleRow: true,
351
+ },
352
+ editCommandHandler: (_item: any, _column: Column, editCommand: EditCommand) => {
353
+ this.editCommandQueue.push(editCommand);
354
+ editCommand.execute();
355
+ },
356
+ // when using the cellMenu, you can change some of the default options and all use some of the callback methods
357
+ enableCellMenu: true,
358
+ cellMenu: {
359
+ // all the Cell Menu callback methods (except the action callback)
360
+ // are available under the grid options as shown below
361
+ onCommand: (e, args) => this.executeCommand(e, args),
362
+ onOptionSelected: (_e, args) => {
363
+ // change "Completed" property with new option selected from the Cell Menu
364
+ const dataContext = args && args.dataContext;
365
+ if (dataContext && dataContext.hasOwnProperty('completed')) {
366
+ dataContext.completed = args.item.option;
367
+ this.angularGrid.gridService.updateItem(dataContext);
368
+ }
369
+ },
370
+ },
371
+ };
372
+ }
373
+
374
+ loadData(itemCount: number): any[] {
375
+ // mock a dataset
376
+ // mock data
377
+ const tmpArray = [];
378
+ for (let i = 0; i < itemCount; i++) {
379
+ const randomYear = 2000 + Math.floor(Math.random() * 10);
380
+ const randomFinishYear = (new Date().getFullYear() - 3) + Math.floor(Math.random() * 10); // use only years not lower than 3 years ago
381
+ const randomMonth = Math.floor(Math.random() * 11);
382
+ const randomDay = Math.floor((Math.random() * 29));
383
+ const randomFinish = new Date(randomFinishYear, (randomMonth + 1), randomDay);
384
+
385
+ tmpArray[i] = {
386
+ id: i,
387
+ title: 'Task ' + i,
388
+ duration: Math.round(Math.random() * 100),
389
+ description: `This is a sample task description.\nIt can be multiline\r\rAnother line...`,
390
+ percentComplete: Math.floor(Math.random() * (100 - 5 + 1) + 5),
391
+ start: new Date(randomYear, randomMonth, randomDay),
392
+ finish: randomFinish < new Date() ? '' : randomFinish, // make sure the random date is earlier than today
393
+ cost: (i % 33 === 0) ? null : Math.round(Math.random() * 10000) / 100,
394
+ effortDriven: (i % 5 === 0),
395
+ prerequisites: (i % 2 === 0) && i !== 0 && i < 50 ? [i, i - 1] : [],
396
+ };
397
+ }
398
+
399
+ return tmpArray;
400
+ }
401
+
402
+ executeCommand(_e: Event, args: MenuCommandItemCallbackArgs) {
403
+ // const columnDef = args.column;
404
+ const command = args.command;
405
+ const dataContext = args.dataContext;
406
+
407
+ switch (command) {
408
+ case 'command1':
409
+ alert('Command 1');
410
+ break;
411
+ case 'command2':
412
+ alert('Command 2');
413
+ break;
414
+ case 'help':
415
+ alert('Please help!');
416
+ break;
417
+ case 'delete-row':
418
+ if (confirm(`Do you really want to delete row (${(args.row || 0) + 1}) with "${dataContext.title}"`)) {
419
+ this.angularGrid?.gridService.deleteItemById(dataContext.id);
420
+ }
421
+ break;
422
+ }
423
+ }
424
+
425
+ headerFormatter(row: number, cell: number, value: any, column: Column) {
426
+ const tooltipTitle = 'Custom Tooltip - Header';
427
+ return `<div class="header-tooltip-title">${tooltipTitle}</div>
428
+ <div class="tooltip-2cols-row"><div>Column:</div> <div>${column.name}</div></div>`;
429
+ }
430
+
431
+ headerRowFormatter(row: number, cell: number, value: any, column: Column) {
432
+ const tooltipTitle = 'Custom Tooltip - Header Row (filter)';
433
+ return `<div class="headerrow-tooltip-title">${tooltipTitle}</div>
434
+ <div class="tooltip-2cols-row"><div>Column:</div> <div>${column.field}</div></div>`;
435
+ }
436
+
437
+ tooltipFormatter(row: number, cell: number, value: any, column: Column, dataContext: any, grid: SlickGrid) {
438
+ const tooltipTitle = 'Custom Tooltip';
439
+ const effortDrivenHtml = Formatters.checkmarkMaterial(row, cell, dataContext.effortDriven, column, dataContext, grid);
440
+
441
+ return `<div class="header-tooltip-title">${tooltipTitle}</div>
442
+ <div class="tooltip-2cols-row"><div>Id:</div> <div>${dataContext.id}</div></div>
443
+ <div class="tooltip-2cols-row"><div>Title:</div> <div>${dataContext.title}</div></div>
444
+ <div class="tooltip-2cols-row"><div>Effort Driven:</div> <div>${effortDrivenHtml}</div></div>
445
+ <div class="tooltip-2cols-row"><div>Completion:</div> <div>${this.loadCompletionIcons(dataContext.percentComplete)}</div></div>
446
+ `;
447
+ }
448
+
449
+ tooltipTaskAsyncFormatter(row: number, cell: number, value: any, column: Column, dataContext: any, grid: SlickGrid) {
450
+ const tooltipTitle = `Task ${dataContext.id} - (async tooltip)`;
451
+
452
+ // use a 2nd Formatter to get the percent completion
453
+ // any properties provided from the `asyncPost` will end up in the `__params` property (unless a different prop name is provided via `asyncParamsPropName`)
454
+ const completionBar = Formatters.percentCompleteBarWithText(row, cell, dataContext.percentComplete, column, dataContext, grid);
455
+ const out = `<div class="color-sf-primary-dark header-tooltip-title">${tooltipTitle}</div>
456
+ <div class="tooltip-2cols-row"><div>Completion:</div> <div>${completionBar}</div></div>
457
+ <div class="tooltip-2cols-row"><div>Lifespan:</div> <div>${dataContext.__params.lifespan.toFixed(2)}</div></div>
458
+ <div class="tooltip-2cols-row"><div>Ratio:</div> <div>${dataContext.__params.ratio.toFixed(2)}</div></div>
459
+ `;
460
+ return out;
461
+ }
462
+
463
+ loadCompletionIcons(percentComplete: number) {
464
+ let output = '';
465
+ let iconCount = 0;
466
+ if (percentComplete > 5 && percentComplete < 25) {
467
+ iconCount = 1;
468
+ } else if (percentComplete >= 25 && percentComplete < 50) {
469
+ iconCount = 2;
470
+ } else if (percentComplete >= 50 && percentComplete < 75) {
471
+ iconCount = 3;
472
+ } else if (percentComplete >= 75 && percentComplete < 100) {
473
+ iconCount = 4;
474
+ } else if (percentComplete === 100) {
475
+ iconCount = 5;
476
+ }
477
+ for (let i = 0; i < iconCount; i++) {
478
+ const iconColor = iconCount === 5 ? 'text-success' : iconCount >= 3 ? 'text-warning' : 'text-secondary';
479
+ output += `<span class="fa fa-check-circle-o ${iconColor}"></span>`;
480
+ }
481
+ return output;
482
+ }
483
+ }
@@ -0,0 +1,93 @@
1
+ <div id="demo-container" class="container-fluid">
2
+ <h2>
3
+ {{title}}
4
+ <span class="float-end">
5
+ <a style="font-size: 18px"
6
+ target="_blank"
7
+ href="https://github.com/ghiscoding/Angular-Slickgrid/blob/master/src/app/examples/grid-draggrouping.component.ts">
8
+ <span class="fa fa-link"></span> code
9
+ </a>
10
+ </span>
11
+ </h2>
12
+ <div class="subtitle" [innerHTML]="subTitle"></div>
13
+
14
+ <form class="form-inline">
15
+ <div class="row">
16
+ <div class="col-sm-12">
17
+ <button class="btn btn-outline-secondary btn-xs" data-test="add-500-rows-btn" (click)="loadData(500)">
18
+ 500 rows
19
+ </button>
20
+ <button class="btn btn-outline-secondary btn-xs" data-test="add-50k-rows-btn" (click)="loadData(50000)">
21
+ 50k rows
22
+ </button>
23
+ <button class="btn btn-outline-secondary btn-xs" data-test="clear-grouping-btn"
24
+ (click)="clearGroupsAndSelects()">
25
+ <i class="fa fa-times"></i> Clear grouping
26
+ </button>
27
+ <button class="btn btn-outline-secondary btn-xs" data-test="collapse-all-btn" (click)="collapseAllGroups()">
28
+ <i class="fa fa-compress"></i> Collapse all groups
29
+ </button>
30
+ <button class="btn btn-outline-secondary btn-xs" data-test="expand-all-btn" (click)="expandAllGroups()">
31
+ <i class="fa fa-expand"></i> Expand all groups
32
+ </button>
33
+ <button class="btn btn-outline-secondary btn-xs" (click)="toggleDraggableGroupingRow()">
34
+ Toggle Draggable Grouping Row
35
+ </button>
36
+ <button class="btn btn-outline-secondary btn-xs" (click)="exportToExcel()">
37
+ <i class="fa fa-file-excel-o text-success"></i> Export to Excel
38
+ </button>
39
+ </div>
40
+ </div>
41
+ <div class="row">
42
+ <div class="col-sm-12">
43
+ <button class="btn btn-outline-secondary btn-xs" data-test="group-duration-sort-value-btn"
44
+ (click)="groupByDurationOrderByCount(false)">
45
+ Group by duration &amp; sort groups by value
46
+ </button>
47
+ <button class="btn btn-outline-secondary btn-xs" data-test="group-duration-sort-count-btn"
48
+ (click)="groupByDurationOrderByCount(true)">
49
+ Group by duration &amp; sort groups by count
50
+ </button>
51
+ <button class="btn btn-outline-secondary btn-xs" data-test="group-duration-effort-btn"
52
+ (click)="groupByDurationEffortDriven()">
53
+ Group by Duration &amp; then Effort-Driven
54
+ </button>
55
+ <button class="btn btn-outline-secondary btn-xs" data-test="set-dynamic-filter"
56
+ (click)="setFiltersDynamically()">
57
+ Set Filters Dynamically
58
+ </button>
59
+ <button class="btn btn-outline-secondary btn-xs" data-test="set-dynamic-sorting"
60
+ (click)="setSortingDynamically()">
61
+ Set Sorting Dynamically
62
+ </button>
63
+ </div>
64
+ </div>
65
+ <div class="row mt-2">
66
+ <div class="col-sm-12">
67
+ <div class="form-row">
68
+ <div class="row form-group">
69
+ <label for="field1" class="col-sm-3 mb-2">Group by field(s)</label>
70
+ <div class="form-group col-md-3"
71
+ *ngFor="let groupField of selectedGroupingFields; let i = index; trackBy: selectTrackByFn">
72
+ <select class="form-select" name="groupField{{i}}" [(ngModel)]="selectedGroupingFields[i]"
73
+ (ngModelChange)="groupByFieldName($event, i)">
74
+ <option value=""></option>
75
+ <option [ngValue]="field.id" *ngFor="let field of columnDefinitions">{{field.name}}</option>
76
+ </select>
77
+ </div>
78
+ </div>
79
+ </div>
80
+ </div>
81
+ </div>
82
+ </form>
83
+ <div class="row mt-1 mb-1">
84
+ <hr />
85
+ </div>
86
+
87
+ <angular-slickgrid gridId="grid19"
88
+ [dataset]="dataset"
89
+ [columnDefinitions]="columnDefinitions"
90
+ [gridOptions]="gridOptions"
91
+ (onAngularGridCreated)="angularGridReady($event.detail)">
92
+ </angular-slickgrid>
93
+ </div>