@everymatrix/stage-mm-verification-report 1.0.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 (201) hide show
  1. package/chunk-A3NTIEMP.js +1 -0
  2. package/chunk-CAY35YP7.js +7 -0
  3. package/chunk-H3QHLLCN.js +1 -0
  4. package/chunk-KE4BCZO4.js +851 -0
  5. package/chunk-OHPEWN32.js +1198 -0
  6. package/chunk-WSQOM5HU.js +1 -0
  7. package/component-lib.js +1 -0
  8. package/index.html +12 -0
  9. package/main.js +3264 -0
  10. package/modules/angular/LICENSE.md +21 -0
  11. package/modules/angular/README.md +67 -0
  12. package/modules/angular/angular-csp.css +25 -0
  13. package/modules/angular/angular.js +36600 -0
  14. package/modules/angular/angular.min.js +352 -0
  15. package/modules/angular/angular.min.js.gzip +0 -0
  16. package/modules/angular/angular.min.js.map +8 -0
  17. package/modules/angular/bower.json +9 -0
  18. package/modules/angular/index.js +2 -0
  19. package/modules/angular/package.json +25 -0
  20. package/modules/angular-ui-grid/CHANGELOG.md +1973 -0
  21. package/modules/angular-ui-grid/README.md +59 -0
  22. package/modules/angular-ui-grid/css/ui-grid.cellnav.css +25 -0
  23. package/modules/angular-ui-grid/css/ui-grid.cellnav.min.css +1 -0
  24. package/modules/angular-ui-grid/css/ui-grid.core.css +866 -0
  25. package/modules/angular-ui-grid/css/ui-grid.core.min.css +5 -0
  26. package/modules/angular-ui-grid/css/ui-grid.edit.css +23 -0
  27. package/modules/angular-ui-grid/css/ui-grid.edit.min.css +1 -0
  28. package/modules/angular-ui-grid/css/ui-grid.empty-base-layer.css +6 -0
  29. package/modules/angular-ui-grid/css/ui-grid.empty-base-layer.min.css +1 -0
  30. package/modules/angular-ui-grid/css/ui-grid.expandable.css +16 -0
  31. package/modules/angular-ui-grid/css/ui-grid.expandable.min.css +1 -0
  32. package/modules/angular-ui-grid/css/ui-grid.exporter.css +0 -0
  33. package/modules/angular-ui-grid/css/ui-grid.exporter.min.css +0 -0
  34. package/modules/angular-ui-grid/css/ui-grid.grouping.css +3 -0
  35. package/modules/angular-ui-grid/css/ui-grid.grouping.min.css +1 -0
  36. package/modules/angular-ui-grid/css/ui-grid.importer.css +0 -0
  37. package/modules/angular-ui-grid/css/ui-grid.importer.min.css +0 -0
  38. package/modules/angular-ui-grid/css/ui-grid.move-columns.css +9 -0
  39. package/modules/angular-ui-grid/css/ui-grid.move-columns.min.css +1 -0
  40. package/modules/angular-ui-grid/css/ui-grid.pagination.css +299 -0
  41. package/modules/angular-ui-grid/css/ui-grid.pagination.min.css +1 -0
  42. package/modules/angular-ui-grid/css/ui-grid.pinning.css +67 -0
  43. package/modules/angular-ui-grid/css/ui-grid.pinning.min.css +1 -0
  44. package/modules/angular-ui-grid/css/ui-grid.resize-columns.css +38 -0
  45. package/modules/angular-ui-grid/css/ui-grid.resize-columns.min.css +1 -0
  46. package/modules/angular-ui-grid/css/ui-grid.row-edit.css +9 -0
  47. package/modules/angular-ui-grid/css/ui-grid.row-edit.min.css +1 -0
  48. package/modules/angular-ui-grid/css/ui-grid.selection.css +25 -0
  49. package/modules/angular-ui-grid/css/ui-grid.selection.min.css +1 -0
  50. package/modules/angular-ui-grid/css/ui-grid.tree-base.css +4 -0
  51. package/modules/angular-ui-grid/css/ui-grid.tree-base.min.css +1 -0
  52. package/modules/angular-ui-grid/css/ui-grid.tree-view.css +6 -0
  53. package/modules/angular-ui-grid/css/ui-grid.tree-view.min.css +1 -0
  54. package/modules/angular-ui-grid/css/ui-grid.validate.css +3 -0
  55. package/modules/angular-ui-grid/css/ui-grid.validate.min.css +1 -0
  56. package/modules/angular-ui-grid/fonts/ui-grid.eot +0 -0
  57. package/modules/angular-ui-grid/fonts/ui-grid.svg +56 -0
  58. package/modules/angular-ui-grid/fonts/ui-grid.ttf +0 -0
  59. package/modules/angular-ui-grid/fonts/ui-grid.woff +0 -0
  60. package/modules/angular-ui-grid/less/animation.less +85 -0
  61. package/modules/angular-ui-grid/less/body.less +84 -0
  62. package/modules/angular-ui-grid/less/cell.less +46 -0
  63. package/modules/angular-ui-grid/less/cellnav.less +29 -0
  64. package/modules/angular-ui-grid/less/core.less +11 -0
  65. package/modules/angular-ui-grid/less/edit.less +27 -0
  66. package/modules/angular-ui-grid/less/elements.less +156 -0
  67. package/modules/angular-ui-grid/less/emptyBaseLayer.less +8 -0
  68. package/modules/angular-ui-grid/less/expandable.less +29 -0
  69. package/modules/angular-ui-grid/less/exporter.less +4 -0
  70. package/modules/angular-ui-grid/less/footer.less +76 -0
  71. package/modules/angular-ui-grid/less/grid.less +86 -0
  72. package/modules/angular-ui-grid/less/grouping.less +5 -0
  73. package/modules/angular-ui-grid/less/header.less +250 -0
  74. package/modules/angular-ui-grid/less/icons.less +151 -0
  75. package/modules/angular-ui-grid/less/importer.less +4 -0
  76. package/modules/angular-ui-grid/less/main.less +2 -0
  77. package/modules/angular-ui-grid/less/menu.less +91 -0
  78. package/modules/angular-ui-grid/less/moveColumns.less +12 -0
  79. package/modules/angular-ui-grid/less/pagination.less +297 -0
  80. package/modules/angular-ui-grid/less/pinning.less +86 -0
  81. package/modules/angular-ui-grid/less/resizeColumns.less +53 -0
  82. package/modules/angular-ui-grid/less/rowEdit.less +19 -0
  83. package/modules/angular-ui-grid/less/rtl.less +67 -0
  84. package/modules/angular-ui-grid/less/selection.less +29 -0
  85. package/modules/angular-ui-grid/less/sorting.less +16 -0
  86. package/modules/angular-ui-grid/less/treeBase.less +6 -0
  87. package/modules/angular-ui-grid/less/treeView.less +8 -0
  88. package/modules/angular-ui-grid/less/validate.less +5 -0
  89. package/modules/angular-ui-grid/less/variables.less +90 -0
  90. package/modules/angular-ui-grid/package.json +144 -0
  91. package/modules/angular-ui-grid/ui-grid.auto-resize.js +69 -0
  92. package/modules/angular-ui-grid/ui-grid.auto-resize.min.js +6 -0
  93. package/modules/angular-ui-grid/ui-grid.cellnav.js +1181 -0
  94. package/modules/angular-ui-grid/ui-grid.cellnav.min.js +6 -0
  95. package/modules/angular-ui-grid/ui-grid.core.js +12737 -0
  96. package/modules/angular-ui-grid/ui-grid.core.min.js +6 -0
  97. package/modules/angular-ui-grid/ui-grid.css +3208 -0
  98. package/modules/angular-ui-grid/ui-grid.edit.js +1325 -0
  99. package/modules/angular-ui-grid/ui-grid.edit.min.js +6 -0
  100. package/modules/angular-ui-grid/ui-grid.empty-base-layer.js +178 -0
  101. package/modules/angular-ui-grid/ui-grid.empty-base-layer.min.js +6 -0
  102. package/modules/angular-ui-grid/ui-grid.expandable.js +651 -0
  103. package/modules/angular-ui-grid/ui-grid.expandable.min.js +6 -0
  104. package/modules/angular-ui-grid/ui-grid.exporter.js +1777 -0
  105. package/modules/angular-ui-grid/ui-grid.exporter.min.js +6 -0
  106. package/modules/angular-ui-grid/ui-grid.grouping.js +1291 -0
  107. package/modules/angular-ui-grid/ui-grid.grouping.min.js +6 -0
  108. package/modules/angular-ui-grid/ui-grid.importer.js +791 -0
  109. package/modules/angular-ui-grid/ui-grid.importer.min.js +6 -0
  110. package/modules/angular-ui-grid/ui-grid.infinite-scroll.js +552 -0
  111. package/modules/angular-ui-grid/ui-grid.infinite-scroll.min.js +6 -0
  112. package/modules/angular-ui-grid/ui-grid.js +30867 -0
  113. package/modules/angular-ui-grid/ui-grid.language.all.js +3214 -0
  114. package/modules/angular-ui-grid/ui-grid.language.all.min.js +6 -0
  115. package/modules/angular-ui-grid/ui-grid.language.ar.js +118 -0
  116. package/modules/angular-ui-grid/ui-grid.language.ar.min.js +6 -0
  117. package/modules/angular-ui-grid/ui-grid.language.bg.js +115 -0
  118. package/modules/angular-ui-grid/ui-grid.language.bg.min.js +6 -0
  119. package/modules/angular-ui-grid/ui-grid.language.cs.js +96 -0
  120. package/modules/angular-ui-grid/ui-grid.language.cs.min.js +6 -0
  121. package/modules/angular-ui-grid/ui-grid.language.da.js +90 -0
  122. package/modules/angular-ui-grid/ui-grid.language.da.min.js +6 -0
  123. package/modules/angular-ui-grid/ui-grid.language.de.js +133 -0
  124. package/modules/angular-ui-grid/ui-grid.language.de.min.js +6 -0
  125. package/modules/angular-ui-grid/ui-grid.language.es-ct.js +133 -0
  126. package/modules/angular-ui-grid/ui-grid.language.es-ct.min.js +6 -0
  127. package/modules/angular-ui-grid/ui-grid.language.es.js +106 -0
  128. package/modules/angular-ui-grid/ui-grid.language.es.min.js +6 -0
  129. package/modules/angular-ui-grid/ui-grid.language.fa.js +93 -0
  130. package/modules/angular-ui-grid/ui-grid.language.fa.min.js +6 -0
  131. package/modules/angular-ui-grid/ui-grid.language.fi.js +76 -0
  132. package/modules/angular-ui-grid/ui-grid.language.fi.min.js +6 -0
  133. package/modules/angular-ui-grid/ui-grid.language.fr.js +128 -0
  134. package/modules/angular-ui-grid/ui-grid.language.fr.min.js +6 -0
  135. package/modules/angular-ui-grid/ui-grid.language.he.js +71 -0
  136. package/modules/angular-ui-grid/ui-grid.language.he.min.js +6 -0
  137. package/modules/angular-ui-grid/ui-grid.language.hy.js +76 -0
  138. package/modules/angular-ui-grid/ui-grid.language.hy.min.js +6 -0
  139. package/modules/angular-ui-grid/ui-grid.language.is.js +118 -0
  140. package/modules/angular-ui-grid/ui-grid.language.is.min.js +6 -0
  141. package/modules/angular-ui-grid/ui-grid.language.it.js +112 -0
  142. package/modules/angular-ui-grid/ui-grid.language.it.min.js +6 -0
  143. package/modules/angular-ui-grid/ui-grid.language.ja.js +118 -0
  144. package/modules/angular-ui-grid/ui-grid.language.ja.min.js +6 -0
  145. package/modules/angular-ui-grid/ui-grid.language.ko.js +77 -0
  146. package/modules/angular-ui-grid/ui-grid.language.ko.min.js +6 -0
  147. package/modules/angular-ui-grid/ui-grid.language.nl.js +91 -0
  148. package/modules/angular-ui-grid/ui-grid.language.nl.min.js +6 -0
  149. package/modules/angular-ui-grid/ui-grid.language.no.js +115 -0
  150. package/modules/angular-ui-grid/ui-grid.language.no.min.js +6 -0
  151. package/modules/angular-ui-grid/ui-grid.language.pl.js +126 -0
  152. package/modules/angular-ui-grid/ui-grid.language.pl.min.js +6 -0
  153. package/modules/angular-ui-grid/ui-grid.language.pt-br.js +133 -0
  154. package/modules/angular-ui-grid/ui-grid.language.pt-br.min.js +6 -0
  155. package/modules/angular-ui-grid/ui-grid.language.pt.js +133 -0
  156. package/modules/angular-ui-grid/ui-grid.language.pt.min.js +6 -0
  157. package/modules/angular-ui-grid/ui-grid.language.ro.js +112 -0
  158. package/modules/angular-ui-grid/ui-grid.language.ro.min.js +6 -0
  159. package/modules/angular-ui-grid/ui-grid.language.rs-lat.js +126 -0
  160. package/modules/angular-ui-grid/ui-grid.language.rs-lat.min.js +6 -0
  161. package/modules/angular-ui-grid/ui-grid.language.ru.js +115 -0
  162. package/modules/angular-ui-grid/ui-grid.language.ru.min.js +6 -0
  163. package/modules/angular-ui-grid/ui-grid.language.sk.js +127 -0
  164. package/modules/angular-ui-grid/ui-grid.language.sk.min.js +6 -0
  165. package/modules/angular-ui-grid/ui-grid.language.sv.js +126 -0
  166. package/modules/angular-ui-grid/ui-grid.language.sv.min.js +6 -0
  167. package/modules/angular-ui-grid/ui-grid.language.ta.js +87 -0
  168. package/modules/angular-ui-grid/ui-grid.language.ta.min.js +6 -0
  169. package/modules/angular-ui-grid/ui-grid.language.tr.js +112 -0
  170. package/modules/angular-ui-grid/ui-grid.language.tr.min.js +6 -0
  171. package/modules/angular-ui-grid/ui-grid.language.ua.js +112 -0
  172. package/modules/angular-ui-grid/ui-grid.language.ua.min.js +6 -0
  173. package/modules/angular-ui-grid/ui-grid.language.zh-cn.js +112 -0
  174. package/modules/angular-ui-grid/ui-grid.language.zh-cn.min.js +6 -0
  175. package/modules/angular-ui-grid/ui-grid.language.zh-tw.js +77 -0
  176. package/modules/angular-ui-grid/ui-grid.language.zh-tw.min.js +6 -0
  177. package/modules/angular-ui-grid/ui-grid.min.css +5 -0
  178. package/modules/angular-ui-grid/ui-grid.min.js +6 -0
  179. package/modules/angular-ui-grid/ui-grid.move-columns.js +582 -0
  180. package/modules/angular-ui-grid/ui-grid.move-columns.min.js +6 -0
  181. package/modules/angular-ui-grid/ui-grid.pagination.js +510 -0
  182. package/modules/angular-ui-grid/ui-grid.pagination.min.js +6 -0
  183. package/modules/angular-ui-grid/ui-grid.pinning.js +281 -0
  184. package/modules/angular-ui-grid/ui-grid.pinning.min.js +6 -0
  185. package/modules/angular-ui-grid/ui-grid.resize-columns.js +574 -0
  186. package/modules/angular-ui-grid/ui-grid.resize-columns.min.js +6 -0
  187. package/modules/angular-ui-grid/ui-grid.row-edit.js +717 -0
  188. package/modules/angular-ui-grid/ui-grid.row-edit.min.js +6 -0
  189. package/modules/angular-ui-grid/ui-grid.saveState.js +831 -0
  190. package/modules/angular-ui-grid/ui-grid.saveState.min.js +6 -0
  191. package/modules/angular-ui-grid/ui-grid.selection.js +1196 -0
  192. package/modules/angular-ui-grid/ui-grid.selection.min.js +6 -0
  193. package/modules/angular-ui-grid/ui-grid.tree-base.js +1743 -0
  194. package/modules/angular-ui-grid/ui-grid.tree-base.min.js +6 -0
  195. package/modules/angular-ui-grid/ui-grid.tree-view.js +218 -0
  196. package/modules/angular-ui-grid/ui-grid.tree-view.min.js +6 -0
  197. package/modules/angular-ui-grid/ui-grid.validate.js +589 -0
  198. package/modules/angular-ui-grid/ui-grid.validate.min.js +6 -0
  199. package/package.json +8 -0
  200. package/polyfills.js +2 -0
  201. package/styles.css +1 -0
@@ -0,0 +1,1291 @@
1
+ /*!
2
+ * ui-grid - v4.12.7 - 2024-04-12
3
+ * http://ui-grid.info/
4
+ * Copyright (c) 2024 ; License: MIT
5
+ */
6
+
7
+ (function () {
8
+ 'use strict';
9
+
10
+ /**
11
+ * @ngdoc overview
12
+ * @name ui.grid.grouping
13
+ * @description
14
+ *
15
+ * # ui.grid.grouping
16
+ *
17
+ * <div class="alert alert-warning" role="alert"><strong>Beta</strong> This feature is ready for testing, but it either hasn't seen a lot of use or has some known bugs.</div>
18
+ *
19
+ * This module provides grouping of rows based on the data in them, similar
20
+ * in concept to excel grouping. You can group multiple columns, resulting in
21
+ * nested grouping.
22
+ *
23
+ * In concept this feature is similar to sorting + grid footer/aggregation, it
24
+ * sorts the data based on the grouped columns, then creates group rows that
25
+ * reflect a break in the data. Each of those group rows can have aggregations for
26
+ * the data within that group.
27
+ *
28
+ * This feature leverages treeBase to provide the tree functionality itself,
29
+ * the key thing this feature does therefore is to set treeLevels on the rows
30
+ * and insert the group headers.
31
+ *
32
+ * Design information:
33
+ * -------------------
34
+ *
35
+ * Each column will get new menu items - group by, and aggregate by. Group by
36
+ * will cause this column to be sorted (if not already), and will move this column
37
+ * to the front of the sorted columns (i.e. grouped columns take precedence over
38
+ * sorted columns). It will respect the sort order already set if there is one,
39
+ * and it will allow the sorting logic to change that sort order, it just forces
40
+ * the column to the front of the sorting. You can group by multiple columns, the
41
+ * logic will add this column to the sorting after any already grouped columns.
42
+ *
43
+ * Once a grouping is defined, grouping logic is added to the rowsProcessors. This
44
+ * will process the rows, identifying a break in the data value, and inserting a grouping row.
45
+ * Grouping rows have specific attributes on them:
46
+ *
47
+ * - internalRow = true: tells us that this isn't a real row, so we can ignore it
48
+ * from any processing that it looking at core data rows. This is used by the core
49
+ * logic (or will be one day), as it's not grouping specific
50
+ * - groupHeader = true: tells us this is a groupHeader. This is used by the grouping logic
51
+ * to know if this is a groupHeader row or not
52
+ *
53
+ * Since the logic is baked into the rowsProcessors, it should get triggered whenever
54
+ * row order or filtering or anything like that is changed. In order to avoid the row instantiation
55
+ * time, and to preserve state across invocations, we hold a cache of the rows that we created
56
+ * last time, and we use them again this time if we can.
57
+ *
58
+ * By default rows are collapsed, which means all data rows have their visible property
59
+ * set to false, and only level 0 group rows are set to visible.
60
+ *
61
+ * <br/>
62
+ * <br/>
63
+ *
64
+ * <div doc-module-components="ui.grid.grouping"></div>
65
+ */
66
+
67
+ var module = angular.module('ui.grid.grouping', ['ui.grid', 'ui.grid.treeBase']);
68
+
69
+ /**
70
+ * @ngdoc object
71
+ * @name ui.grid.grouping.constant:uiGridGroupingConstants
72
+ *
73
+ * @description constants available in grouping module, this includes
74
+ * all the constants declared in the treeBase module (these are manually copied
75
+ * as there isn't an easy way to include constants in another constants file, and
76
+ * we don't want to make users include treeBase)
77
+ *
78
+ */
79
+ module.constant('uiGridGroupingConstants', {
80
+ featureName: "grouping",
81
+ rowHeaderColName: 'treeBaseRowHeaderCol',
82
+ EXPANDED: 'expanded',
83
+ COLLAPSED: 'collapsed',
84
+ aggregation: {
85
+ COUNT: 'count',
86
+ SUM: 'sum',
87
+ MAX: 'max',
88
+ MIN: 'min',
89
+ AVG: 'avg'
90
+ }
91
+ });
92
+
93
+ /**
94
+ * @ngdoc service
95
+ * @name ui.grid.grouping.service:uiGridGroupingService
96
+ *
97
+ * @description Services for grouping features
98
+ */
99
+ module.service('uiGridGroupingService', ['$q', 'uiGridGroupingConstants', 'gridUtil', 'rowSorter', 'GridRow', 'gridClassFactory', 'i18nService', 'uiGridConstants', 'uiGridTreeBaseService',
100
+ function ($q, uiGridGroupingConstants, gridUtil, rowSorter, GridRow, gridClassFactory, i18nService, uiGridConstants, uiGridTreeBaseService) {
101
+ var service = {
102
+ initializeGrid: function (grid, $scope) {
103
+ uiGridTreeBaseService.initializeGrid( grid, $scope );
104
+
105
+ // add feature namespace and any properties to grid for needed
106
+ /**
107
+ * @ngdoc object
108
+ * @name ui.grid.grouping.grid:grouping
109
+ *
110
+ * @description Grid properties and functions added for grouping
111
+ */
112
+ grid.grouping = {};
113
+
114
+ /**
115
+ * @ngdoc property
116
+ * @propertyOf ui.grid.grouping.grid:grouping
117
+ * @name groupHeaderCache
118
+ *
119
+ * @description Cache that holds the group header rows we created last time, we'll
120
+ * reuse these next time, not least because they hold our expanded states.
121
+ *
122
+ * We need to take care with these that they don't become a memory leak, we
123
+ * create a new cache each time using the values from the old cache. This works
124
+ * so long as we're creating group rows for invisible rows as well.
125
+ *
126
+ * The cache is a nested hash, indexed on the value we grouped by. So if we
127
+ * grouped by gender then age, we'd maybe have something like:
128
+ * ```
129
+ * {
130
+ * male: {
131
+ * row: <pointer to the old row>,
132
+ * children: {
133
+ * 22: { row: <pointer to the old row> },
134
+ * 31: { row: <pointer to the old row> }
135
+ * },
136
+ * female: {
137
+ * row: <pointer to the old row>,
138
+ * children: {
139
+ * 28: { row: <pointer to the old row> },
140
+ * 55: { row: <pointer to the old row> }
141
+ * }
142
+ * }
143
+ * ```
144
+ *
145
+ * We create new rows for any missing rows, this means that they come in as collapsed.
146
+ *
147
+ */
148
+ grid.grouping.groupHeaderCache = {};
149
+
150
+ service.defaultGridOptions(grid.options);
151
+
152
+ grid.registerRowsProcessor(service.groupRows, 400);
153
+
154
+ grid.registerColumnBuilder( service.groupingColumnBuilder);
155
+
156
+ grid.registerColumnsProcessor(service.groupingColumnProcessor, 400);
157
+
158
+ /**
159
+ * @ngdoc object
160
+ * @name ui.grid.grouping.api:PublicApi
161
+ *
162
+ * @description Public Api for grouping feature
163
+ */
164
+ var publicApi = {
165
+ events: {
166
+ grouping: {
167
+ /**
168
+ * @ngdoc event
169
+ * @eventOf ui.grid.grouping.api:PublicApi
170
+ * @name aggregationChanged
171
+ * @description raised whenever aggregation is changed, added or removed from a column
172
+ *
173
+ * <pre>
174
+ * gridApi.grouping.on.aggregationChanged(scope,function(col) {})
175
+ * </pre>
176
+ * @param {GridColumn} col the column on which aggregation changed. The aggregation
177
+ * type is available as `col.treeAggregation.type`
178
+ */
179
+ aggregationChanged: {},
180
+ /**
181
+ * @ngdoc event
182
+ * @eventOf ui.grid.grouping.api:PublicApi
183
+ * @name groupingChanged
184
+ * @description raised whenever the grouped columns changes
185
+ *
186
+ * <pre>
187
+ * gridApi.grouping.on.groupingChanged(scope,function(col) {})
188
+ * </pre>
189
+ * @param {GridColumn} col the column on which grouping changed. The new grouping is
190
+ * available as `col.grouping`
191
+ */
192
+ groupingChanged: {}
193
+ }
194
+ },
195
+ methods: {
196
+ grouping: {
197
+ /**
198
+ * @ngdoc function
199
+ * @name getGrouping
200
+ * @methodOf ui.grid.grouping.api:PublicApi
201
+ * @description Get the grouping configuration for this grid,
202
+ * used by the saveState feature. Adds expandedState to the information
203
+ * provided by the internal getGrouping, and removes any aggregations that have a source
204
+ * of grouping (i.e. will be automatically reapplied when we regroup the column)
205
+ * Returned grouping is an object
206
+ * `{ grouping: groupArray, treeAggregations: aggregateArray, expandedState: hash }`
207
+ * where grouping contains an array of objects:
208
+ * `{ field: column.field, colName: column.name, groupPriority: column.grouping.groupPriority }`
209
+ * and aggregations contains an array of objects:
210
+ * `{ field: column.field, colName: column.name, aggregation: column.grouping.aggregation }`
211
+ * and expandedState is a hash of the currently expanded nodes
212
+ *
213
+ * The groupArray will be sorted by groupPriority.
214
+ *
215
+ * @param {boolean} getExpanded whether or not to return the expanded state
216
+ * @returns {object} grouping configuration
217
+ */
218
+ getGrouping: function ( getExpanded ) {
219
+ var grouping = service.getGrouping(grid);
220
+
221
+ grouping.grouping.forEach( function( group ) {
222
+ group.colName = group.col.name;
223
+ delete group.col;
224
+ });
225
+
226
+ grouping.aggregations.forEach( function( aggregation ) {
227
+ aggregation.colName = aggregation.col.name;
228
+ delete aggregation.col;
229
+ });
230
+
231
+ grouping.aggregations = grouping.aggregations.filter( function( aggregation ) {
232
+ return !aggregation.aggregation.source || aggregation.aggregation.source !== 'grouping';
233
+ });
234
+
235
+ if ( getExpanded ) {
236
+ grouping.rowExpandedStates = service.getRowExpandedStates( grid.grouping.groupingHeaderCache );
237
+ }
238
+
239
+ return grouping;
240
+ },
241
+
242
+ /**
243
+ * @ngdoc function
244
+ * @name setGrouping
245
+ * @methodOf ui.grid.grouping.api:PublicApi
246
+ * @description Set the grouping configuration for this grid,
247
+ * used by the saveState feature, but can also be used by any
248
+ * user to specify a combined grouping and aggregation configuration
249
+ * @param {object} config the config you want to apply, in the format
250
+ * provided out by getGrouping
251
+ */
252
+ setGrouping: function ( config ) {
253
+ service.setGrouping(grid, config);
254
+ },
255
+
256
+ /**
257
+ * @ngdoc function
258
+ * @name groupColumn
259
+ * @methodOf ui.grid.grouping.api:PublicApi
260
+ * @description Adds this column to the existing grouping, at the end of the priority order.
261
+ * If the column doesn't have a sort, adds one, by default ASC
262
+ *
263
+ * This column will move to the left of any non-group columns, the
264
+ * move is handled in a columnProcessor, so gets called as part of refresh
265
+ *
266
+ * @param {string} columnName the name of the column we want to group
267
+ */
268
+ groupColumn: function(columnName) {
269
+ var column = grid.getColumn(columnName);
270
+
271
+ service.groupColumn(grid, column);
272
+ },
273
+
274
+ /**
275
+ * @ngdoc function
276
+ * @name ungroupColumn
277
+ * @methodOf ui.grid.grouping.api:PublicApi
278
+ * @description Removes the groupPriority from this column. If the
279
+ * column was previously aggregated the aggregation will come back.
280
+ * The sort will remain.
281
+ *
282
+ * This column will move to the right of any other group columns, the
283
+ * move is handled in a columnProcessor, so gets called as part of refresh
284
+ *
285
+ * @param {string} columnName the name of the column we want to ungroup
286
+ */
287
+ ungroupColumn: function(columnName) {
288
+ var column = grid.getColumn(columnName);
289
+
290
+ service.ungroupColumn(grid, column);
291
+ },
292
+
293
+ /**
294
+ * @ngdoc function
295
+ * @name clearGrouping
296
+ * @methodOf ui.grid.grouping.api:PublicApi
297
+ * @description Clear any grouped columns and any aggregations. Doesn't remove sorting,
298
+ * as we don't know whether that sorting was added by grouping or was there beforehand
299
+ *
300
+ */
301
+ clearGrouping: function() {
302
+ service.clearGrouping(grid);
303
+ },
304
+
305
+ /**
306
+ * @ngdoc function
307
+ * @name aggregateColumn
308
+ * @methodOf ui.grid.grouping.api:PublicApi
309
+ * @description Sets the aggregation type on a column, if the
310
+ * column is currently grouped then it removes the grouping first.
311
+ * If the aggregationDef is null then will result in the aggregation
312
+ * being removed
313
+ *
314
+ * @param {string} columnName the column we want to aggregate
315
+ * @param {string|function} aggregationDef one of the recognised types
316
+ * from uiGridGroupingConstants or a custom aggregation function.
317
+ * @param {string} aggregationLabel (optional) The label to use for this aggregation.
318
+ */
319
+ aggregateColumn: function(columnName, aggregationDef, aggregationLabel) {
320
+ var column = grid.getColumn(columnName);
321
+
322
+ service.aggregateColumn(grid, column, aggregationDef, aggregationLabel);
323
+ }
324
+ }
325
+ }
326
+ };
327
+
328
+ grid.api.registerEventsFromObject(publicApi.events);
329
+
330
+ grid.api.registerMethodsFromObject(publicApi.methods);
331
+
332
+ grid.api.core.on.sortChanged($scope, service.tidyPriorities);
333
+ },
334
+
335
+ defaultGridOptions: function (gridOptions) {
336
+ // default option to true unless it was explicitly set to false
337
+ /**
338
+ * @ngdoc object
339
+ * @name ui.grid.grouping.api:GridOptions
340
+ *
341
+ * @description GridOptions for grouping feature, these are available to be
342
+ * set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
343
+ */
344
+
345
+ /**
346
+ * @ngdoc object
347
+ * @name enableGrouping
348
+ * @propertyOf ui.grid.grouping.api:GridOptions
349
+ * @description Enable row grouping for entire grid.
350
+ * <br/>Defaults to true
351
+ */
352
+ gridOptions.enableGrouping = gridOptions.enableGrouping !== false;
353
+
354
+ /**
355
+ * @ngdoc object
356
+ * @name groupingShowCounts
357
+ * @propertyOf ui.grid.grouping.api:GridOptions
358
+ * @description shows counts on the groupHeader rows. Not that if you are using a cellFilter or a
359
+ * sortingAlgorithm which relies on a specific format or data type, showing counts may cause that
360
+ * to break, since the group header rows will always be a string with groupingShowCounts enabled.
361
+ * <br/>Defaults to true except on columns of types 'date' and 'object'
362
+ */
363
+ gridOptions.groupingShowCounts = gridOptions.groupingShowCounts !== false;
364
+
365
+ /**
366
+ * @ngdoc object
367
+ * @name groupingNullLabel
368
+ * @propertyOf ui.grid.grouping.api:GridOptions
369
+ * @description The string to use for the grouping header row label on rows which contain a null or undefined value in the grouped column.
370
+ * <br/>Defaults to "Null"
371
+ */
372
+ gridOptions.groupingNullLabel = typeof(gridOptions.groupingNullLabel) === 'undefined' ? 'Null' : gridOptions.groupingNullLabel;
373
+
374
+ /**
375
+ * @ngdoc object
376
+ * @name enableGroupHeaderSelection
377
+ * @propertyOf ui.grid.grouping.api:GridOptions
378
+ * @description Allows group header rows to be selected.
379
+ * <br/>Defaults to false
380
+ */
381
+ gridOptions.enableGroupHeaderSelection = gridOptions.enableGroupHeaderSelection === true;
382
+ },
383
+
384
+
385
+ /**
386
+ * @ngdoc function
387
+ * @name groupingColumnBuilder
388
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
389
+ * @description Sets the grouping defaults based on the columnDefs
390
+ *
391
+ * @param {object} colDef columnDef we're basing on
392
+ * @param {GridColumn} col the column we're to update
393
+ * @param {object} gridOptions the options we should use
394
+ * @returns {promise} promise for the builder - actually we do it all inline so it's immediately resolved
395
+ */
396
+ groupingColumnBuilder: function (colDef, col, gridOptions) {
397
+ /**
398
+ * @ngdoc object
399
+ * @name ui.grid.grouping.api:ColumnDef
400
+ *
401
+ * @description ColumnDef for grouping feature, these are available to be
402
+ * set using the ui-grid {@link ui.grid.class:GridOptions.columnDef gridOptions.columnDefs}
403
+ */
404
+
405
+ /**
406
+ * @ngdoc object
407
+ * @name enableGrouping
408
+ * @propertyOf ui.grid.grouping.api:ColumnDef
409
+ * @description Enable grouping on this column
410
+ * <br/>Defaults to true.
411
+ */
412
+ if (colDef.enableGrouping === false) {
413
+ return;
414
+ }
415
+
416
+ /**
417
+ * @ngdoc object
418
+ * @name grouping
419
+ * @propertyOf ui.grid.grouping.api:ColumnDef
420
+ * @description Set the grouping for a column. Format is:
421
+ * ```
422
+ * {
423
+ * groupPriority: <number, starts at 0, if less than 0 or undefined then we're aggregating in this column>
424
+ * }
425
+ * ```
426
+ *
427
+ * **Note that aggregation used to be included in grouping, but is now separately set on the column via treeAggregation
428
+ * setting in treeBase**
429
+ *
430
+ * We group in the priority order given, this will also put these columns to the high order of the sort irrespective
431
+ * of the sort priority given them. If there is no sort defined then we sort ascending, if there is a sort defined then
432
+ * we use that sort.
433
+ *
434
+ * If the groupPriority is undefined or less than 0, then we expect to be aggregating, and we look at the
435
+ * aggregation types to determine what sort of aggregation we can do. Values are in the constants file, but
436
+ * include SUM, COUNT, MAX, MIN
437
+ *
438
+ * groupPriorities should generally be sequential, if they're not then the next time getGrouping is called
439
+ * we'll renumber them to be sequential.
440
+ * <br/>Defaults to undefined.
441
+ */
442
+
443
+ if ( typeof(col.grouping) === 'undefined' && typeof(colDef.grouping) !== 'undefined') {
444
+ col.grouping = angular.copy(colDef.grouping);
445
+ if ( typeof(col.grouping.groupPriority) !== 'undefined' && col.grouping.groupPriority > -1 ) {
446
+ col.treeAggregationFn = uiGridTreeBaseService.nativeAggregations()[uiGridGroupingConstants.aggregation.COUNT].aggregationFn;
447
+ col.treeAggregationFinalizerFn = service.groupedFinalizerFn;
448
+ }
449
+ } else if (typeof(col.grouping) === 'undefined') {
450
+ col.grouping = {};
451
+ }
452
+
453
+ if (typeof(col.grouping) !== 'undefined' && typeof(col.grouping.groupPriority) !== 'undefined' && col.grouping.groupPriority >= 0) {
454
+ col.suppressRemoveSort = true;
455
+ }
456
+
457
+ var groupColumn = {
458
+ name: 'ui.grid.grouping.group',
459
+ title: i18nService.get().grouping.group,
460
+ icon: 'ui-grid-icon-indent-right',
461
+ shown: function () {
462
+ return typeof(this.context.col.grouping) === 'undefined' ||
463
+ typeof(this.context.col.grouping.groupPriority) === 'undefined' ||
464
+ this.context.col.grouping.groupPriority < 0;
465
+ },
466
+ action: function () {
467
+ service.groupColumn( this.context.col.grid, this.context.col );
468
+ }
469
+ };
470
+
471
+ var ungroupColumn = {
472
+ name: 'ui.grid.grouping.ungroup',
473
+ title: i18nService.get().grouping.ungroup,
474
+ icon: 'ui-grid-icon-indent-left',
475
+ shown: function () {
476
+ return typeof(this.context.col.grouping) !== 'undefined' &&
477
+ typeof(this.context.col.grouping.groupPriority) !== 'undefined' &&
478
+ this.context.col.grouping.groupPriority >= 0;
479
+ },
480
+ action: function () {
481
+ service.ungroupColumn( this.context.col.grid, this.context.col );
482
+ }
483
+ };
484
+
485
+ var aggregateRemove = {
486
+ name: 'ui.grid.grouping.aggregateRemove',
487
+ title: i18nService.get().grouping.aggregate_remove,
488
+ shown: function () {
489
+ return typeof(this.context.col.treeAggregationFn) !== 'undefined';
490
+ },
491
+ action: function () {
492
+ service.aggregateColumn( this.context.col.grid, this.context.col, null);
493
+ }
494
+ };
495
+
496
+ // generic adder for the aggregation menus, which follow a pattern
497
+ var addAggregationMenu = function(type, title) {
498
+ title = title || i18nService.get().grouping['aggregate_' + type] || type;
499
+ var menuItem = {
500
+ name: 'ui.grid.grouping.aggregate' + type,
501
+ title: title,
502
+ shown: function () {
503
+ return typeof(this.context.col.treeAggregation) === 'undefined' ||
504
+ typeof(this.context.col.treeAggregation.type) === 'undefined' ||
505
+ this.context.col.treeAggregation.type !== type;
506
+ },
507
+ action: function () {
508
+ service.aggregateColumn( this.context.col.grid, this.context.col, type);
509
+ }
510
+ };
511
+
512
+ if (!gridUtil.arrayContainsObjectWithProperty(col.menuItems, 'name', 'ui.grid.grouping.aggregate' + type)) {
513
+ col.menuItems.push(menuItem);
514
+ }
515
+ };
516
+
517
+ /**
518
+ * @ngdoc object
519
+ * @name groupingShowGroupingMenu
520
+ * @propertyOf ui.grid.grouping.api:ColumnDef
521
+ * @description Show the grouping (group and ungroup items) menu on this column
522
+ * <br/>Defaults to true.
523
+ */
524
+ if ( col.colDef.groupingShowGroupingMenu !== false ) {
525
+ if (!gridUtil.arrayContainsObjectWithProperty(col.menuItems, 'name', 'ui.grid.grouping.group')) {
526
+ col.menuItems.push(groupColumn);
527
+ }
528
+
529
+ if (!gridUtil.arrayContainsObjectWithProperty(col.menuItems, 'name', 'ui.grid.grouping.ungroup')) {
530
+ col.menuItems.push(ungroupColumn);
531
+ }
532
+ }
533
+
534
+
535
+ /**
536
+ * @ngdoc object
537
+ * @name groupingShowAggregationMenu
538
+ * @propertyOf ui.grid.grouping.api:ColumnDef
539
+ * @description Show the aggregation menu on this column
540
+ * <br/>Defaults to true.
541
+ */
542
+ if ( col.colDef.groupingShowAggregationMenu !== false ) {
543
+ angular.forEach(uiGridTreeBaseService.nativeAggregations(), function(aggregationDef, name) {
544
+ addAggregationMenu(name);
545
+ });
546
+ angular.forEach(gridOptions.treeCustomAggregations, function(aggregationDef, name) {
547
+ addAggregationMenu(name, aggregationDef.menuTitle);
548
+ });
549
+
550
+ if (!gridUtil.arrayContainsObjectWithProperty(col.menuItems, 'name', 'ui.grid.grouping.aggregateRemove')) {
551
+ col.menuItems.push(aggregateRemove);
552
+ }
553
+ }
554
+ },
555
+
556
+
557
+
558
+
559
+ /**
560
+ * @ngdoc function
561
+ * @name groupingColumnProcessor
562
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
563
+ * @description Moves the columns around based on which are grouped
564
+ *
565
+ * @param {array} columns the columns to consider rendering
566
+ * @param {array} rows the grid rows, which we don't use but are passed to us
567
+ * @returns {array} updated columns array
568
+ */
569
+ groupingColumnProcessor: function( columns, rows ) {
570
+ columns = service.moveGroupColumns(this, columns, rows);
571
+ return columns;
572
+ },
573
+
574
+ /**
575
+ * @ngdoc function
576
+ * @name groupedFinalizerFn
577
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
578
+ * @description Used on group columns to display the rendered value and optionally
579
+ * display the count of rows.
580
+ *
581
+ * @param {aggregation} aggregation The aggregation entity for a grouped column
582
+ */
583
+ groupedFinalizerFn: function( aggregation ) {
584
+ var col = this;
585
+
586
+ if ( typeof(aggregation.groupVal) !== 'undefined') {
587
+ aggregation.rendered = aggregation.groupVal;
588
+ if ( col.grid.options.groupingShowCounts && col.colDef.type !== 'date' && col.colDef.type !== 'object' ) {
589
+ aggregation.rendered += (' (' + aggregation.value + ')');
590
+ }
591
+ } else {
592
+ aggregation.rendered = null;
593
+ }
594
+ },
595
+
596
+ /**
597
+ * @ngdoc function
598
+ * @name moveGroupColumns
599
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
600
+ * @description Moves the column order so that the grouped columns are lined up
601
+ * to the left (well, unless you're RTL, then it's the right). By doing this in
602
+ * the columnsProcessor, we make it transient - when the column is ungrouped it'll
603
+ * go back to where it was.
604
+ *
605
+ * Does nothing if the option `moveGroupColumns` is set to false.
606
+ *
607
+ * @param {Grid} grid grid object
608
+ * @param {array} columns the columns that we should process/move
609
+ * @returns {array} updated columns
610
+ */
611
+ moveGroupColumns: function( grid, columns ) {
612
+ if ( grid.options.moveGroupColumns === false) {
613
+ return columns;
614
+ }
615
+
616
+ columns.forEach(function(column, index) {
617
+ // position used to make stable sort in moveGroupColumns
618
+ column.groupingPosition = index;
619
+ });
620
+
621
+ columns.sort(function(a, b) {
622
+ var a_group, b_group;
623
+
624
+ if (a.isRowHeader) {
625
+ a_group = a.headerPriority;
626
+ }
627
+ else if ( typeof(a.grouping) === 'undefined' || typeof(a.grouping.groupPriority) === 'undefined' || a.grouping.groupPriority < 0) {
628
+ a_group = null;
629
+ }
630
+ else {
631
+ a_group = a.grouping.groupPriority;
632
+ }
633
+
634
+ if (b.isRowHeader) {
635
+ b_group = b.headerPriority;
636
+ }
637
+ else if ( typeof(b.grouping) === 'undefined' || typeof(b.grouping.groupPriority) === 'undefined' || b.grouping.groupPriority < 0) {
638
+ b_group = null;
639
+ }
640
+ else {
641
+ b_group = b.grouping.groupPriority;
642
+ }
643
+
644
+ // groups get sorted to the top
645
+ if ( a_group !== null && b_group === null) { return -1; }
646
+ if ( b_group !== null && a_group === null) { return 1; }
647
+ if ( a_group !== null && b_group !== null) {return a_group - b_group; }
648
+
649
+ return a.groupingPosition - b.groupingPosition;
650
+ });
651
+
652
+ columns.forEach( function(column) {
653
+ delete column.groupingPosition;
654
+ });
655
+
656
+ return columns;
657
+ },
658
+
659
+
660
+ /**
661
+ * @ngdoc function
662
+ * @name groupColumn
663
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
664
+ * @description Adds this column to the existing grouping, at the end of the priority order.
665
+ * If the column doesn't have a sort, adds one, by default ASC
666
+ *
667
+ * This column will move to the left of any non-group columns, the
668
+ * move is handled in a columnProcessor, so gets called as part of refresh
669
+ *
670
+ * @param {Grid} grid grid object
671
+ * @param {GridColumn} column the column we want to group
672
+ */
673
+ groupColumn: function( grid, column) {
674
+ if ( typeof(column.grouping) === 'undefined' ) {
675
+ column.grouping = {};
676
+ }
677
+
678
+ // set the group priority to the next number in the hierarchy
679
+ var existingGrouping = service.getGrouping( grid );
680
+ column.grouping.groupPriority = existingGrouping.grouping.length;
681
+
682
+ // save sort in order to restore it when column is ungrouped
683
+ column.previousSort = angular.copy(column.sort);
684
+
685
+ // add sort if not present
686
+ if ( !column.sort ) {
687
+ column.sort = { direction: uiGridConstants.ASC };
688
+ } else if ( typeof(column.sort.direction) === 'undefined' || column.sort.direction === null ) {
689
+ column.sort.direction = uiGridConstants.ASC;
690
+ }
691
+
692
+ column.treeAggregation = { type: uiGridGroupingConstants.aggregation.COUNT, source: 'grouping' };
693
+
694
+ if ( column.colDef && angular.isFunction(column.colDef.customTreeAggregationFn) ) {
695
+ column.treeAggregationFn = column.colDef.customTreeAggregationFn;
696
+ } else {
697
+ column.treeAggregationFn = uiGridTreeBaseService.nativeAggregations()[uiGridGroupingConstants.aggregation.COUNT].aggregationFn;
698
+ }
699
+
700
+ column.treeAggregationFinalizerFn = service.groupedFinalizerFn;
701
+
702
+ grid.api.grouping.raise.groupingChanged(column);
703
+ // This indirectly calls service.tidyPriorities( grid );
704
+ grid.api.core.raise.sortChanged(grid, grid.getColumnSorting());
705
+
706
+ grid.queueGridRefresh();
707
+ },
708
+
709
+
710
+ /**
711
+ * @ngdoc function
712
+ * @name ungroupColumn
713
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
714
+ * @description Removes the groupPriority from this column. If the
715
+ * column was previously aggregated the aggregation will come back.
716
+ * The sort will remain.
717
+ *
718
+ * This column will move to the right of any other group columns, the
719
+ * move is handled in a columnProcessor, so gets called as part of refresh
720
+ *
721
+ * @param {Grid} grid grid object
722
+ * @param {GridColumn} column the column we want to ungroup
723
+ */
724
+ ungroupColumn: function( grid, column) {
725
+ if ( typeof(column.grouping) === 'undefined' ) {
726
+ return;
727
+ }
728
+
729
+ delete column.grouping.groupPriority;
730
+ delete column.treeAggregation;
731
+ delete column.customTreeAggregationFinalizer;
732
+
733
+ if (column.previousSort) {
734
+ column.sort = column.previousSort;
735
+ delete column.previousSort;
736
+ }
737
+
738
+ service.tidyPriorities( grid );
739
+
740
+ grid.api.grouping.raise.groupingChanged(column);
741
+ grid.api.core.raise.sortChanged(grid, grid.getColumnSorting());
742
+
743
+ grid.queueGridRefresh();
744
+ },
745
+
746
+ /**
747
+ * @ngdoc function
748
+ * @name aggregateColumn
749
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
750
+ * @description Sets the aggregation type on a column, if the
751
+ * column is currently grouped then it removes the grouping first.
752
+ *
753
+ * @param {Grid} grid grid object
754
+ * @param {GridColumn} column the column we want to aggregate
755
+ * @param {string} aggregationType of the recognised types from uiGridGroupingConstants or one of the custom aggregations from gridOptions
756
+ * @param {string} aggregationLabel to be used instead of the default label. If empty string is passed, label is omitted
757
+ */
758
+ aggregateColumn: function( grid, column, aggregationType, aggregationLabel ) {
759
+ if (typeof(column.grouping) !== 'undefined' && typeof(column.grouping.groupPriority) !== 'undefined' && column.grouping.groupPriority >= 0) {
760
+ service.ungroupColumn( grid, column );
761
+ }
762
+
763
+ var aggregationDef = {};
764
+
765
+ if ( typeof(grid.options.treeCustomAggregations[aggregationType]) !== 'undefined' ) {
766
+ aggregationDef = grid.options.treeCustomAggregations[aggregationType];
767
+ } else if ( typeof(uiGridTreeBaseService.nativeAggregations()[aggregationType]) !== 'undefined' ) {
768
+ aggregationDef = uiGridTreeBaseService.nativeAggregations()[aggregationType];
769
+ }
770
+
771
+ column.treeAggregation = {
772
+ type: aggregationType,
773
+ label: ( typeof aggregationLabel === 'string') ?
774
+ aggregationLabel :
775
+ i18nService.get().aggregation[aggregationDef.label] || aggregationDef.label
776
+ };
777
+ column.treeAggregationFn = aggregationDef.aggregationFn;
778
+ column.treeAggregationFinalizerFn = aggregationDef.finalizerFn;
779
+
780
+ grid.api.grouping.raise.aggregationChanged(column);
781
+
782
+ grid.queueGridRefresh();
783
+ },
784
+
785
+
786
+ /**
787
+ * @ngdoc function
788
+ * @name setGrouping
789
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
790
+ * @description Set the grouping based on a config object, used by the save state feature
791
+ * (more specifically, by the restore function in that feature )
792
+ *
793
+ * @param {Grid} grid grid object
794
+ * @param {object} config the config we want to set, same format as that returned by getGrouping
795
+ */
796
+ setGrouping: function ( grid, config ) {
797
+ if ( typeof(config) === 'undefined' ) {
798
+ return;
799
+ }
800
+
801
+ // first remove any existing grouping
802
+ service.clearGrouping(grid);
803
+
804
+ if ( config.grouping && config.grouping.length && config.grouping.length > 0 ) {
805
+ config.grouping.forEach( function( group ) {
806
+ var col = grid.getColumn(group.colName);
807
+
808
+ if ( col ) {
809
+ service.groupColumn( grid, col );
810
+ }
811
+ });
812
+ }
813
+
814
+ if ( config.aggregations && config.aggregations.length ) {
815
+ config.aggregations.forEach( function( aggregation ) {
816
+ var col = grid.getColumn(aggregation.colName);
817
+
818
+ if ( col ) {
819
+ service.aggregateColumn( grid, col, aggregation.aggregation.type );
820
+ }
821
+ });
822
+ }
823
+
824
+ if ( config.rowExpandedStates ) {
825
+ service.applyRowExpandedStates( grid.grouping.groupingHeaderCache, config.rowExpandedStates );
826
+ }
827
+ },
828
+
829
+
830
+ /**
831
+ * @ngdoc function
832
+ * @name clearGrouping
833
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
834
+ * @description Clear any grouped columns and any aggregations. Doesn't remove sorting,
835
+ * as we don't know whether that sorting was added by grouping or was there beforehand
836
+ *
837
+ * @param {Grid} grid grid object
838
+ */
839
+ clearGrouping: function( grid ) {
840
+ var currentGrouping = service.getGrouping(grid);
841
+
842
+ if ( currentGrouping.grouping.length > 0 ) {
843
+ currentGrouping.grouping.forEach( function( group ) {
844
+ if (!group.col) {
845
+ // should have a group.colName if there's no col
846
+ group.col = grid.getColumn(group.colName);
847
+ }
848
+ service.ungroupColumn(grid, group.col);
849
+ });
850
+ }
851
+
852
+ if ( currentGrouping.aggregations.length > 0 ) {
853
+ currentGrouping.aggregations.forEach( function( aggregation ) {
854
+ if (!aggregation.col) {
855
+ // should have a group.colName if there's no col
856
+ aggregation.col = grid.getColumn(aggregation.colName);
857
+ }
858
+ service.aggregateColumn(grid, aggregation.col, null);
859
+ });
860
+ }
861
+ },
862
+
863
+
864
+ /**
865
+ * @ngdoc function
866
+ * @name tidyPriorities
867
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
868
+ * @description Renumbers groupPriority and sortPriority such that
869
+ * groupPriority is contiguous, and sortPriority either matches
870
+ * groupPriority (for group columns), and otherwise is contiguous and
871
+ * higher than groupPriority.
872
+ *
873
+ * @param {Grid} grid grid object
874
+ */
875
+ tidyPriorities: function( grid ) {
876
+ // if we're called from sortChanged, grid is in this, not passed as param, the param can be a column or undefined
877
+ if ( ( typeof(grid) === 'undefined' || typeof(grid.grid) !== 'undefined' ) && typeof(this.grid) !== 'undefined' ) {
878
+ grid = this.grid;
879
+ }
880
+
881
+ var groupArray = [],
882
+ sortArray = [];
883
+
884
+ grid.columns.forEach( function(column, index) {
885
+ if ( typeof(column.grouping) !== 'undefined' && typeof(column.grouping.groupPriority) !== 'undefined' && column.grouping.groupPriority >= 0) {
886
+ groupArray.push(column);
887
+ }
888
+ else if ( typeof(column.sort) !== 'undefined' && typeof(column.sort.priority) !== 'undefined' && column.sort.priority >= 0) {
889
+ sortArray.push(column);
890
+ }
891
+ });
892
+
893
+ groupArray.sort(function(a, b) { return a.grouping.groupPriority - b.grouping.groupPriority; });
894
+ groupArray.forEach( function(column, index) {
895
+ column.grouping.groupPriority = index;
896
+ column.suppressRemoveSort = true;
897
+ if ( typeof(column.sort) === 'undefined') {
898
+ column.sort = {};
899
+ }
900
+ column.sort.priority = index;
901
+ });
902
+
903
+ var i = groupArray.length;
904
+
905
+ sortArray.sort(function(a, b) { return a.sort.priority - b.sort.priority; });
906
+ sortArray.forEach(function(column) {
907
+ column.sort.priority = i;
908
+ column.suppressRemoveSort = column.colDef.suppressRemoveSort;
909
+ i++;
910
+ });
911
+ },
912
+
913
+ /**
914
+ * @ngdoc function
915
+ * @name groupRows
916
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
917
+ * @description The rowProcessor that creates the groupHeaders (i.e. does
918
+ * the actual grouping).
919
+ *
920
+ * Assumes it is always called after the sorting processor, guaranteed by the priority setting
921
+ *
922
+ * Processes all the rows in order, inserting a groupHeader row whenever there is a change
923
+ * in value of a grouped row, based on the sortAlgorithm used for the column. The group header row
924
+ * is looked up in the groupHeaderCache, and used from there if there is one. The entity is reset
925
+ * to {} if one is found.
926
+ *
927
+ * As it processes it maintains a `processingState` array. This records, for each level of grouping we're
928
+ * working with, the following information:
929
+ * ```
930
+ * {
931
+ * fieldName: name,
932
+ * col: col,
933
+ * initialised: boolean,
934
+ * currentValue: value,
935
+ * currentRow: gridRow,
936
+ * }
937
+ * ```
938
+ * We look for changes in the currentValue at any of the levels. Where we find a change we:
939
+ *
940
+ * - create a new groupHeader row in the array
941
+ *
942
+ * @param {array} renderableRows the rows we want to process, usually the output from the previous rowProcessor
943
+ * @returns {array} the updated rows, including our new group rows
944
+ */
945
+ groupRows: function( renderableRows ) {
946
+ if (renderableRows.length === 0) {
947
+ return renderableRows;
948
+ }
949
+
950
+ var grid = this;
951
+ grid.grouping.oldGroupingHeaderCache = grid.grouping.groupingHeaderCache || {};
952
+ grid.grouping.groupingHeaderCache = {};
953
+
954
+ var processingState = service.initialiseProcessingState( grid );
955
+
956
+ // processes each of the fields we are grouping by, checks if the value has changed and inserts a groupHeader
957
+ // Broken out as shouldn't create functions in a loop.
958
+ var updateProcessingState = function( groupFieldState, stateIndex ) {
959
+ var fieldValue = grid.getCellValue(row, groupFieldState.col);
960
+
961
+ // look for change of value - and insert a header
962
+ if ( !groupFieldState.initialised || rowSorter.getSortFn(groupFieldState.col)(fieldValue, groupFieldState.currentValue) !== 0 ) {
963
+ service.insertGroupHeader( grid, renderableRows, i, processingState, stateIndex );
964
+ i++;
965
+ }
966
+ };
967
+
968
+ // use a for loop because it's tolerant of the array length changing whilst we go - we can
969
+ // manipulate the iterator when we insert groupHeader rows
970
+ for (var i = 0; i < renderableRows.length; i++ ) {
971
+ var row = renderableRows[i];
972
+
973
+ if ( row.visible ) {
974
+ processingState.forEach( updateProcessingState );
975
+ }
976
+ }
977
+
978
+ delete grid.grouping.oldGroupingHeaderCache;
979
+ return renderableRows;
980
+ },
981
+
982
+
983
+ /**
984
+ * @ngdoc function
985
+ * @name initialiseProcessingState
986
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
987
+ * @description Creates the processing state array that is used
988
+ * for groupRows.
989
+ *
990
+ * @param {Grid} grid grid object
991
+ * @returns {array} an array in the format described in the groupRows method,
992
+ * initialised with blank values
993
+ */
994
+ initialiseProcessingState: function( grid ) {
995
+ var processingState = [];
996
+ var columnSettings = service.getGrouping( grid );
997
+
998
+ columnSettings.grouping.forEach( function( groupItem, index) {
999
+ processingState.push({
1000
+ fieldName: groupItem.field,
1001
+ col: groupItem.col,
1002
+ initialised: false,
1003
+ currentValue: null,
1004
+ currentRow: null
1005
+ });
1006
+ });
1007
+
1008
+ return processingState;
1009
+ },
1010
+
1011
+
1012
+ /**
1013
+ * @ngdoc function
1014
+ * @name getGrouping
1015
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
1016
+ * @description Get the grouping settings from the columns. As a side effect
1017
+ * this always renumbers the grouping starting at 0
1018
+ * @param {Grid} grid grid object
1019
+ * @returns {array} an array of the group fields, in order of priority
1020
+ */
1021
+ getGrouping: function( grid ) {
1022
+ var groupArray = [],
1023
+ aggregateArray = [];
1024
+
1025
+ // get all the grouping
1026
+ grid.columns.forEach(function(column) {
1027
+ if ( column.grouping ) {
1028
+ if ( typeof(column.grouping.groupPriority) !== 'undefined' && column.grouping.groupPriority >= 0) {
1029
+ groupArray.push({ field: column.field, col: column, groupPriority: column.grouping.groupPriority, grouping: column.grouping });
1030
+ }
1031
+ }
1032
+ if ( column.treeAggregation && column.treeAggregation.type ) {
1033
+ aggregateArray.push({ field: column.field, col: column, aggregation: column.treeAggregation });
1034
+ }
1035
+ });
1036
+
1037
+ // sort grouping into priority order
1038
+ groupArray.sort( function(a, b) {
1039
+ return a.groupPriority - b.groupPriority;
1040
+ });
1041
+
1042
+ // renumber the priority in case it was somewhat messed up, then remove the grouping reference
1043
+ groupArray.forEach( function( group, index) {
1044
+ group.grouping.groupPriority = index;
1045
+ group.groupPriority = index;
1046
+ delete group.grouping;
1047
+ });
1048
+
1049
+ return { grouping: groupArray, aggregations: aggregateArray };
1050
+ },
1051
+
1052
+
1053
+ /**
1054
+ * @ngdoc function
1055
+ * @name insertGroupHeader
1056
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
1057
+ * @description Create a group header row, and link it to the various configuration
1058
+ * items that we use.
1059
+ *
1060
+ * Look for the row in the oldGroupingHeaderCache, write the row into the new groupingHeaderCache.
1061
+ *
1062
+ * @param {Grid} grid grid object
1063
+ * @param {array} renderableRows the rows that we are processing
1064
+ * @param {number} rowIndex the row we were up to processing
1065
+ * @param {array} processingState the current processing state
1066
+ * @param {number} stateIndex the processing state item that we were on when we triggered a new group header -
1067
+ * i.e. the column that we want to create a header for
1068
+ */
1069
+ insertGroupHeader: function( grid, renderableRows, rowIndex, processingState, stateIndex ) {
1070
+ // set the value that caused the end of a group into the header row and the processing state
1071
+ var col = processingState[stateIndex].col,
1072
+ newValue = grid.getCellValue(renderableRows[rowIndex], col),
1073
+ newDisplayValue = newValue;
1074
+
1075
+ if ( typeof(newValue) === 'undefined' || newValue === null ) {
1076
+ newDisplayValue = grid.options.groupingNullLabel;
1077
+ }
1078
+
1079
+ function getKeyAsValueForCacheMap(key) {
1080
+ return angular.isObject(key) ? JSON.stringify(key) : key;
1081
+ }
1082
+
1083
+ var cacheItem = grid.grouping.oldGroupingHeaderCache;
1084
+
1085
+ for ( var i = 0; i < stateIndex; i++ ) {
1086
+ if ( cacheItem && cacheItem[getKeyAsValueForCacheMap(processingState[i].currentValue)] ) {
1087
+ cacheItem = cacheItem[getKeyAsValueForCacheMap(processingState[i].currentValue)].children;
1088
+ }
1089
+ }
1090
+
1091
+ var headerRow;
1092
+
1093
+ if ( cacheItem && cacheItem[getKeyAsValueForCacheMap(newValue)]) {
1094
+ headerRow = cacheItem[getKeyAsValueForCacheMap(newValue)].row;
1095
+ headerRow.entity = {};
1096
+ } else {
1097
+ headerRow = new GridRow( {}, null, grid );
1098
+ gridClassFactory.rowTemplateAssigner.call(grid, headerRow);
1099
+ }
1100
+
1101
+ headerRow.entity['$$' + processingState[stateIndex].col.uid] = { groupVal: newDisplayValue };
1102
+ headerRow.treeLevel = stateIndex;
1103
+ headerRow.groupHeader = true;
1104
+ headerRow.internalRow = true;
1105
+ headerRow.enableCellEdit = false;
1106
+ headerRow.enableSelection = grid.options.enableGroupHeaderSelection;
1107
+ processingState[stateIndex].initialised = true;
1108
+ processingState[stateIndex].currentValue = newValue;
1109
+ processingState[stateIndex].currentRow = headerRow;
1110
+
1111
+ // set all processing states below this one to not be initialised - change of this state
1112
+ // means all those need to start again
1113
+ service.finaliseProcessingState( processingState, stateIndex + 1);
1114
+
1115
+ // insert our new header row
1116
+ renderableRows.splice(rowIndex, 0, headerRow);
1117
+
1118
+ // add our new header row to the cache
1119
+ cacheItem = grid.grouping.groupingHeaderCache;
1120
+ for ( i = 0; i < stateIndex; i++ ) {
1121
+ cacheItem = cacheItem[getKeyAsValueForCacheMap(processingState[i].currentValue)].children;
1122
+ }
1123
+ cacheItem[getKeyAsValueForCacheMap(newValue)] = { row: headerRow, children: {} };
1124
+ },
1125
+
1126
+
1127
+ /**
1128
+ * @ngdoc function
1129
+ * @name finaliseProcessingState
1130
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
1131
+ * @description Set all processing states lower than the one that had a break in value to
1132
+ * no longer be initialised. Render the counts into the entity ready for display.
1133
+ *
1134
+ * @param {array} processingState the current processing state
1135
+ * @param {number} stateIndex the processing state item that we were on when we triggered a new group header, all
1136
+ * processing states after this need to be finalised
1137
+ */
1138
+ finaliseProcessingState: function( processingState, stateIndex ) {
1139
+ for ( var i = stateIndex; i < processingState.length; i++) {
1140
+ processingState[i].initialised = false;
1141
+ processingState[i].currentRow = null;
1142
+ processingState[i].currentValue = null;
1143
+ }
1144
+ },
1145
+
1146
+
1147
+ /**
1148
+ * @ngdoc function
1149
+ * @name getRowExpandedStates
1150
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
1151
+ * @description Extract the groupHeaderCache hash, pulling out only the states.
1152
+ *
1153
+ * The example below shows a grid that is grouped by gender then age
1154
+ *
1155
+ * <pre>
1156
+ * {
1157
+ * male: {
1158
+ * state: 'expanded',
1159
+ * children: {
1160
+ * 22: { state: 'expanded' },
1161
+ * 30: { state: 'collapsed' }
1162
+ * }
1163
+ * },
1164
+ * female: {
1165
+ * state: 'expanded',
1166
+ * children: {
1167
+ * 28: { state: 'expanded' },
1168
+ * 55: { state: 'collapsed' }
1169
+ * }
1170
+ * }
1171
+ * }
1172
+ * </pre>
1173
+ *
1174
+ * @param {object} treeChildren The tree children elements object
1175
+ * @returns {object} the expanded states as an object
1176
+ */
1177
+ getRowExpandedStates: function(treeChildren) {
1178
+ if ( typeof(treeChildren) === 'undefined' ) {
1179
+ return {};
1180
+ }
1181
+
1182
+ var newChildren = {};
1183
+
1184
+ angular.forEach( treeChildren, function( value, key ) {
1185
+ newChildren[key] = { state: value.row.treeNode.state };
1186
+ if ( value.children ) {
1187
+ newChildren[key].children = service.getRowExpandedStates( value.children );
1188
+ } else {
1189
+ newChildren[key].children = {};
1190
+ }
1191
+ });
1192
+
1193
+ return newChildren;
1194
+ },
1195
+
1196
+
1197
+ /**
1198
+ * @ngdoc function
1199
+ * @name applyRowExpandedStates
1200
+ * @methodOf ui.grid.grouping.service:uiGridGroupingService
1201
+ * @description Take a hash in the format as created by getRowExpandedStates,
1202
+ * and apply it to the grid.grouping.groupHeaderCache.
1203
+ *
1204
+ * Takes a treeSubset, and applies to a treeSubset - so can be called
1205
+ * recursively.
1206
+ *
1207
+ * @param {object} currentNode can be grid.grouping.groupHeaderCache, or any of
1208
+ * the children of that hash
1209
+ * @param {object} expandedStates can be the full expanded states, or children
1210
+ * of that expanded states (which hopefully matches the subset of the groupHeaderCache)
1211
+ */
1212
+ applyRowExpandedStates: function( currentNode, expandedStates ) {
1213
+ if ( typeof(expandedStates) === 'undefined' ) {
1214
+ return;
1215
+ }
1216
+
1217
+ angular.forEach(expandedStates, function( value, key ) {
1218
+ if ( currentNode[key] ) {
1219
+ currentNode[key].row.treeNode.state = value.state;
1220
+
1221
+ if (value.children && currentNode[key].children) {
1222
+ service.applyRowExpandedStates( currentNode[key].children, value.children );
1223
+ }
1224
+ }
1225
+ });
1226
+ }
1227
+
1228
+
1229
+ };
1230
+
1231
+ return service;
1232
+
1233
+ }]);
1234
+
1235
+
1236
+ /**
1237
+ * @ngdoc directive
1238
+ * @name ui.grid.grouping.directive:uiGridGrouping
1239
+ * @element div
1240
+ * @restrict A
1241
+ *
1242
+ * @description Adds grouping features to grid
1243
+ *
1244
+ * @example
1245
+ <example module="app">
1246
+ <file name="app.js">
1247
+ var app = angular.module('app', ['ui.grid', 'ui.grid.grouping']);
1248
+
1249
+ app.controller('MainCtrl', ['$scope', function ($scope) {
1250
+ $scope.data = [
1251
+ { name: 'Bob', title: 'CEO' },
1252
+ { name: 'Frank', title: 'Lowly Developer' }
1253
+ ];
1254
+
1255
+ $scope.columnDefs = [
1256
+ {name: 'name', enableCellEdit: true},
1257
+ {name: 'title', enableCellEdit: true}
1258
+ ];
1259
+
1260
+ $scope.gridOptions = { columnDefs: $scope.columnDefs, data: $scope.data };
1261
+ }]);
1262
+ </file>
1263
+ <file name="index.html">
1264
+ <div ng-controller="MainCtrl">
1265
+ <div ui-grid="gridOptions" ui-grid-grouping></div>
1266
+ </div>
1267
+ </file>
1268
+ </example>
1269
+ */
1270
+ module.directive('uiGridGrouping', ['uiGridGroupingConstants', 'uiGridGroupingService',
1271
+ function (uiGridGroupingConstants, uiGridGroupingService) {
1272
+ return {
1273
+ replace: true,
1274
+ priority: 0,
1275
+ require: '^uiGrid',
1276
+ scope: false,
1277
+ compile: function () {
1278
+ return {
1279
+ pre: function ($scope, $elm, $attrs, uiGridCtrl) {
1280
+ if (uiGridCtrl.grid.options.enableGrouping !== false) {
1281
+ uiGridGroupingService.initializeGrid(uiGridCtrl.grid, $scope);
1282
+ }
1283
+ },
1284
+ post: function ($scope, $elm, $attrs, uiGridCtrl) {
1285
+ }
1286
+ };
1287
+ }
1288
+ };
1289
+ }]);
1290
+
1291
+ })();