cx 24.3.7 → 24.3.8
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/dist/data.js +46 -15
- package/dist/manifest.js +672 -672
- package/dist/ui.js +11 -9
- package/dist/widgets.js +10 -7
- package/package.json +1 -1
- package/src/data/Grouper.js +144 -120
- package/src/data/Grouper.spec.js +57 -42
- package/src/ui/adapter/GroupAdapter.js +141 -138
- package/src/widgets/grid/Grid.js +10 -6
|
@@ -1,138 +1,141 @@
|
|
|
1
|
-
import { ArrayAdapter } from "./ArrayAdapter";
|
|
2
|
-
import { ReadOnlyDataView } from "../../data/ReadOnlyDataView";
|
|
3
|
-
import { Grouper } from "../../data/Grouper";
|
|
4
|
-
import { isArray } from "../../util/isArray";
|
|
5
|
-
import { isDefined } from "../../util/isDefined";
|
|
6
|
-
import { getComparer } from "../../data/comparer";
|
|
7
|
-
import { Culture } from "../Culture";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
result
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
let
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
let
|
|
44
|
-
grouper
|
|
45
|
-
grouper.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
.
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
let
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
1
|
+
import { ArrayAdapter } from "./ArrayAdapter";
|
|
2
|
+
import { ReadOnlyDataView } from "../../data/ReadOnlyDataView";
|
|
3
|
+
import { Grouper } from "../../data/Grouper";
|
|
4
|
+
import { isArray } from "../../util/isArray";
|
|
5
|
+
import { isDefined } from "../../util/isDefined";
|
|
6
|
+
import { getComparer } from "../../data/comparer";
|
|
7
|
+
import { Culture } from "../Culture";
|
|
8
|
+
import { isObject } from "../../util/isObject";
|
|
9
|
+
|
|
10
|
+
export class GroupAdapter extends ArrayAdapter {
|
|
11
|
+
init() {
|
|
12
|
+
super.init();
|
|
13
|
+
|
|
14
|
+
if (this.groupRecordsAlias) this.groupRecordsName = this.groupRecordsAlias;
|
|
15
|
+
|
|
16
|
+
if (this.groupings) this.groupBy(this.groupings);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
getRecords(context, instance, records, parentStore) {
|
|
20
|
+
let result = super.getRecords(context, instance, records, parentStore);
|
|
21
|
+
|
|
22
|
+
if (this.groupings) {
|
|
23
|
+
let groupedResults = [];
|
|
24
|
+
this.processLevel([], result, groupedResults, parentStore);
|
|
25
|
+
result = groupedResults;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
processLevel(keys, records, result, parentStore) {
|
|
32
|
+
let level = keys.length;
|
|
33
|
+
let inverseLevel = this.groupings.length - level;
|
|
34
|
+
|
|
35
|
+
if (inverseLevel == 0) {
|
|
36
|
+
for (let i = 0; i < records.length; i++) {
|
|
37
|
+
records[i].store.setStore(parentStore);
|
|
38
|
+
result.push(records[i]);
|
|
39
|
+
}
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
let grouping = this.groupings[level];
|
|
44
|
+
let { grouper } = grouping;
|
|
45
|
+
grouper.reset();
|
|
46
|
+
grouper.processAll(records);
|
|
47
|
+
let results = grouper.getResults();
|
|
48
|
+
if (grouping.comparer) results.sort(grouping.comparer);
|
|
49
|
+
|
|
50
|
+
results.forEach((gr) => {
|
|
51
|
+
keys.push(gr.key);
|
|
52
|
+
|
|
53
|
+
let key = keys.map(serializeKey).join("|");
|
|
54
|
+
|
|
55
|
+
let $group = {
|
|
56
|
+
...gr.key,
|
|
57
|
+
...gr.aggregates,
|
|
58
|
+
$name: gr.name,
|
|
59
|
+
$level: inverseLevel,
|
|
60
|
+
$records: gr.records || [],
|
|
61
|
+
$key: key,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
let data = {
|
|
65
|
+
[this.recordName]: gr.records.length > 0 ? gr.records[0].data : null,
|
|
66
|
+
[this.groupName]: $group,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
let groupStore = new ReadOnlyDataView({
|
|
70
|
+
store: parentStore,
|
|
71
|
+
data,
|
|
72
|
+
immutable: this.immutable,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
let group = {
|
|
76
|
+
key,
|
|
77
|
+
data,
|
|
78
|
+
group: $group,
|
|
79
|
+
grouping,
|
|
80
|
+
store: groupStore,
|
|
81
|
+
level: inverseLevel,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
if (grouping.includeHeader !== false)
|
|
85
|
+
result.push({
|
|
86
|
+
...group,
|
|
87
|
+
type: "group-header",
|
|
88
|
+
key: "header:" + group.key,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
this.processLevel(keys, gr.records, result, groupStore);
|
|
92
|
+
|
|
93
|
+
if (grouping.includeFooter !== false)
|
|
94
|
+
result.push({
|
|
95
|
+
...group,
|
|
96
|
+
type: "group-footer",
|
|
97
|
+
key: "footer:" + group.key,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
keys.pop();
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
groupBy(groupings) {
|
|
105
|
+
if (!groupings) this.groupings = null;
|
|
106
|
+
else if (isArray(groupings)) {
|
|
107
|
+
this.groupings = groupings;
|
|
108
|
+
this.groupings.forEach((g) => {
|
|
109
|
+
let groupSorters = [];
|
|
110
|
+
let key = {};
|
|
111
|
+
for (let name in g.key) {
|
|
112
|
+
if (!g.key[name] || !isDefined(g.key[name].direction) || !isDefined(g.key[name].value))
|
|
113
|
+
g.key[name] = { value: g.key[name], direction: "ASC" };
|
|
114
|
+
key[name] = g.key[name].value;
|
|
115
|
+
groupSorters.push({
|
|
116
|
+
field: name,
|
|
117
|
+
direction: g.key[name].direction,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
g.grouper = new Grouper(key, { ...this.aggregates, ...g.aggregates }, (r) => r.store.getData(), g.text);
|
|
121
|
+
g.comparer = null;
|
|
122
|
+
if (groupSorters.length > 0)
|
|
123
|
+
g.comparer = getComparer(
|
|
124
|
+
groupSorters,
|
|
125
|
+
(x) => x.key,
|
|
126
|
+
this.sortOptions ? Culture.getComparer(this.sortOptions) : null,
|
|
127
|
+
);
|
|
128
|
+
});
|
|
129
|
+
} else throw new Error("Invalid grouping provided.");
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
GroupAdapter.prototype.groupName = "$group";
|
|
134
|
+
|
|
135
|
+
function serializeKey(data) {
|
|
136
|
+
if (isObject(data))
|
|
137
|
+
return Object.keys(data)
|
|
138
|
+
.map((k) => serializeKey(data[k]))
|
|
139
|
+
.join(":");
|
|
140
|
+
return data?.toString() ?? "";
|
|
141
|
+
}
|
package/src/widgets/grid/Grid.js
CHANGED
|
@@ -43,6 +43,7 @@ import { unfocusElement } from "../../ui/FocusManager";
|
|
|
43
43
|
import { tooltipMouseMove, tooltipMouseLeave } from "../overlay/tooltip-ops";
|
|
44
44
|
import { Container } from "../../ui/Container";
|
|
45
45
|
import { findFirstChild } from "../../util/DOM";
|
|
46
|
+
import { Binding } from "../../data/Binding";
|
|
46
47
|
|
|
47
48
|
export class Grid extends Container {
|
|
48
49
|
declareData(...args) {
|
|
@@ -910,9 +911,9 @@ export class Grid extends Container {
|
|
|
910
911
|
}
|
|
911
912
|
|
|
912
913
|
if (colSpan > 1) skip = colSpan - 1;
|
|
913
|
-
} else if (c.aggregate && c.
|
|
914
|
+
} else if (c.aggregate && c.aggregateAliasGetter && c.caption !== false) {
|
|
914
915
|
empty = false;
|
|
915
|
-
v =
|
|
916
|
+
v = c.aggregateAliasGetter(group);
|
|
916
917
|
if (isString(ci.data.format)) v = Format.value(v, ci.data.format);
|
|
917
918
|
}
|
|
918
919
|
|
|
@@ -993,9 +994,9 @@ export class Grid extends Container {
|
|
|
993
994
|
}
|
|
994
995
|
|
|
995
996
|
if (colSpan > 1) skip = colSpan - 1;
|
|
996
|
-
} else if (c.aggregate && c.
|
|
997
|
+
} else if (c.aggregate && c.aggregateAliasGetter && c.footer !== false) {
|
|
997
998
|
empty = false;
|
|
998
|
-
v =
|
|
999
|
+
v = c.aggregateAliasGetter(group);
|
|
999
1000
|
if (isString(ci.data.format)) v = Format.value(v, ci.data.format);
|
|
1000
1001
|
}
|
|
1001
1002
|
|
|
@@ -1594,9 +1595,11 @@ class GridComponent extends VDOM.Component {
|
|
|
1594
1595
|
</tbody>
|
|
1595
1596
|
);
|
|
1596
1597
|
|
|
1598
|
+
let dataRecordClass = CSS.element(baseClass, "data");
|
|
1599
|
+
|
|
1597
1600
|
let isDataRecord = widget.buffered
|
|
1598
|
-
? (item) => item
|
|
1599
|
-
: (item) => item
|
|
1601
|
+
? (item) => item?.props?.instance?.data?.class == dataRecordClass
|
|
1602
|
+
: (item) => item?.props?.record?.type;
|
|
1600
1603
|
|
|
1601
1604
|
let index = 0;
|
|
1602
1605
|
while (index < children.length && !isDataRecord(children[index])) index++;
|
|
@@ -3108,6 +3111,7 @@ class GridColumnHeader extends Widget {
|
|
|
3108
3111
|
if (!this.aggregateField && this.field) this.aggregateField = this.field;
|
|
3109
3112
|
|
|
3110
3113
|
if (!this.aggregateAlias) this.aggregateAlias = this.aggregateField;
|
|
3114
|
+
if (this.aggregateAlias) this.aggregateAliasGetter = Binding.get(this.aggregateAlias).value;
|
|
3111
3115
|
|
|
3112
3116
|
if (this.footer && isSelector(this.footer))
|
|
3113
3117
|
this.footer = {
|