@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.
- package/chunk-A3NTIEMP.js +1 -0
- package/chunk-CAY35YP7.js +7 -0
- package/chunk-H3QHLLCN.js +1 -0
- package/chunk-KE4BCZO4.js +851 -0
- package/chunk-OHPEWN32.js +1198 -0
- package/chunk-WSQOM5HU.js +1 -0
- package/component-lib.js +1 -0
- package/index.html +12 -0
- package/main.js +3264 -0
- package/modules/angular/LICENSE.md +21 -0
- package/modules/angular/README.md +67 -0
- package/modules/angular/angular-csp.css +25 -0
- package/modules/angular/angular.js +36600 -0
- package/modules/angular/angular.min.js +352 -0
- package/modules/angular/angular.min.js.gzip +0 -0
- package/modules/angular/angular.min.js.map +8 -0
- package/modules/angular/bower.json +9 -0
- package/modules/angular/index.js +2 -0
- package/modules/angular/package.json +25 -0
- package/modules/angular-ui-grid/CHANGELOG.md +1973 -0
- package/modules/angular-ui-grid/README.md +59 -0
- package/modules/angular-ui-grid/css/ui-grid.cellnav.css +25 -0
- package/modules/angular-ui-grid/css/ui-grid.cellnav.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.core.css +866 -0
- package/modules/angular-ui-grid/css/ui-grid.core.min.css +5 -0
- package/modules/angular-ui-grid/css/ui-grid.edit.css +23 -0
- package/modules/angular-ui-grid/css/ui-grid.edit.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.empty-base-layer.css +6 -0
- package/modules/angular-ui-grid/css/ui-grid.empty-base-layer.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.expandable.css +16 -0
- package/modules/angular-ui-grid/css/ui-grid.expandable.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.exporter.css +0 -0
- package/modules/angular-ui-grid/css/ui-grid.exporter.min.css +0 -0
- package/modules/angular-ui-grid/css/ui-grid.grouping.css +3 -0
- package/modules/angular-ui-grid/css/ui-grid.grouping.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.importer.css +0 -0
- package/modules/angular-ui-grid/css/ui-grid.importer.min.css +0 -0
- package/modules/angular-ui-grid/css/ui-grid.move-columns.css +9 -0
- package/modules/angular-ui-grid/css/ui-grid.move-columns.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.pagination.css +299 -0
- package/modules/angular-ui-grid/css/ui-grid.pagination.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.pinning.css +67 -0
- package/modules/angular-ui-grid/css/ui-grid.pinning.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.resize-columns.css +38 -0
- package/modules/angular-ui-grid/css/ui-grid.resize-columns.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.row-edit.css +9 -0
- package/modules/angular-ui-grid/css/ui-grid.row-edit.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.selection.css +25 -0
- package/modules/angular-ui-grid/css/ui-grid.selection.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.tree-base.css +4 -0
- package/modules/angular-ui-grid/css/ui-grid.tree-base.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.tree-view.css +6 -0
- package/modules/angular-ui-grid/css/ui-grid.tree-view.min.css +1 -0
- package/modules/angular-ui-grid/css/ui-grid.validate.css +3 -0
- package/modules/angular-ui-grid/css/ui-grid.validate.min.css +1 -0
- package/modules/angular-ui-grid/fonts/ui-grid.eot +0 -0
- package/modules/angular-ui-grid/fonts/ui-grid.svg +56 -0
- package/modules/angular-ui-grid/fonts/ui-grid.ttf +0 -0
- package/modules/angular-ui-grid/fonts/ui-grid.woff +0 -0
- package/modules/angular-ui-grid/less/animation.less +85 -0
- package/modules/angular-ui-grid/less/body.less +84 -0
- package/modules/angular-ui-grid/less/cell.less +46 -0
- package/modules/angular-ui-grid/less/cellnav.less +29 -0
- package/modules/angular-ui-grid/less/core.less +11 -0
- package/modules/angular-ui-grid/less/edit.less +27 -0
- package/modules/angular-ui-grid/less/elements.less +156 -0
- package/modules/angular-ui-grid/less/emptyBaseLayer.less +8 -0
- package/modules/angular-ui-grid/less/expandable.less +29 -0
- package/modules/angular-ui-grid/less/exporter.less +4 -0
- package/modules/angular-ui-grid/less/footer.less +76 -0
- package/modules/angular-ui-grid/less/grid.less +86 -0
- package/modules/angular-ui-grid/less/grouping.less +5 -0
- package/modules/angular-ui-grid/less/header.less +250 -0
- package/modules/angular-ui-grid/less/icons.less +151 -0
- package/modules/angular-ui-grid/less/importer.less +4 -0
- package/modules/angular-ui-grid/less/main.less +2 -0
- package/modules/angular-ui-grid/less/menu.less +91 -0
- package/modules/angular-ui-grid/less/moveColumns.less +12 -0
- package/modules/angular-ui-grid/less/pagination.less +297 -0
- package/modules/angular-ui-grid/less/pinning.less +86 -0
- package/modules/angular-ui-grid/less/resizeColumns.less +53 -0
- package/modules/angular-ui-grid/less/rowEdit.less +19 -0
- package/modules/angular-ui-grid/less/rtl.less +67 -0
- package/modules/angular-ui-grid/less/selection.less +29 -0
- package/modules/angular-ui-grid/less/sorting.less +16 -0
- package/modules/angular-ui-grid/less/treeBase.less +6 -0
- package/modules/angular-ui-grid/less/treeView.less +8 -0
- package/modules/angular-ui-grid/less/validate.less +5 -0
- package/modules/angular-ui-grid/less/variables.less +90 -0
- package/modules/angular-ui-grid/package.json +144 -0
- package/modules/angular-ui-grid/ui-grid.auto-resize.js +69 -0
- package/modules/angular-ui-grid/ui-grid.auto-resize.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.cellnav.js +1181 -0
- package/modules/angular-ui-grid/ui-grid.cellnav.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.core.js +12737 -0
- package/modules/angular-ui-grid/ui-grid.core.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.css +3208 -0
- package/modules/angular-ui-grid/ui-grid.edit.js +1325 -0
- package/modules/angular-ui-grid/ui-grid.edit.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.empty-base-layer.js +178 -0
- package/modules/angular-ui-grid/ui-grid.empty-base-layer.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.expandable.js +651 -0
- package/modules/angular-ui-grid/ui-grid.expandable.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.exporter.js +1777 -0
- package/modules/angular-ui-grid/ui-grid.exporter.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.grouping.js +1291 -0
- package/modules/angular-ui-grid/ui-grid.grouping.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.importer.js +791 -0
- package/modules/angular-ui-grid/ui-grid.importer.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.infinite-scroll.js +552 -0
- package/modules/angular-ui-grid/ui-grid.infinite-scroll.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.js +30867 -0
- package/modules/angular-ui-grid/ui-grid.language.all.js +3214 -0
- package/modules/angular-ui-grid/ui-grid.language.all.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.ar.js +118 -0
- package/modules/angular-ui-grid/ui-grid.language.ar.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.bg.js +115 -0
- package/modules/angular-ui-grid/ui-grid.language.bg.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.cs.js +96 -0
- package/modules/angular-ui-grid/ui-grid.language.cs.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.da.js +90 -0
- package/modules/angular-ui-grid/ui-grid.language.da.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.de.js +133 -0
- package/modules/angular-ui-grid/ui-grid.language.de.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.es-ct.js +133 -0
- package/modules/angular-ui-grid/ui-grid.language.es-ct.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.es.js +106 -0
- package/modules/angular-ui-grid/ui-grid.language.es.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.fa.js +93 -0
- package/modules/angular-ui-grid/ui-grid.language.fa.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.fi.js +76 -0
- package/modules/angular-ui-grid/ui-grid.language.fi.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.fr.js +128 -0
- package/modules/angular-ui-grid/ui-grid.language.fr.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.he.js +71 -0
- package/modules/angular-ui-grid/ui-grid.language.he.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.hy.js +76 -0
- package/modules/angular-ui-grid/ui-grid.language.hy.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.is.js +118 -0
- package/modules/angular-ui-grid/ui-grid.language.is.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.it.js +112 -0
- package/modules/angular-ui-grid/ui-grid.language.it.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.ja.js +118 -0
- package/modules/angular-ui-grid/ui-grid.language.ja.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.ko.js +77 -0
- package/modules/angular-ui-grid/ui-grid.language.ko.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.nl.js +91 -0
- package/modules/angular-ui-grid/ui-grid.language.nl.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.no.js +115 -0
- package/modules/angular-ui-grid/ui-grid.language.no.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.pl.js +126 -0
- package/modules/angular-ui-grid/ui-grid.language.pl.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.pt-br.js +133 -0
- package/modules/angular-ui-grid/ui-grid.language.pt-br.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.pt.js +133 -0
- package/modules/angular-ui-grid/ui-grid.language.pt.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.ro.js +112 -0
- package/modules/angular-ui-grid/ui-grid.language.ro.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.rs-lat.js +126 -0
- package/modules/angular-ui-grid/ui-grid.language.rs-lat.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.ru.js +115 -0
- package/modules/angular-ui-grid/ui-grid.language.ru.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.sk.js +127 -0
- package/modules/angular-ui-grid/ui-grid.language.sk.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.sv.js +126 -0
- package/modules/angular-ui-grid/ui-grid.language.sv.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.ta.js +87 -0
- package/modules/angular-ui-grid/ui-grid.language.ta.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.tr.js +112 -0
- package/modules/angular-ui-grid/ui-grid.language.tr.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.ua.js +112 -0
- package/modules/angular-ui-grid/ui-grid.language.ua.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.zh-cn.js +112 -0
- package/modules/angular-ui-grid/ui-grid.language.zh-cn.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.language.zh-tw.js +77 -0
- package/modules/angular-ui-grid/ui-grid.language.zh-tw.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.min.css +5 -0
- package/modules/angular-ui-grid/ui-grid.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.move-columns.js +582 -0
- package/modules/angular-ui-grid/ui-grid.move-columns.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.pagination.js +510 -0
- package/modules/angular-ui-grid/ui-grid.pagination.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.pinning.js +281 -0
- package/modules/angular-ui-grid/ui-grid.pinning.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.resize-columns.js +574 -0
- package/modules/angular-ui-grid/ui-grid.resize-columns.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.row-edit.js +717 -0
- package/modules/angular-ui-grid/ui-grid.row-edit.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.saveState.js +831 -0
- package/modules/angular-ui-grid/ui-grid.saveState.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.selection.js +1196 -0
- package/modules/angular-ui-grid/ui-grid.selection.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.tree-base.js +1743 -0
- package/modules/angular-ui-grid/ui-grid.tree-base.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.tree-view.js +218 -0
- package/modules/angular-ui-grid/ui-grid.tree-view.min.js +6 -0
- package/modules/angular-ui-grid/ui-grid.validate.js +589 -0
- package/modules/angular-ui-grid/ui-grid.validate.min.js +6 -0
- package/package.json +8 -0
- package/polyfills.js +2 -0
- 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> </div>"
|
|
1741
|
+
);
|
|
1742
|
+
|
|
1743
|
+
}]);
|