@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,1743 @@
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.treeBase
13
+ * @description
14
+ *
15
+ * # ui.grid.treeBase
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 base tree handling functions that are shared by other features, notably grouping
20
+ * and treeView. It provides a tree view of the data, with nodes in that
21
+ * tree and leaves.
22
+ *
23
+ * Design information:
24
+ * -------------------
25
+ *
26
+ * The raw data that is provided must come with a $$treeLevel on any non-leaf node. Grouping will create
27
+ * these on all the group header rows, treeView will expect these to be set in the raw data by the user.
28
+ * TreeBase will run a rowsProcessor that:
29
+ * - builds `treeBase.tree` out of the provided rows
30
+ * - permits a recursive sort of the tree
31
+ * - maintains the expand/collapse state of each node
32
+ * - provides the expand/collapse all button and the expand/collapse buttons
33
+ * - maintains the count of children for each node
34
+ *
35
+ * Each row is updated with a link to the tree node that represents it. Refer {@link ui.grid.treeBase.grid:treeBase.tree tree documentation}
36
+ * for information.
37
+ *
38
+ * TreeBase adds information to the rows
39
+ * - treeLevel: if present and > -1 tells us the level (level 0 is the top level)
40
+ * - treeNode: pointer to the node in the grid.treeBase.tree that refers
41
+ * to this row, allowing us to manipulate the state
42
+ *
43
+ * Since the logic is baked into the rowsProcessors, it should get triggered whenever
44
+ * row order or filtering or anything like that is changed. We recall the expanded state
45
+ * across invocations of the rowsProcessors by the reference to the treeNode on the individual
46
+ * rows. We rebuild the tree itself quite frequently, when we do this we use the saved treeNodes to
47
+ * get the state, but we overwrite the other data in that treeNode.
48
+ *
49
+ * By default rows are collapsed, which means all data rows have their visible property
50
+ * set to false, and only level 0 group rows are set to visible.
51
+ *
52
+ * We rely on the rowsProcessors to do the actual expanding and collapsing, so we set the flags we want into
53
+ * grid.treeBase.tree, then call refresh. This is because we can't easily change the visible
54
+ * row cache without calling the processors, and once we've built the logic into the rowProcessors we may as
55
+ * well use it all the time.
56
+ *
57
+ * Tree base provides sorting (on non-grouped columns).
58
+ *
59
+ * Sorting works in two passes. The standard sorting is performed for any columns that are important to building
60
+ * the tree (for example, any grouped columns). Then after the tree is built, a recursive tree sort is performed
61
+ * for the remaining sort columns (including the original sort) - these columns are sorted within each tree level
62
+ * (so all the level 1 nodes are sorted, then all the level 2 nodes within each level 1 node etc).
63
+ *
64
+ * To achieve this we make use of the `ignoreSort` property on the sort configuration. The parent feature (treeView or grouping)
65
+ * must provide a rowsProcessor that runs with very low priority (typically in the 60-65 range), and that sets
66
+ * the `ignoreSort`on any sort that it wants to run on the tree. TreeBase will clear the ignoreSort on all sorts - so it
67
+ * will turn on any sorts that haven't run. It will then call a recursive sort on the tree.
68
+ *
69
+ * Tree base provides treeAggregation. It checks the treeAggregation configuration on each column, and aggregates based on
70
+ * the logic provided as it builds the tree. Footer aggregation from the uiGrid core should not be used with treeBase aggregation,
71
+ * since it operates on all visible rows, as opposed to to leaf nodes only. Setting `showColumnFooter: true` will show the
72
+ * treeAggregations in the column footer. Aggregation information will be collected in the format:
73
+ *
74
+ * ```
75
+ * {
76
+ * type: 'count',
77
+ * value: 4,
78
+ * label: 'count: ',
79
+ * rendered: 'count: 4'
80
+ * }
81
+ * ```
82
+ *
83
+ * A callback is provided to format the value once it is finalised (aka a valueFilter).
84
+ *
85
+ * <br/>
86
+ * <br/>
87
+ *
88
+ * <div doc-module-components="ui.grid.treeBase"></div>
89
+ */
90
+
91
+ var module = angular.module('ui.grid.treeBase', ['ui.grid']);
92
+
93
+ /**
94
+ * @ngdoc object
95
+ * @name ui.grid.treeBase.constant:uiGridTreeBaseConstants
96
+ *
97
+ * @description constants available in treeBase module.
98
+ *
99
+ * These constants are manually copied into grouping and treeView,
100
+ * as I haven't found a way to simply include them, and it's not worth
101
+ * investing time in for something that changes very infrequently.
102
+ *
103
+ */
104
+ module.constant('uiGridTreeBaseConstants', {
105
+ featureName: "treeBase",
106
+ rowHeaderColName: 'treeBaseRowHeaderCol',
107
+ EXPANDED: 'expanded',
108
+ COLLAPSED: 'collapsed',
109
+ aggregation: {
110
+ COUNT: 'count',
111
+ SUM: 'sum',
112
+ MAX: 'max',
113
+ MIN: 'min',
114
+ AVG: 'avg'
115
+ }
116
+ });
117
+
118
+ /**
119
+ * @ngdoc service
120
+ * @name ui.grid.treeBase.service:uiGridTreeBaseService
121
+ *
122
+ * @description Services for treeBase feature
123
+ */
124
+ /**
125
+ * @ngdoc object
126
+ * @name ui.grid.treeBase.api:ColumnDef
127
+ *
128
+ * @description ColumnDef for tree feature, these are available to be
129
+ * set using the ui-grid {@link ui.grid.class:GridOptions.columnDef gridOptions.columnDefs}
130
+ */
131
+
132
+ module.service('uiGridTreeBaseService', ['$q', 'uiGridTreeBaseConstants', 'gridUtil', 'GridRow', 'gridClassFactory', 'i18nService', 'uiGridConstants', 'rowSorter',
133
+ function ($q, uiGridTreeBaseConstants, gridUtil, GridRow, gridClassFactory, i18nService, uiGridConstants, rowSorter) {
134
+
135
+ var service = {
136
+
137
+ initializeGrid: function (grid) {
138
+
139
+ // add feature namespace and any properties to grid for needed
140
+ /**
141
+ * @ngdoc object
142
+ * @name ui.grid.treeBase.grid:treeBase
143
+ *
144
+ * @description Grid properties and functions added for treeBase
145
+ */
146
+ grid.treeBase = {};
147
+
148
+ /**
149
+ * @ngdoc property
150
+ * @propertyOf ui.grid.treeBase.grid:treeBase
151
+ * @name numberLevels
152
+ *
153
+ * @description Total number of tree levels currently used, calculated by the rowsProcessor by
154
+ * retaining the highest tree level it sees
155
+ */
156
+ grid.treeBase.numberLevels = 0;
157
+
158
+ /**
159
+ * @ngdoc property
160
+ * @propertyOf ui.grid.treeBase.grid:treeBase
161
+ * @name expandAll
162
+ *
163
+ * @description Whether or not the expandAll box is selected
164
+ */
165
+ grid.treeBase.expandAll = false;
166
+
167
+ /**
168
+ * @ngdoc property
169
+ * @propertyOf ui.grid.treeBase.grid:treeBase
170
+ * @name tree
171
+ *
172
+ * @description Tree represented as a nested array that holds the state of each node, along with a
173
+ * pointer to the row. The array order is material - we will display the children in the order
174
+ * they are stored in the array
175
+ *
176
+ * Each node stores:
177
+ *
178
+ * - the state of this node
179
+ * - an array of children of this node
180
+ * - a pointer to the parent of this node (reverse pointer, allowing us to walk up the tree)
181
+ * - the number of children of this node
182
+ * - aggregation information calculated from the nodes
183
+ *
184
+ * ```
185
+ * [{
186
+ * state: 'expanded',
187
+ * row: <reference to row>,
188
+ * parentRow: null,
189
+ * aggregations: [{
190
+ * type: 'count',
191
+ * col: <gridCol>,
192
+ * value: 2,
193
+ * label: 'count: ',
194
+ * rendered: 'count: 2'
195
+ * }],
196
+ * children: [
197
+ * {
198
+ * state: 'expanded',
199
+ * row: <reference to row>,
200
+ * parentRow: <reference to row>,
201
+ * aggregations: [{
202
+ * type: 'count',
203
+ * col: '<gridCol>,
204
+ * value: 4,
205
+ * label: 'count: ',
206
+ * rendered: 'count: 4'
207
+ * }],
208
+ * children: [
209
+ * { state: 'expanded', row: <reference to row>, parentRow: <reference to row> },
210
+ * { state: 'collapsed', row: <reference to row>, parentRow: <reference to row> },
211
+ * { state: 'expanded', row: <reference to row>, parentRow: <reference to row> },
212
+ * { state: 'collapsed', row: <reference to row>, parentRow: <reference to row> }
213
+ * ]
214
+ * },
215
+ * {
216
+ * state: 'collapsed',
217
+ * row: <reference to row>,
218
+ * parentRow: <reference to row>,
219
+ * aggregations: [{
220
+ * type: 'count',
221
+ * col: <gridCol>,
222
+ * value: 3,
223
+ * label: 'count: ',
224
+ * rendered: 'count: 3'
225
+ * }],
226
+ * children: [
227
+ * { state: 'expanded', row: <reference to row>, parentRow: <reference to row> },
228
+ * { state: 'collapsed', row: <reference to row>, parentRow: <reference to row> },
229
+ * { state: 'expanded', row: <reference to row>, parentRow: <reference to row> }
230
+ * ]
231
+ * }
232
+ * ]
233
+ * }, {<another level 0 node maybe>} ]
234
+ * ```
235
+ * Missing state values are false - meaning they aren't expanded.
236
+ *
237
+ * This is used because the rowProcessors run every time the grid is refreshed, so
238
+ * we'd lose the expanded state every time the grid was refreshed. This instead gives
239
+ * us a reliable lookup that persists across rowProcessors.
240
+ *
241
+ * This tree is rebuilt every time we run the rowsProcessors. Since each row holds a pointer
242
+ * to it's tree node we can persist expand/collapse state across calls to rowsProcessor, we discard
243
+ * all transient information on the tree (children, childCount) and recalculate it
244
+ *
245
+ */
246
+ grid.treeBase.tree = [];
247
+
248
+ service.defaultGridOptions(grid.options);
249
+
250
+ grid.registerRowsProcessor(service.treeRows, 410);
251
+
252
+ grid.registerColumnBuilder( service.treeBaseColumnBuilder );
253
+
254
+ service.createRowHeader( grid );
255
+
256
+ /**
257
+ * @ngdoc object
258
+ * @name ui.grid.treeBase.api:PublicApi
259
+ *
260
+ * @description Public Api for treeBase feature
261
+ */
262
+ var publicApi = {
263
+ events: {
264
+ treeBase: {
265
+ /**
266
+ * @ngdoc event
267
+ * @eventOf ui.grid.treeBase.api:PublicApi
268
+ * @name rowExpanded
269
+ * @description raised whenever a row is expanded. If you are dynamically
270
+ * rendering your tree you can listen to this event, and then retrieve
271
+ * the children of this row and load them into the grid data.
272
+ *
273
+ * When the data is loaded the grid will automatically refresh to show these new rows
274
+ *
275
+ * <pre>
276
+ * gridApi.treeBase.on.rowExpanded(scope,function(row) {})
277
+ * </pre>
278
+ * @param {gridRow} row the row that was expanded. You can also
279
+ * retrieve the grid from this row with row.grid
280
+ */
281
+ rowExpanded: {},
282
+
283
+ /**
284
+ * @ngdoc event
285
+ * @eventOf ui.grid.treeBase.api:PublicApi
286
+ * @name rowCollapsed
287
+ * @description raised whenever a row is collapsed. Doesn't really have
288
+ * a purpose at the moment, included for symmetry
289
+ *
290
+ * <pre>
291
+ * gridApi.treeBase.on.rowCollapsed(scope,function(row) {})
292
+ * </pre>
293
+ * @param {gridRow} row the row that was collapsed. You can also
294
+ * retrieve the grid from this row with row.grid
295
+ */
296
+ rowCollapsed: {}
297
+ }
298
+ },
299
+
300
+ methods: {
301
+ treeBase: {
302
+ /**
303
+ * @ngdoc function
304
+ * @name expandAllRows
305
+ * @methodOf ui.grid.treeBase.api:PublicApi
306
+ * @description Expands all tree rows
307
+ */
308
+ expandAllRows: function () {
309
+ service.expandAllRows(grid);
310
+ },
311
+
312
+ /**
313
+ * @ngdoc function
314
+ * @name collapseAllRows
315
+ * @methodOf ui.grid.treeBase.api:PublicApi
316
+ * @description collapse all tree rows
317
+ */
318
+ collapseAllRows: function () {
319
+ service.collapseAllRows(grid);
320
+ },
321
+
322
+ /**
323
+ * @ngdoc function
324
+ * @name toggleRowTreeState
325
+ * @methodOf ui.grid.treeBase.api:PublicApi
326
+ * @description call expand if the row is collapsed, collapse if it is expanded
327
+ * @param {gridRow} row the row you wish to toggle
328
+ */
329
+ toggleRowTreeState: function (row) {
330
+ service.toggleRowTreeState(grid, row);
331
+ },
332
+
333
+ /**
334
+ * @ngdoc function
335
+ * @name expandRow
336
+ * @methodOf ui.grid.treeBase.api:PublicApi
337
+ * @description expand the immediate children of the specified row
338
+ * @param {gridRow} row the row you wish to expand
339
+ * @param {boolean} recursive true if you wish to expand the row's ancients
340
+ */
341
+ expandRow: function (row, recursive) {
342
+ service.expandRow(grid, row, recursive);
343
+ },
344
+
345
+ /**
346
+ * @ngdoc function
347
+ * @name expandRowChildren
348
+ * @methodOf ui.grid.treeBase.api:PublicApi
349
+ * @description expand all children of the specified row
350
+ * @param {gridRow} row the row you wish to expand
351
+ */
352
+ expandRowChildren: function (row) {
353
+ service.expandRowChildren(grid, row);
354
+ },
355
+
356
+ /**
357
+ * @ngdoc function
358
+ * @name collapseRow
359
+ * @methodOf ui.grid.treeBase.api:PublicApi
360
+ * @description collapse the specified row. When
361
+ * you expand the row again, all grandchildren will retain their state
362
+ * @param {gridRow} row the row you wish to collapse
363
+ */
364
+ collapseRow: function ( row ) {
365
+ service.collapseRow(grid, row);
366
+ },
367
+
368
+ /**
369
+ * @ngdoc function
370
+ * @name collapseRowChildren
371
+ * @methodOf ui.grid.treeBase.api:PublicApi
372
+ * @description collapse all children of the specified row. When
373
+ * you expand the row again, all grandchildren will be collapsed
374
+ * @param {gridRow} row the row you wish to collapse children for
375
+ */
376
+ collapseRowChildren: function ( row ) {
377
+ service.collapseRowChildren(grid, row);
378
+ },
379
+
380
+ /**
381
+ * @ngdoc function
382
+ * @name getTreeState
383
+ * @methodOf ui.grid.treeBase.api:PublicApi
384
+ * @description Get the tree state for this grid,
385
+ * used by the saveState feature
386
+ * Returned treeState as an object
387
+ * `{ expandedState: { uid: 'expanded', uid: 'collapsed' } }`
388
+ * where expandedState is a hash of row uid and the current expanded state
389
+ *
390
+ * @returns {object} tree state
391
+ *
392
+ * TODO - this needs work - we need an identifier that persists across instantiations,
393
+ * not uid. This really means we need a row identity defined, but that won't work for
394
+ * grouping. Perhaps this needs to be moved up to treeView and grouping, rather than
395
+ * being in base.
396
+ */
397
+ getTreeExpandedState: function () {
398
+ return { expandedState: service.getTreeState(grid) };
399
+ },
400
+
401
+ /**
402
+ * @ngdoc function
403
+ * @name setTreeState
404
+ * @methodOf ui.grid.treeBase.api:PublicApi
405
+ * @description Set the expanded states of the tree
406
+ * @param {object} config the config you want to apply, in the format
407
+ * provided by getTreeState
408
+ */
409
+ setTreeState: function ( config ) {
410
+ service.setTreeState( grid, config );
411
+ },
412
+
413
+ /**
414
+ * @ngdoc function
415
+ * @name getRowChildren
416
+ * @methodOf ui.grid.treeBase.api:PublicApi
417
+ * @description Get the children of the specified row
418
+ * @param {GridRow} row the row you want the children of
419
+ * @returns {Array} array of children of this row, the children
420
+ * are all gridRows
421
+ */
422
+ getRowChildren: function ( row ) {
423
+ return row.treeNode.children.map( function( childNode ) {
424
+ return childNode.row;
425
+ });
426
+ }
427
+ }
428
+ }
429
+ };
430
+
431
+ grid.api.registerEventsFromObject(publicApi.events);
432
+
433
+ grid.api.registerMethodsFromObject(publicApi.methods);
434
+ },
435
+
436
+
437
+ defaultGridOptions: function (gridOptions) {
438
+ // default option to true unless it was explicitly set to false
439
+ /**
440
+ * @ngdoc object
441
+ * @name ui.grid.treeBase.api:GridOptions
442
+ *
443
+ * @description GridOptions for treeBase feature, these are available to be
444
+ * set using the ui-grid {@link ui.grid.class:GridOptions gridOptions}
445
+ */
446
+
447
+ /**
448
+ * @ngdoc object
449
+ * @name treeRowHeaderBaseWidth
450
+ * @propertyOf ui.grid.treeBase.api:GridOptions
451
+ * @description Base width of the tree header, provides for a single level of tree. This
452
+ * is incremented by `treeIndent` for each extra level
453
+ * <br/>Defaults to 30
454
+ */
455
+ gridOptions.treeRowHeaderBaseWidth = gridOptions.treeRowHeaderBaseWidth || 30;
456
+
457
+ /**
458
+ * @ngdoc object
459
+ * @name treeIndent
460
+ * @propertyOf ui.grid.treeBase.api:GridOptions
461
+ * @description Number of pixels of indent for the icon at each tree level, wider indents are visually more pleasing,
462
+ * but will make the tree row header wider
463
+ * <br/>Defaults to 10
464
+ */
465
+ gridOptions.treeIndent = (gridOptions.treeIndent != null) ? gridOptions.treeIndent : 10;
466
+
467
+ /**
468
+ * @ngdoc object
469
+ * @name showTreeRowHeader
470
+ * @propertyOf ui.grid.treeBase.api:GridOptions
471
+ * @description If set to false, don't create the row header. You'll need to programmatically control the expand
472
+ * states
473
+ * <br/>Defaults to true
474
+ */
475
+ gridOptions.showTreeRowHeader = gridOptions.showTreeRowHeader !== false;
476
+
477
+ /**
478
+ * @ngdoc object
479
+ * @name showTreeExpandNoChildren
480
+ * @propertyOf ui.grid.treeBase.api:GridOptions
481
+ * @description If set to true, show the expand/collapse button even if there are no
482
+ * children of a node. You'd use this if you're planning to dynamically load the children
483
+ *
484
+ * <br/>Defaults to true, grouping overrides to false
485
+ */
486
+ gridOptions.showTreeExpandNoChildren = gridOptions.showTreeExpandNoChildren !== false;
487
+
488
+ /**
489
+ * @ngdoc object
490
+ * @name treeRowHeaderAlwaysVisible
491
+ * @propertyOf ui.grid.treeBase.api:GridOptions
492
+ * @description If set to true, row header even if there are no tree nodes
493
+ *
494
+ * <br/>Defaults to true
495
+ */
496
+ gridOptions.treeRowHeaderAlwaysVisible = gridOptions.treeRowHeaderAlwaysVisible !== false;
497
+
498
+ /**
499
+ * @ngdoc object
500
+ * @name treeCustomAggregations
501
+ * @propertyOf ui.grid.treeBase.api:GridOptions
502
+ * @description Define custom aggregation functions. The properties of this object will be
503
+ * aggregation types available for use on columnDef with {@link ui.grid.treeBase.api:ColumnDef treeAggregationType} or through the column menu.
504
+ * If a function defined here uses the same name as one of the native aggregations, this one will take precedence.
505
+ * The object format is:
506
+ *
507
+ * <pre>
508
+ * {
509
+ * aggregationName: {
510
+ * label: (optional) string,
511
+ * aggregationFn: function( aggregation, fieldValue, numValue, row ) {...},
512
+ * finalizerFn: (optional) function( aggregation ) {...}
513
+ * },
514
+ * mean: {
515
+ * label: 'mean',
516
+ * aggregationFn: function( aggregation, fieldValue, numValue ) {
517
+ * aggregation.count = (aggregation.count || 1) + 1;
518
+ * aggregation.sum = (aggregation.sum || 0) + numValue;
519
+ * },
520
+ * finalizerFn: function( aggregation ) {
521
+ * aggregation.value = aggregation.sum / aggregation.count
522
+ * }
523
+ * }
524
+ * }
525
+ * </pre>
526
+ *
527
+ * <br/>The `finalizerFn` may be used to manipulate the value before rendering, or to
528
+ * apply a custom rendered value. If `aggregation.rendered` is left undefined, the value will be
529
+ * rendered. Note that the native aggregation functions use an `finalizerFn` to concatenate
530
+ * the label and the value.
531
+ *
532
+ * <br/>Defaults to {}
533
+ */
534
+ gridOptions.treeCustomAggregations = gridOptions.treeCustomAggregations || {};
535
+
536
+ /**
537
+ * @ngdoc object
538
+ * @name enableExpandAll
539
+ * @propertyOf ui.grid.treeBase.api:GridOptions
540
+ * @description Enable the expand all button at the top of the row header
541
+ *
542
+ * <br/>Defaults to true
543
+ */
544
+ gridOptions.enableExpandAll = gridOptions.enableExpandAll !== false;
545
+ },
546
+
547
+
548
+ /**
549
+ * @ngdoc function
550
+ * @name treeBaseColumnBuilder
551
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
552
+ * @description Sets the tree defaults based on the columnDefs
553
+ *
554
+ * @param {object} colDef columnDef we're basing on
555
+ * @param {GridColumn} col the column we're to update
556
+ * @param {object} gridOptions the options we should use
557
+ * @returns {promise} promise for the builder - actually we do it all inline so it's immediately resolved
558
+ */
559
+ treeBaseColumnBuilder: function (colDef, col, gridOptions) {
560
+
561
+
562
+ /**
563
+ * @ngdoc object
564
+ * @name customTreeAggregationFn
565
+ * @propertyOf ui.grid.treeBase.api:ColumnDef
566
+ * @description A custom function that aggregates rows into some form of
567
+ * total. Aggregations run row-by-row, the function needs to be capable of
568
+ * creating a running total.
569
+ *
570
+ * The function will be provided the aggregation item (in which you can store running
571
+ * totals), the row value that is to be aggregated, and that same row value converted to
572
+ * a number (most aggregations work on numbers)
573
+ * @example
574
+ * <pre>
575
+ * customTreeAggregationFn = function ( aggregation, fieldValue, numValue, row ) {
576
+ * // calculates the average of the squares of the values
577
+ * if ( typeof(aggregation.count) === 'undefined' ) {
578
+ * aggregation.count = 0;
579
+ * }
580
+ * aggregation.count++;
581
+ *
582
+ * if ( !isNaN(numValue) ) {
583
+ * if ( typeof(aggregation.total) === 'undefined' ) {
584
+ * aggregation.total = 0;
585
+ * }
586
+ * aggregation.total = aggregation.total + numValue * numValue;
587
+ * }
588
+ *
589
+ * aggregation.value = aggregation.total / aggregation.count;
590
+ * }
591
+ * </pre>
592
+ * <br/>Defaults to undefined. May be overwritten by treeAggregationType, the two options should not be used together.
593
+ */
594
+ if ( typeof(colDef.customTreeAggregationFn) !== 'undefined' ) {
595
+ col.treeAggregationFn = colDef.customTreeAggregationFn;
596
+ }
597
+
598
+ /**
599
+ * @ngdoc object
600
+ * @name treeAggregationType
601
+ * @propertyOf ui.grid.treeBase.api:ColumnDef
602
+ * @description Use one of the native or grid-level aggregation methods for calculating aggregations on this column.
603
+ * Native method are in the constants file and include: SUM, COUNT, MIN, MAX, AVG. This may also be the property the
604
+ * name of an aggregation function defined with {@link ui.grid.treeBase.api:GridOptions treeCustomAggregations}.
605
+ *
606
+ * <pre>
607
+ * treeAggregationType = uiGridTreeBaseConstants.aggregation.SUM,
608
+ * }
609
+ * </pre>
610
+ *
611
+ * If you are using aggregations you should either:
612
+ *
613
+ * - also use grouping, in which case the aggregations are displayed in the group header, OR
614
+ * - use treeView, in which case you can set `treeAggregationUpdateEntity: true` in the colDef, and
615
+ * treeBase will store the aggregation information in the entity, or you can set `treeAggregationUpdateEntity: false`
616
+ * in the colDef, and you need to manual retrieve the calculated aggregations from the row.treeNode.aggregations
617
+ *
618
+ * <br/>Takes precendence over a treeAggregationFn, the two options should not be used together.
619
+ * <br/>Defaults to undefined.
620
+ */
621
+ if ( typeof(colDef.treeAggregationType) !== 'undefined' ) {
622
+ col.treeAggregation = { type: colDef.treeAggregationType };
623
+ if ( typeof(gridOptions.treeCustomAggregations[colDef.treeAggregationType]) !== 'undefined' ) {
624
+ col.treeAggregationFn = gridOptions.treeCustomAggregations[colDef.treeAggregationType].aggregationFn;
625
+ col.treeAggregationFinalizerFn = gridOptions.treeCustomAggregations[colDef.treeAggregationType].finalizerFn;
626
+ col.treeAggregation.label = gridOptions.treeCustomAggregations[colDef.treeAggregationType].label;
627
+ }
628
+ else if ( typeof(service.nativeAggregations()[colDef.treeAggregationType]) !== 'undefined' ) {
629
+ col.treeAggregationFn = service.nativeAggregations()[colDef.treeAggregationType].aggregationFn;
630
+ col.treeAggregation.label = service.nativeAggregations()[colDef.treeAggregationType].label;
631
+ }
632
+ }
633
+
634
+ /**
635
+ * @ngdoc object
636
+ * @name treeAggregationLabel
637
+ * @propertyOf ui.grid.treeBase.api:ColumnDef
638
+ * @description A custom label to use for this aggregation. If provided we don't use native i18n.
639
+ */
640
+ if ( typeof(colDef.treeAggregationLabel) !== 'undefined' ) {
641
+ if (typeof(col.treeAggregation) === 'undefined' ) {
642
+ col.treeAggregation = {};
643
+ }
644
+ col.treeAggregation.label = colDef.treeAggregationLabel;
645
+ }
646
+
647
+ /**
648
+ * @ngdoc object
649
+ * @name treeAggregationUpdateEntity
650
+ * @propertyOf ui.grid.treeBase.api:ColumnDef
651
+ * @description Store calculated aggregations into the entity, allowing them
652
+ * to be displayed in the grid using a standard cellTemplate. This defaults to true,
653
+ * if you are using grouping then you shouldn't set it to false, as then the aggregations won't
654
+ * display.
655
+ *
656
+ * If you are using treeView in most cases you'll want to set this to true. This will result in
657
+ * getCellValue returning the aggregation rather than whatever was stored in the cell attribute on
658
+ * the entity. If you want to render the underlying entity value (and do something else with the aggregation)
659
+ * then you could use a custom cellTemplate to display `row.entity.myAttribute`, rather than using getCellValue.
660
+ *
661
+ * <br/>Defaults to true
662
+ *
663
+ * @example
664
+ * <pre>
665
+ * gridOptions.columns = [{
666
+ * name: 'myCol',
667
+ * treeAggregation: { type: uiGridTreeBaseConstants.aggregation.SUM },
668
+ * treeAggregationUpdateEntity: true
669
+ * cellTemplate: '<div>{{row.entity.myCol + " " + row.treeNode.aggregations[0].rendered}}</div>'
670
+ * }];
671
+ * </pre>
672
+ */
673
+ col.treeAggregationUpdateEntity = colDef.treeAggregationUpdateEntity !== false;
674
+
675
+ /**
676
+ * @ngdoc object
677
+ * @name customTreeAggregationFinalizerFn
678
+ * @propertyOf ui.grid.treeBase.api:ColumnDef
679
+ * @description A custom function that populates aggregation.rendered, this is called when
680
+ * a particular aggregation has been fully calculated, and we want to render the value.
681
+ *
682
+ * With the native aggregation options we just concatenate `aggregation.label` and
683
+ * `aggregation.value`, but if you wanted to apply a filter or otherwise manipulate the label
684
+ * or the value, you can do so with this function. This function will be called after the
685
+ * the default `finalizerFn`.
686
+ *
687
+ * @example
688
+ * <pre>
689
+ * customTreeAggregationFinalizerFn = function ( aggregation ) {
690
+ * aggregation.rendered = aggregation.label + aggregation.value / 100 + '%';
691
+ * }
692
+ * </pre>
693
+ * <br/>Defaults to undefined.
694
+ */
695
+ if ( typeof(col.customTreeAggregationFinalizerFn) === 'undefined' ) {
696
+ col.customTreeAggregationFinalizerFn = colDef.customTreeAggregationFinalizerFn;
697
+ }
698
+
699
+ },
700
+
701
+
702
+ /**
703
+ * @ngdoc function
704
+ * @name createRowHeader
705
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
706
+ * @description Create the rowHeader. If treeRowHeaderAlwaysVisible then
707
+ * set it to visible, otherwise set it to invisible
708
+ *
709
+ * @param {Grid} grid grid object
710
+ */
711
+ createRowHeader: function( grid ) {
712
+ var rowHeaderColumnDef = {
713
+ name: uiGridTreeBaseConstants.rowHeaderColName,
714
+ displayName: '',
715
+ width: grid.options.treeRowHeaderBaseWidth,
716
+ minWidth: 10,
717
+ cellTemplate: 'ui-grid/treeBaseRowHeader',
718
+ headerCellTemplate: 'ui-grid/treeBaseHeaderCell',
719
+ enableColumnResizing: false,
720
+ enableColumnMenu: false,
721
+ exporterSuppressExport: true,
722
+ allowCellFocus: true
723
+ };
724
+
725
+ rowHeaderColumnDef.visible = grid.options.treeRowHeaderAlwaysVisible;
726
+ grid.addRowHeaderColumn(rowHeaderColumnDef, -100);
727
+ },
728
+
729
+
730
+ /**
731
+ * @ngdoc function
732
+ * @name expandAllRows
733
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
734
+ * @description Expands all nodes in the tree
735
+ *
736
+ * @param {Grid} grid grid object
737
+ */
738
+ expandAllRows: function (grid) {
739
+ grid.treeBase.tree.forEach( function( node ) {
740
+ service.setAllNodes( grid, node, uiGridTreeBaseConstants.EXPANDED);
741
+ });
742
+ grid.treeBase.expandAll = true;
743
+ grid.queueGridRefresh();
744
+ },
745
+
746
+
747
+ /**
748
+ * @ngdoc function
749
+ * @name collapseAllRows
750
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
751
+ * @description Collapses all nodes in the tree
752
+ *
753
+ * @param {Grid} grid grid object
754
+ */
755
+ collapseAllRows: function (grid) {
756
+ grid.treeBase.tree.forEach( function( node ) {
757
+ service.setAllNodes( grid, node, uiGridTreeBaseConstants.COLLAPSED);
758
+ });
759
+ grid.treeBase.expandAll = false;
760
+ grid.queueGridRefresh();
761
+ },
762
+
763
+
764
+ /**
765
+ * @ngdoc function
766
+ * @name setAllNodes
767
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
768
+ * @description Works through a subset of grid.treeBase.rowExpandedStates, setting
769
+ * all child nodes (and their descendents) of the provided node to the given state.
770
+ *
771
+ * Calls itself recursively on all nodes so as to achieve this.
772
+ *
773
+ * @param {Grid} grid the grid we're operating on (so we can raise events)
774
+ * @param {object} treeNode a node in the tree that we want to update
775
+ * @param {string} targetState the state we want to set it to
776
+ */
777
+ setAllNodes: function (grid, treeNode, targetState) {
778
+ if ( typeof(treeNode.state) !== 'undefined' && treeNode.state !== targetState ) {
779
+ treeNode.state = targetState;
780
+
781
+ if ( targetState === uiGridTreeBaseConstants.EXPANDED ) {
782
+ grid.api.treeBase.raise.rowExpanded(treeNode.row);
783
+ }
784
+ else {
785
+ grid.api.treeBase.raise.rowCollapsed(treeNode.row);
786
+ }
787
+ }
788
+
789
+ // set all child nodes
790
+ if ( treeNode.children ) {
791
+ treeNode.children.forEach(function( childNode ) {
792
+ service.setAllNodes(grid, childNode, targetState);
793
+ });
794
+ }
795
+ },
796
+
797
+
798
+ /**
799
+ * @ngdoc function
800
+ * @name toggleRowTreeState
801
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
802
+ * @description Toggles the expand or collapse state of this grouped row, if
803
+ * it's a parent row
804
+ *
805
+ * @param {Grid} grid grid object
806
+ * @param {GridRow} row the row we want to toggle
807
+ */
808
+ toggleRowTreeState: function ( grid, row ) {
809
+ if ( typeof(row.treeLevel) === 'undefined' || row.treeLevel === null || row.treeLevel < 0 ) {
810
+ return;
811
+ }
812
+
813
+ if (row.treeNode.state === uiGridTreeBaseConstants.EXPANDED) {
814
+ service.collapseRow(grid, row);
815
+ }
816
+ else {
817
+ service.expandRow(grid, row, false);
818
+ }
819
+
820
+ grid.queueGridRefresh();
821
+ },
822
+
823
+
824
+ /**
825
+ * @ngdoc function
826
+ * @name expandRow
827
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
828
+ * @description Expands this specific row, showing only immediate children.
829
+ *
830
+ * @param {Grid} grid grid object
831
+ * @param {GridRow} row the row we want to expand
832
+ * @param {boolean} recursive true if you wish to expand the row's ancients
833
+ */
834
+ expandRow: function ( grid, row, recursive ) {
835
+ if ( recursive ) {
836
+ var parents = [];
837
+ while ( row && typeof(row.treeLevel) !== 'undefined' && row.treeLevel !== null && row.treeLevel >= 0 && row.treeNode.state !== uiGridTreeBaseConstants.EXPANDED ) {
838
+ parents.push(row);
839
+ row = row.treeNode.parentRow;
840
+ }
841
+
842
+ if ( parents.length > 0 ) {
843
+ row = parents.pop();
844
+ while ( row ) {
845
+ row.treeNode.state = uiGridTreeBaseConstants.EXPANDED;
846
+ grid.api.treeBase.raise.rowExpanded(row);
847
+ row = parents.pop();
848
+ }
849
+
850
+ grid.treeBase.expandAll = service.allExpanded(grid.treeBase.tree);
851
+ grid.queueGridRefresh();
852
+ }
853
+ }
854
+ else {
855
+ if ( typeof(row.treeLevel) === 'undefined' || row.treeLevel === null || row.treeLevel < 0 ) {
856
+ return;
857
+ }
858
+
859
+ if ( row.treeNode.state !== uiGridTreeBaseConstants.EXPANDED ) {
860
+ row.treeNode.state = uiGridTreeBaseConstants.EXPANDED;
861
+ grid.api.treeBase.raise.rowExpanded(row);
862
+ grid.treeBase.expandAll = service.allExpanded(grid.treeBase.tree);
863
+ grid.queueGridRefresh();
864
+ }
865
+ }
866
+ },
867
+
868
+
869
+ /**
870
+ * @ngdoc function
871
+ * @name expandRowChildren
872
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
873
+ * @description Expands this specific row, showing all children.
874
+ *
875
+ * @param {Grid} grid grid object
876
+ * @param {GridRow} row the row we want to expand
877
+ */
878
+ expandRowChildren: function ( grid, row ) {
879
+ if ( typeof(row.treeLevel) === 'undefined' || row.treeLevel === null || row.treeLevel < 0 ) {
880
+ return;
881
+ }
882
+
883
+ service.setAllNodes(grid, row.treeNode, uiGridTreeBaseConstants.EXPANDED);
884
+ grid.treeBase.expandAll = service.allExpanded(grid.treeBase.tree);
885
+ grid.queueGridRefresh();
886
+ },
887
+
888
+
889
+ /**
890
+ * @ngdoc function
891
+ * @name collapseRow
892
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
893
+ * @description Collapses this specific row
894
+ *
895
+ * @param {Grid} grid grid object
896
+ * @param {GridRow} row the row we want to collapse
897
+ */
898
+ collapseRow: function( grid, row ) {
899
+ if ( typeof(row.treeLevel) === 'undefined' || row.treeLevel === null || row.treeLevel < 0 ) {
900
+ return;
901
+ }
902
+
903
+ if ( row.treeNode.state !== uiGridTreeBaseConstants.COLLAPSED ) {
904
+ row.treeNode.state = uiGridTreeBaseConstants.COLLAPSED;
905
+ grid.treeBase.expandAll = false;
906
+ grid.api.treeBase.raise.rowCollapsed(row);
907
+ grid.queueGridRefresh();
908
+ }
909
+ },
910
+
911
+
912
+ /**
913
+ * @ngdoc function
914
+ * @name collapseRowChildren
915
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
916
+ * @description Collapses this specific row and all children
917
+ *
918
+ * @param {Grid} grid grid object
919
+ * @param {GridRow} row the row we want to collapse
920
+ */
921
+ collapseRowChildren: function( grid, row ) {
922
+ if ( typeof(row.treeLevel) === 'undefined' || row.treeLevel === null || row.treeLevel < 0 ) {
923
+ return;
924
+ }
925
+
926
+ service.setAllNodes(grid, row.treeNode, uiGridTreeBaseConstants.COLLAPSED);
927
+ grid.treeBase.expandAll = false;
928
+ grid.queueGridRefresh();
929
+ },
930
+
931
+
932
+ /**
933
+ * @ngdoc function
934
+ * @name allExpanded
935
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
936
+ * @description Returns true if all rows are expanded, false
937
+ * if they're not. Walks the tree to determine this. Used
938
+ * to set the expandAll state.
939
+ *
940
+ * If the node has no children, then return true (it's immaterial
941
+ * whether it is expanded). If the node has children, then return
942
+ * false if this node is collapsed, or if any child node is not all expanded
943
+ *
944
+ * @param {object} tree the grid to check
945
+ * @returns {boolean} whether or not the tree is all expanded
946
+ */
947
+ allExpanded: function( tree ) {
948
+ var allExpanded = true;
949
+
950
+ tree.forEach(function( node ) {
951
+ if ( !service.allExpandedInternal( node ) ) {
952
+ allExpanded = false;
953
+ }
954
+ });
955
+ return allExpanded;
956
+ },
957
+
958
+ allExpandedInternal: function( treeNode ) {
959
+ if ( treeNode.children && treeNode.children.length > 0 ) {
960
+ if ( treeNode.state === uiGridTreeBaseConstants.COLLAPSED ) {
961
+ return false;
962
+ }
963
+ var allExpanded = true;
964
+ treeNode.children.forEach( function( node ) {
965
+ if ( !service.allExpandedInternal( node ) ) {
966
+ allExpanded = false;
967
+ }
968
+ });
969
+ return allExpanded;
970
+ }
971
+ else {
972
+ return true;
973
+ }
974
+ },
975
+
976
+
977
+ /**
978
+ * @ngdoc function
979
+ * @name treeRows
980
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
981
+ * @description The rowProcessor that adds the nodes to the tree, and sets the visible
982
+ * state of each row based on it's parent state
983
+ *
984
+ * Assumes it is always called after the sorting processor, and the grouping processor if there is one.
985
+ * Performs any tree sorts itself after having built the tree
986
+ *
987
+ * Processes all the rows in order, setting the group level based on the $$treeLevel in the associated
988
+ * entity, and setting the visible state based on the parent's state.
989
+ *
990
+ * Calculates the deepest level of tree whilst it goes, and updates that so that the header column can be correctly
991
+ * sized.
992
+ *
993
+ * Aggregates if necessary along the way.
994
+ *
995
+ * @param {array} renderableRows the rows we want to process, usually the output from the previous rowProcessor
996
+ * @returns {array} the updated rows
997
+ */
998
+ treeRows: function( renderableRows ) {
999
+ var grid = this;
1000
+
1001
+ if (renderableRows.length === 0) {
1002
+ service.updateRowHeaderWidth( grid );
1003
+ return renderableRows;
1004
+ }
1005
+
1006
+ grid.treeBase.tree = service.createTree( grid, renderableRows );
1007
+ service.updateRowHeaderWidth( grid );
1008
+
1009
+ service.sortTree( grid );
1010
+ service.fixFilter( grid );
1011
+
1012
+ return service.renderTree( grid.treeBase.tree );
1013
+ },
1014
+
1015
+
1016
+ /**
1017
+ * @ngdoc function
1018
+ * @name createOrUpdateRowHeaderWidth
1019
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
1020
+ * @description Calculates the rowHeader width.
1021
+ *
1022
+ * If rowHeader is always present, updates the width.
1023
+ *
1024
+ * If rowHeader is only sometimes present (`treeRowHeaderAlwaysVisible: false`), determines whether there
1025
+ * should be one, then creates or removes it as appropriate, with the created rowHeader having the
1026
+ * right width.
1027
+ *
1028
+ * If there's never a rowHeader then never creates one: `showTreeRowHeader: false`
1029
+ *
1030
+ * @param {Grid} grid the grid we want to set the row header on
1031
+ */
1032
+ updateRowHeaderWidth: function( grid ) {
1033
+ var rowHeader = grid.getColumn(uiGridTreeBaseConstants.rowHeaderColName),
1034
+ newWidth = grid.options.treeRowHeaderBaseWidth + grid.options.treeIndent * Math.max(grid.treeBase.numberLevels - 1, 0);
1035
+
1036
+ if ( rowHeader && newWidth !== rowHeader.width ) {
1037
+ rowHeader.width = newWidth;
1038
+ grid.queueRefresh();
1039
+ }
1040
+
1041
+ var newVisibility = true;
1042
+
1043
+ if ( grid.options.showTreeRowHeader === false ) {
1044
+ newVisibility = false;
1045
+ }
1046
+ if ( grid.options.treeRowHeaderAlwaysVisible === false && grid.treeBase.numberLevels <= 0 ) {
1047
+ newVisibility = false;
1048
+ }
1049
+ if ( rowHeader && rowHeader.visible !== newVisibility ) {
1050
+ rowHeader.visible = newVisibility;
1051
+ rowHeader.colDef.visible = newVisibility;
1052
+ grid.queueGridRefresh();
1053
+ }
1054
+ },
1055
+
1056
+
1057
+ /**
1058
+ * @ngdoc function
1059
+ * @name renderTree
1060
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
1061
+ * @description Creates an array of rows based on the tree, exporting only
1062
+ * the visible nodes and leaves
1063
+ *
1064
+ * @param {array} nodeList The list of nodes - can be grid.treeBase.tree, or can be node.children when
1065
+ * we're calling recursively
1066
+ * @returns {array} renderable rows
1067
+ */
1068
+ renderTree: function( nodeList ) {
1069
+ var renderableRows = [];
1070
+
1071
+ nodeList.forEach( function ( node ) {
1072
+ if ( node.row.visible ) {
1073
+ renderableRows.push( node.row );
1074
+ }
1075
+ if ( node.state === uiGridTreeBaseConstants.EXPANDED && node.children && node.children.length > 0 ) {
1076
+ renderableRows = renderableRows.concat( service.renderTree( node.children ) );
1077
+ }
1078
+ });
1079
+ return renderableRows;
1080
+ },
1081
+
1082
+
1083
+ /**
1084
+ * @ngdoc function
1085
+ * @name createTree
1086
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
1087
+ * @description Creates a tree from the renderableRows
1088
+ *
1089
+ * @param {Grid} grid The grid
1090
+ * @param {array} renderableRows The rows we want to create a tree from
1091
+ * @returns {object} The tree we've build
1092
+ */
1093
+ createTree: function( grid, renderableRows ) {
1094
+ var currentLevel = -1,
1095
+ parentsCache = {},
1096
+ parents = [],
1097
+ currentState;
1098
+
1099
+ grid.treeBase.tree = [];
1100
+ grid.treeBase.numberLevels = 0;
1101
+
1102
+ var aggregations = service.getAggregations( grid );
1103
+
1104
+ function createNode( row ) {
1105
+ if ( !row.internalRow && row.treeLevel !== row.entity.$$treeLevel ) {
1106
+ row.treeLevel = row.entity.$$treeLevel;
1107
+ }
1108
+
1109
+ if ( row.treeLevel <= currentLevel ) {
1110
+ // pop any levels that aren't parents of this level, formatting the aggregation at the same time
1111
+ while ( row.treeLevel <= currentLevel ) {
1112
+ var lastParent = parents.pop();
1113
+ service.finaliseAggregations( lastParent );
1114
+ currentLevel--;
1115
+ }
1116
+
1117
+ // reset our current state based on the new parent, set to expanded if this is a level 0 node
1118
+ if ( parents.length > 0 ) {
1119
+ currentState = service.setCurrentState(parents);
1120
+ }
1121
+ else {
1122
+ currentState = uiGridTreeBaseConstants.EXPANDED;
1123
+ }
1124
+ }
1125
+
1126
+ // If row header as parent exists in parentsCache
1127
+ if (
1128
+ typeof row.treeLevel !== 'undefined' &&
1129
+ row.treeLevel !== null &&
1130
+ row.treeLevel >= 0 &&
1131
+ parentsCache.hasOwnProperty(row.uid)
1132
+ ) {
1133
+ parents.push(parentsCache[row.uid]);
1134
+ }
1135
+
1136
+ // aggregate if this is a leaf node
1137
+ if ( ( typeof(row.treeLevel) === 'undefined' || row.treeLevel === null || row.treeLevel < 0 ) && row.visible ) {
1138
+ service.aggregate( grid, row, parents );
1139
+ }
1140
+
1141
+ // add this node to the tree
1142
+ if (!parentsCache.hasOwnProperty(row.uid)) {
1143
+ service.addOrUseNode(grid, row, parents, aggregations);
1144
+ }
1145
+
1146
+ if ( typeof(row.treeLevel) !== 'undefined' && row.treeLevel !== null && row.treeLevel >= 0 ) {
1147
+ if (!parentsCache.hasOwnProperty(row.uid)) {
1148
+ parentsCache[row.uid] = row;
1149
+ parents.push(row);
1150
+ }
1151
+ currentLevel++;
1152
+ currentState = service.setCurrentState(parents);
1153
+ }
1154
+
1155
+ // update the tree number of levels, so we can set header width if we need to
1156
+ if ( grid.treeBase.numberLevels < row.treeLevel + 1) {
1157
+ grid.treeBase.numberLevels = row.treeLevel + 1;
1158
+ }
1159
+ }
1160
+
1161
+ renderableRows.forEach( createNode );
1162
+
1163
+ // finalize remaining aggregations
1164
+ while ( parents.length > 0 ) {
1165
+ var lastParent = parents.pop();
1166
+ service.finaliseAggregations( lastParent );
1167
+ }
1168
+
1169
+ return grid.treeBase.tree;
1170
+ },
1171
+
1172
+
1173
+ /**
1174
+ * @ngdoc function
1175
+ * @name addOrUseNode
1176
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
1177
+ * @description Creates a tree node for this row. If this row already has a treeNode
1178
+ * recorded against it, preserves the state, but otherwise overwrites the data.
1179
+ *
1180
+ * @param {grid} grid The grid we're operating on
1181
+ * @param {gridRow} row The row we want to set
1182
+ * @param {array} parents An array of the parents this row should have
1183
+ * @param {array} aggregationBase Empty aggregation information
1184
+ * @returns {undefined} Updates the parents array, updates the row to have a treeNode, and updates the
1185
+ * grid.treeBase.tree
1186
+ */
1187
+ addOrUseNode: function( grid, row, parents, aggregationBase ) {
1188
+ var newAggregations = [];
1189
+ aggregationBase.forEach( function(aggregation) {
1190
+ newAggregations.push(service.buildAggregationObject(aggregation.col));
1191
+ });
1192
+
1193
+ var newNode = { state: uiGridTreeBaseConstants.COLLAPSED, row: row, parentRow: null, aggregations: newAggregations, children: [] };
1194
+ if ( row.treeNode ) {
1195
+ newNode.state = row.treeNode.state;
1196
+ }
1197
+ if ( parents.length > 0 ) {
1198
+ newNode.parentRow = parents[parents.length - 1];
1199
+ }
1200
+ row.treeNode = newNode;
1201
+
1202
+ if ( parents.length === 0 ) {
1203
+ grid.treeBase.tree.push( newNode );
1204
+ } else {
1205
+ parents[parents.length - 1].treeNode.children.push( newNode );
1206
+ }
1207
+ },
1208
+
1209
+
1210
+ /**
1211
+ * @ngdoc function
1212
+ * @name setCurrentState
1213
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
1214
+ * @description Looks at the parents array to determine our current state.
1215
+ * If any node in the hierarchy is collapsed, then return collapsed, otherwise return
1216
+ * expanded.
1217
+ *
1218
+ * @param {array} parents An array of the parents this row should have
1219
+ * @returns {string} The state we should be setting to any nodes we see
1220
+ */
1221
+ setCurrentState: function( parents ) {
1222
+ var currentState = uiGridTreeBaseConstants.EXPANDED;
1223
+
1224
+ parents.forEach( function(parent) {
1225
+ if ( parent.treeNode.state === uiGridTreeBaseConstants.COLLAPSED ) {
1226
+ currentState = uiGridTreeBaseConstants.COLLAPSED;
1227
+ }
1228
+ });
1229
+ return currentState;
1230
+ },
1231
+
1232
+
1233
+ /**
1234
+ * @ngdoc function
1235
+ * @name sortTree
1236
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
1237
+ * @description Performs a recursive sort on the tree nodes, sorting the
1238
+ * children of each node and putting them back into the children array.
1239
+ *
1240
+ * Before doing this it turns back on all the sortIgnore - things that were previously
1241
+ * ignored we process now. Since we're sorting within the nodes, presumably anything
1242
+ * that was already sorted is how we derived the nodes, we can keep those sorts too.
1243
+ *
1244
+ * We only sort tree nodes that are expanded - no point in wasting effort sorting collapsed
1245
+ * nodes
1246
+ *
1247
+ * @param {Grid} grid The grid to get the aggregation information from
1248
+ * @returns {array} The aggregation information
1249
+ */
1250
+ sortTree: function( grid ) {
1251
+ grid.columns.forEach( function( column ) {
1252
+ if ( column.sort && column.sort.ignoreSort ) {
1253
+ delete column.sort.ignoreSort;
1254
+ }
1255
+ });
1256
+
1257
+ grid.treeBase.tree = service.sortInternal( grid, grid.treeBase.tree );
1258
+ },
1259
+
1260
+ sortInternal: function( grid, treeList ) {
1261
+ var rows = treeList.map( function( node ) {
1262
+ return node.row;
1263
+ });
1264
+
1265
+ rows = rowSorter.sort( grid, rows, grid.columns );
1266
+
1267
+ var treeNodes = rows.map( function( row ) {
1268
+ return row.treeNode;
1269
+ });
1270
+
1271
+ treeNodes.forEach( function( node ) {
1272
+ if ( node.state === uiGridTreeBaseConstants.EXPANDED && node.children && node.children.length > 0 ) {
1273
+ node.children = service.sortInternal( grid, node.children );
1274
+ }
1275
+ });
1276
+
1277
+ return treeNodes;
1278
+ },
1279
+
1280
+ /**
1281
+ * @ngdoc function
1282
+ * @name fixFilter
1283
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
1284
+ * @description After filtering has run, we need to go back through the tree
1285
+ * and make sure the parent rows are always visible if any of the child rows
1286
+ * are visible (filtering may make a child visible, but the parent may not
1287
+ * match the filter criteria)
1288
+ *
1289
+ * This has a risk of being computationally expensive, we do it by walking
1290
+ * the tree and remembering whether there are any invisible nodes on the
1291
+ * way down.
1292
+ *
1293
+ * @param {Grid} grid the grid to fix filters on
1294
+ */
1295
+ fixFilter: function( grid ) {
1296
+ var parentsVisible;
1297
+
1298
+ grid.treeBase.tree.forEach( function( node ) {
1299
+ if ( node.children && node.children.length > 0 ) {
1300
+ parentsVisible = node.row.visible;
1301
+ service.fixFilterInternal( node.children, parentsVisible );
1302
+ }
1303
+ });
1304
+ },
1305
+
1306
+ fixFilterInternal: function( nodes, parentsVisible) {
1307
+ nodes.forEach(function( node ) {
1308
+ if ( node.row.visible && !parentsVisible ) {
1309
+ service.setParentsVisible( node );
1310
+ parentsVisible = true;
1311
+ }
1312
+
1313
+ if ( node.children && node.children.length > 0 ) {
1314
+ if ( service.fixFilterInternal( node.children, ( parentsVisible && node.row.visible ) ) ) {
1315
+ parentsVisible = true;
1316
+ }
1317
+ }
1318
+ });
1319
+
1320
+ return parentsVisible;
1321
+ },
1322
+
1323
+ setParentsVisible: function( node ) {
1324
+ while ( node.parentRow ) {
1325
+ node.parentRow.visible = true;
1326
+ node = node.parentRow.treeNode;
1327
+ }
1328
+ },
1329
+
1330
+ /**
1331
+ * @ngdoc function
1332
+ * @name buildAggregationObject
1333
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
1334
+ * @description Build the object which is stored on the column for holding meta-data about the aggregation.
1335
+ * This method should only be called with columns which have an aggregation.
1336
+ *
1337
+ * @param {GridColumn} column The column which this object relates to
1338
+ * @returns {object} {col: GridColumn object, label: string, type: string (optional)}
1339
+ */
1340
+ buildAggregationObject: function( column ) {
1341
+ var newAggregation = { col: column };
1342
+
1343
+ if ( column.treeAggregation && column.treeAggregation.type ) {
1344
+ newAggregation.type = column.treeAggregation.type;
1345
+ }
1346
+
1347
+ if ( column.treeAggregation && column.treeAggregation.label ) {
1348
+ newAggregation.label = column.treeAggregation.label;
1349
+ }
1350
+
1351
+ return newAggregation;
1352
+ },
1353
+
1354
+ /**
1355
+ * @ngdoc function
1356
+ * @name getAggregations
1357
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
1358
+ * @description Looks through the grid columns to find those with aggregations,
1359
+ * and collates the aggregation information into an array, returns that array
1360
+ *
1361
+ * @param {Grid} grid the grid to get the aggregation information from
1362
+ * @returns {array} the aggregation information
1363
+ */
1364
+ getAggregations: function( grid ) {
1365
+ var aggregateArray = [];
1366
+
1367
+ grid.columns.forEach( function(column) {
1368
+ if ( typeof(column.treeAggregationFn) !== 'undefined' ) {
1369
+ aggregateArray.push( service.buildAggregationObject(column) );
1370
+
1371
+ if ( grid.options.showColumnFooter && typeof(column.colDef.aggregationType) === 'undefined' && column.treeAggregation ) {
1372
+ // Add aggregation object for footer
1373
+ column.treeFooterAggregation = service.buildAggregationObject(column);
1374
+ column.aggregationType = service.treeFooterAggregationType;
1375
+ }
1376
+ }
1377
+ });
1378
+ return aggregateArray;
1379
+ },
1380
+
1381
+
1382
+ /**
1383
+ * @ngdoc function
1384
+ * @name aggregate
1385
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
1386
+ * @description Accumulate the data from this row onto the aggregations for each parent
1387
+ *
1388
+ * Iterate over the parents, then iterate over the aggregations for each of those parents,
1389
+ * and perform the aggregation for each individual aggregation
1390
+ *
1391
+ * @param {Grid} grid grid object
1392
+ * @param {GridRow} row the row we want to set grouping visibility on
1393
+ * @param {array} parents the parents that we would want to aggregate onto
1394
+ */
1395
+ aggregate: function( grid, row, parents ) {
1396
+ if (parents.length === 0 && row.treeNode && row.treeNode.aggregations) {
1397
+ row.treeNode.aggregations.forEach(function(aggregation) {
1398
+ // Calculate aggregations for footer even if there are no grouped rows
1399
+ if (typeof(aggregation.col.treeFooterAggregation) !== 'undefined') {
1400
+ var fieldValue = grid.getCellValue(row, aggregation.col);
1401
+ var numValue = Number(fieldValue);
1402
+ if (aggregation.col.treeAggregationFn) {
1403
+ aggregation.col.treeAggregationFn(aggregation.col.treeFooterAggregation, fieldValue, numValue, row);
1404
+ } else {
1405
+ aggregation.col.treeFooterAggregation.value = undefined;
1406
+ }
1407
+ }
1408
+ });
1409
+ }
1410
+
1411
+ parents.forEach( function( parent, index ) {
1412
+ if (parent.treeNode.aggregations) {
1413
+ parent.treeNode.aggregations.forEach( function( aggregation ) {
1414
+ var fieldValue = grid.getCellValue(row, aggregation.col);
1415
+ var numValue = Number(fieldValue);
1416
+ aggregation.col.treeAggregationFn(aggregation, fieldValue, numValue, row);
1417
+
1418
+ if (index === 0 && typeof(aggregation.col.treeFooterAggregation) !== 'undefined') {
1419
+ if (aggregation.col.treeAggregationFn) {
1420
+ aggregation.col.treeAggregationFn(aggregation.col.treeFooterAggregation, fieldValue, numValue, row);
1421
+ } else {
1422
+ aggregation.col.treeFooterAggregation.value = undefined;
1423
+ }
1424
+ }
1425
+ });
1426
+ }
1427
+ });
1428
+ },
1429
+
1430
+
1431
+ // Aggregation routines - no doco needed as self evident
1432
+ nativeAggregations: function() {
1433
+ return {
1434
+ count: {
1435
+ label: i18nService.get().aggregation.count,
1436
+ menuTitle: i18nService.get().grouping.aggregate_count,
1437
+ aggregationFn: function (aggregation, fieldValue, numValue) {
1438
+ if (typeof(aggregation.value) === 'undefined') {
1439
+ aggregation.value = 1;
1440
+ } else {
1441
+ aggregation.value++;
1442
+ }
1443
+ }
1444
+ },
1445
+
1446
+ sum: {
1447
+ label: i18nService.get().aggregation.sum,
1448
+ menuTitle: i18nService.get().grouping.aggregate_sum,
1449
+ aggregationFn: function( aggregation, fieldValue, numValue ) {
1450
+ if (!isNaN(numValue)) {
1451
+ if (typeof(aggregation.value) === 'undefined') {
1452
+ aggregation.value = numValue;
1453
+ } else {
1454
+ aggregation.value += numValue;
1455
+ }
1456
+ }
1457
+ }
1458
+ },
1459
+
1460
+ min: {
1461
+ label: i18nService.get().aggregation.min,
1462
+ menuTitle: i18nService.get().grouping.aggregate_min,
1463
+ aggregationFn: function( aggregation, fieldValue, numValue ) {
1464
+ if (typeof(aggregation.value) === 'undefined') {
1465
+ aggregation.value = fieldValue;
1466
+ } else {
1467
+ if (typeof(fieldValue) !== 'undefined' && fieldValue !== null && (fieldValue < aggregation.value || aggregation.value === null)) {
1468
+ aggregation.value = fieldValue;
1469
+ }
1470
+ }
1471
+ }
1472
+ },
1473
+
1474
+ max: {
1475
+ label: i18nService.get().aggregation.max,
1476
+ menuTitle: i18nService.get().grouping.aggregate_max,
1477
+ aggregationFn: function( aggregation, fieldValue, numValue ) {
1478
+ if ( typeof(aggregation.value) === 'undefined' ) {
1479
+ aggregation.value = fieldValue;
1480
+ } else {
1481
+ if ( typeof(fieldValue) !== 'undefined' && fieldValue !== null && (fieldValue > aggregation.value || aggregation.value === null)) {
1482
+ aggregation.value = fieldValue;
1483
+ }
1484
+ }
1485
+ }
1486
+ },
1487
+
1488
+ avg: {
1489
+ label: i18nService.get().aggregation.avg,
1490
+ menuTitle: i18nService.get().grouping.aggregate_avg,
1491
+ aggregationFn: function( aggregation, fieldValue, numValue ) {
1492
+ if ( typeof(aggregation.count) === 'undefined' ) {
1493
+ aggregation.count = 1;
1494
+ } else {
1495
+ aggregation.count++;
1496
+ }
1497
+
1498
+ if ( isNaN(numValue) ) {
1499
+ return;
1500
+ }
1501
+
1502
+ if ( typeof(aggregation.value) === 'undefined' || typeof(aggregation.sum) === 'undefined' ) {
1503
+ aggregation.value = numValue;
1504
+ aggregation.sum = numValue;
1505
+ } else {
1506
+ aggregation.sum += numValue;
1507
+ aggregation.value = aggregation.sum / aggregation.count;
1508
+ }
1509
+ }
1510
+ }
1511
+ };
1512
+ },
1513
+
1514
+ /**
1515
+ * @ngdoc function
1516
+ * @name finaliseAggregation
1517
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
1518
+ * @description Helper function used to finalize aggregation nodes and footer cells
1519
+ *
1520
+ * @param {gridRow} row The parent we're finalising
1521
+ * @param {aggregation} aggregation The aggregation object manipulated by the aggregationFn
1522
+ */
1523
+ finaliseAggregation: function(row, aggregation) {
1524
+ if ( aggregation.col.treeAggregationUpdateEntity && typeof(row) !== 'undefined' && typeof(row.entity[ '$$' + aggregation.col.uid ]) !== 'undefined' ) {
1525
+ angular.extend( aggregation, row.entity[ '$$' + aggregation.col.uid ]);
1526
+ }
1527
+
1528
+ if ( typeof(aggregation.col.treeAggregationFinalizerFn) === 'function' ) {
1529
+ aggregation.col.treeAggregationFinalizerFn( aggregation );
1530
+ }
1531
+ if ( typeof(aggregation.col.customTreeAggregationFinalizerFn) === 'function' ) {
1532
+ aggregation.col.customTreeAggregationFinalizerFn( aggregation );
1533
+ }
1534
+ if ( typeof(aggregation.rendered) === 'undefined' ) {
1535
+ aggregation.rendered = aggregation.label ? aggregation.label + aggregation.value : aggregation.value;
1536
+ }
1537
+ },
1538
+
1539
+ /**
1540
+ * @ngdoc function
1541
+ * @name finaliseAggregations
1542
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
1543
+ * @description Format the data from the aggregation into the rendered text
1544
+ * e.g. if we had label: 'sum: ' and value: 25, we'd create 'sum: 25'.
1545
+ *
1546
+ * As part of this we call any formatting callback routines we've been provided.
1547
+ *
1548
+ * We write our aggregation out to the row.entity if treeAggregationUpdateEntity is
1549
+ * set on the column - we don't overwrite any information that's already there, we append
1550
+ * to it so that grouping can have set the groupVal beforehand without us overwriting it.
1551
+ *
1552
+ * We need to copy the data from the row.entity first before we finalise the aggregation,
1553
+ * we need that information for the finaliserFn
1554
+ *
1555
+ * @param {gridRow} row the parent we're finalising
1556
+ */
1557
+ finaliseAggregations: function( row ) {
1558
+ if ( row == null || typeof(row.treeNode.aggregations) === 'undefined' ) {
1559
+ return;
1560
+ }
1561
+
1562
+ row.treeNode.aggregations.forEach( function( aggregation ) {
1563
+ service.finaliseAggregation(row, aggregation);
1564
+
1565
+ if ( aggregation.col.treeAggregationUpdateEntity ) {
1566
+ var aggregationCopy = {};
1567
+
1568
+ angular.forEach( aggregation, function( value, key ) {
1569
+ if ( aggregation.hasOwnProperty(key) && key !== 'col' ) {
1570
+ aggregationCopy[key] = value;
1571
+ }
1572
+ });
1573
+
1574
+ row.entity[ '$$' + aggregation.col.uid ] = aggregationCopy;
1575
+ }
1576
+ });
1577
+ },
1578
+
1579
+ /**
1580
+ * @ngdoc function
1581
+ * @name treeFooterAggregationType
1582
+ * @methodOf ui.grid.treeBase.service:uiGridTreeBaseService
1583
+ * @description Uses the tree aggregation functions and finalizers to set the
1584
+ * column footer aggregations.
1585
+ *
1586
+ * @param {rows} rows The visible rows. not used, but accepted to match signature of GridColumn.aggregationType
1587
+ * @param {GridColumn} column The column we are finalizing
1588
+ */
1589
+ treeFooterAggregationType: function( rows, column ) {
1590
+ service.finaliseAggregation(undefined, column.treeFooterAggregation);
1591
+ if ( typeof(column.treeFooterAggregation.value) === 'undefined' || column.treeFooterAggregation.rendered === null ) {
1592
+ // The was apparently no aggregation performed (perhaps this is a grouped column
1593
+ return '';
1594
+ }
1595
+ return column.treeFooterAggregation.rendered;
1596
+ }
1597
+ };
1598
+
1599
+ return service;
1600
+ }]);
1601
+
1602
+
1603
+ /**
1604
+ * @ngdoc directive
1605
+ * @name ui.grid.treeBase.directive:uiGridTreeRowHeaderButtons
1606
+ * @element div
1607
+ *
1608
+ * @description Provides the expand/collapse button on rows
1609
+ */
1610
+ module.directive('uiGridTreeBaseRowHeaderButtons', ['$templateCache', 'uiGridTreeBaseService',
1611
+ function ($templateCache, uiGridTreeBaseService) {
1612
+ return {
1613
+ replace: true,
1614
+ restrict: 'E',
1615
+ template: $templateCache.get('ui-grid/treeBaseRowHeaderButtons'),
1616
+ scope: true,
1617
+ require: '^uiGrid',
1618
+ link: function($scope, $elm, $attrs, uiGridCtrl) {
1619
+ var self = uiGridCtrl.grid;
1620
+ $scope.treeButtonClass = function(row) {
1621
+ if ( ( self.options.showTreeExpandNoChildren && row.treeLevel > -1 ) || ( row.treeNode.children && row.treeNode.children.length > 0 ) ) {
1622
+ if (row.treeNode.state === 'expanded' ) {
1623
+ return 'ui-grid-icon-minus-squared';
1624
+ }
1625
+ if (row.treeNode.state === 'collapsed' ) {
1626
+ return 'ui-grid-icon-plus-squared';
1627
+ }
1628
+ }
1629
+ };
1630
+ $scope.treeButtonClick = function(row, evt) {
1631
+ evt.stopPropagation();
1632
+ uiGridTreeBaseService.toggleRowTreeState(self, row, evt);
1633
+ };
1634
+ $scope.treeButtonKeyDown = function (row, evt) {
1635
+ if (evt.keyCode === 32 || evt.keyCode === 13) {
1636
+ $scope.treeButtonClick(row, evt);
1637
+ }
1638
+ };
1639
+ }
1640
+ };
1641
+ }]);
1642
+
1643
+
1644
+ /**
1645
+ * @ngdoc directive
1646
+ * @name ui.grid.treeBase.directive:uiGridTreeBaseExpandAllButtons
1647
+ * @element div
1648
+ *
1649
+ * @description Provides the expand/collapse all button
1650
+ */
1651
+ module.directive('uiGridTreeBaseExpandAllButtons', ['$templateCache', 'uiGridTreeBaseService',
1652
+ function ($templateCache, uiGridTreeBaseService) {
1653
+ return {
1654
+ replace: true,
1655
+ restrict: 'E',
1656
+ template: $templateCache.get('ui-grid/treeBaseExpandAllButtons'),
1657
+ scope: false,
1658
+ link: function($scope) {
1659
+ var self = $scope.col.grid;
1660
+ $scope.headerButtonClass = function() {
1661
+ if (self.treeBase.numberLevels > 0 && self.treeBase.expandAll) {
1662
+ return 'ui-grid-icon-minus-squared';
1663
+ }
1664
+ if (self.treeBase.numberLevels > 0 && !self.treeBase.expandAll) {
1665
+ return 'ui-grid-icon-plus-squared';
1666
+ }
1667
+ };
1668
+ $scope.headerButtonClick = function(row, evt) {
1669
+ if ( self.treeBase.expandAll ) {
1670
+ uiGridTreeBaseService.collapseAllRows(self, evt);
1671
+ } else {
1672
+ uiGridTreeBaseService.expandAllRows(self, evt);
1673
+ }
1674
+ };
1675
+ $scope.headerButtonKeyDown = function (evt) {
1676
+ if (evt.keyCode === 32 || evt.keyCode === 13) {
1677
+ $scope.headerButtonClick(self, evt);
1678
+ }
1679
+ };
1680
+ }
1681
+ };
1682
+ }]);
1683
+
1684
+
1685
+ /**
1686
+ * @ngdoc directive
1687
+ * @name ui.grid.treeBase.directive:uiGridViewport
1688
+ * @element div
1689
+ *
1690
+ * @description Stacks on top of ui.grid.uiGridViewport to set formatting on a tree header row
1691
+ */
1692
+ module.directive('uiGridViewport',
1693
+ function () {
1694
+ return {
1695
+ priority: -200, // run after default directive
1696
+ scope: false,
1697
+ compile: function ($elm) {
1698
+ var rowRepeatDiv = angular.element($elm.children().children()[0]);
1699
+
1700
+ var existingNgClass = rowRepeatDiv.attr("ng-class");
1701
+ var newNgClass = '';
1702
+ if ( existingNgClass ) {
1703
+ newNgClass = existingNgClass.slice(0, -1) + ",'ui-grid-tree-header-row': row.treeLevel > -1}";
1704
+ } else {
1705
+ newNgClass = "{'ui-grid-tree-header-row': row.treeLevel > -1}";
1706
+ }
1707
+ rowRepeatDiv.attr("ng-class", newNgClass);
1708
+
1709
+ return {
1710
+ pre: function ($scope, $elm, $attrs, controllers) {
1711
+
1712
+ },
1713
+ post: function ($scope, $elm, $attrs, controllers) {
1714
+ }
1715
+ };
1716
+ }
1717
+ };
1718
+ });
1719
+ })();
1720
+
1721
+ angular.module('ui.grid.treeBase').run(['$templateCache', function($templateCache) {
1722
+ 'use strict';
1723
+
1724
+ $templateCache.put('ui-grid/treeBaseExpandAllButtons',
1725
+ "<div class=\"ui-grid-tree-base-row-header-buttons\" tabindex=\"0\" ng-class=\"headerButtonClass()\" ng-click=\"headerButtonClick($event)\" ng-keydown=\"headerButtonKeyDown($event)\"></div>"
1726
+ );
1727
+
1728
+
1729
+ $templateCache.put('ui-grid/treeBaseHeaderCell',
1730
+ "<div><div class=\"ui-grid-cell-contents\" col-index=\"renderIndex\"><ui-grid-tree-base-expand-all-buttons ng-if=\"grid.options.enableExpandAll\"></ui-grid-tree-base-expand-all-buttons></div></div>"
1731
+ );
1732
+
1733
+
1734
+ $templateCache.put('ui-grid/treeBaseRowHeader',
1735
+ "<div class=\"ui-grid-cell-contents\"><ui-grid-tree-base-row-header-buttons></ui-grid-tree-base-row-header-buttons></div>"
1736
+ );
1737
+
1738
+
1739
+ $templateCache.put('ui-grid/treeBaseRowHeaderButtons',
1740
+ "<div class=\"ui-grid-tree-base-row-header-buttons\" ng-class=\"{'ui-grid-tree-base-header': row.treeLevel > -1 }\" tabindex=\"0\" ng-keydown=\"treeButtonKeyDown(row, $event)\" ng-click=\"treeButtonClick(row, $event)\"><i ng-class=\"treeButtonClass(row)\" ng-style=\"{'padding-left': grid.options.treeIndent * row.treeLevel + 'px'}\"></i> &nbsp;</div>"
1741
+ );
1742
+
1743
+ }]);