cx 24.3.7 → 24.3.9
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/charts.js +35 -35
- package/dist/data.js +83 -42
- package/dist/manifest.js +799 -775
- package/dist/svg.js +11 -11
- package/dist/ui.js +224 -95
- package/dist/util.js +6 -1
- package/dist/widgets.js +151 -154
- package/package.json +1 -1
- package/src/data/Expression.d.ts +17 -16
- package/src/data/Expression.js +220 -212
- package/src/data/Grouper.js +144 -120
- package/src/data/Grouper.spec.js +57 -42
- package/src/data/StringTemplate.d.ts +15 -14
- package/src/data/StringTemplate.js +92 -85
- package/src/ui/Culture.d.ts +47 -23
- package/src/ui/Culture.js +132 -76
- package/src/ui/CultureScope.d.ts +10 -0
- package/src/ui/CultureScope.js +53 -0
- package/src/ui/Format.js +107 -87
- package/src/ui/adapter/GroupAdapter.js +141 -138
- package/src/ui/index.d.ts +43 -42
- package/src/ui/index.js +45 -44
- package/src/util/Format.d.ts +18 -14
- package/src/util/Format.js +234 -242
- package/src/widgets/grid/Grid.js +10 -6
package/src/util/Format.js
CHANGED
|
@@ -1,242 +1,234 @@
|
|
|
1
|
-
import {debug} from "./Debug";
|
|
2
|
-
import {GlobalCacheIdentifier} from
|
|
3
|
-
import {isNumber} from
|
|
4
|
-
import {isUndefined} from
|
|
5
|
-
import {isArray} from
|
|
6
|
-
|
|
7
|
-
//Culture dependent formatters are defined in the ui package.
|
|
8
|
-
|
|
9
|
-
const defaultFormatter = v => v.toString();
|
|
10
|
-
|
|
11
|
-
let formatFactory = {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
formatFactory.
|
|
136
|
-
formatFactory.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
return
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
static
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
static
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
export function trimFractionZeros(str, max) {
|
|
237
|
-
let cnt = 0, l = str.length;
|
|
238
|
-
while (cnt < max && (str[l - 1 - cnt] === '0' || str[l - 1 - cnt] === '.'))
|
|
239
|
-
cnt++;
|
|
240
|
-
|
|
241
|
-
return cnt > 0 ? str.substring(0, l - cnt) : str;
|
|
242
|
-
}
|
|
1
|
+
import { debug } from "./Debug";
|
|
2
|
+
import { GlobalCacheIdentifier } from "./GlobalCacheIdentifier";
|
|
3
|
+
import { isNumber } from "../util/isNumber";
|
|
4
|
+
import { isUndefined } from "../util/isUndefined";
|
|
5
|
+
import { isArray } from "../util/isArray";
|
|
6
|
+
|
|
7
|
+
//Culture dependent formatters are defined in the ui package.
|
|
8
|
+
|
|
9
|
+
const defaultFormatter = (v) => v.toString();
|
|
10
|
+
|
|
11
|
+
let formatFactory = {
|
|
12
|
+
string: function () {
|
|
13
|
+
return defaultFormatter;
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
wrap: function (part0, prefix, suffix) {
|
|
17
|
+
if (!prefix) prefix = "";
|
|
18
|
+
|
|
19
|
+
if (!suffix) suffix = "";
|
|
20
|
+
|
|
21
|
+
return (value) => prefix + value.toString() + suffix;
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
fixed: function (part0, digits) {
|
|
25
|
+
return (value) => value.toFixed(digits);
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
prefix: function (part0, prefix) {
|
|
29
|
+
if (!prefix) prefix = "";
|
|
30
|
+
|
|
31
|
+
return (value) => prefix + value.toString();
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
suffix: function (part0, suffix) {
|
|
35
|
+
if (!suffix) suffix = "";
|
|
36
|
+
|
|
37
|
+
return (value) => value.toString() + suffix;
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
uppercase: function () {
|
|
41
|
+
return (value) => value.toString().toUpperCase();
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
lowercase: function () {
|
|
45
|
+
return (value) => value.toString().toLowerCase();
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
urlencode: function () {
|
|
49
|
+
return (value) => encodeURIComponent(value);
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
number: function (part0, minFractionDigits, maxFractionDigits) {
|
|
53
|
+
let { minimumFractionDigits, maximumFractionDigits } = resolveMinMaxFractionDigits(
|
|
54
|
+
minFractionDigits,
|
|
55
|
+
maxFractionDigits,
|
|
56
|
+
);
|
|
57
|
+
let trimmable = maximumFractionDigits - minimumFractionDigits;
|
|
58
|
+
if (trimmable > 0) {
|
|
59
|
+
if (minimumFractionDigits == 0) ++trimmable;
|
|
60
|
+
return (value) => trimFractionZeros(value.toFixed(maximumFractionDigits), trimmable);
|
|
61
|
+
}
|
|
62
|
+
return (value) => value.toFixed(maximumFractionDigits);
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
percentage: function (part0, minFractionDigits, maxFractionDigits) {
|
|
66
|
+
let numberFormatter = formatFactory.number(part0, minFractionDigits, maxFractionDigits);
|
|
67
|
+
return (value) => numberFormatter(value * 100) + "%";
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
percentageSign: function (part0, minFractionDigits, maxFractionDigits) {
|
|
71
|
+
let numberFormatter = formatFactory.number(part0, minFractionDigits, maxFractionDigits);
|
|
72
|
+
return (value) => numberFormatter(value) + "%";
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
date: function () {
|
|
76
|
+
return (value) => {
|
|
77
|
+
let date = new Date(value);
|
|
78
|
+
return `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()}`;
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
time: function () {
|
|
83
|
+
return (value) => {
|
|
84
|
+
let date = new Date(value);
|
|
85
|
+
let h = date.getHours() >= 10 ? date.getHours() : "0" + date.getHours();
|
|
86
|
+
let m = date.getMinutes() >= 10 ? date.getMinutes() : "0" + date.getMinutes();
|
|
87
|
+
return `${h}:${m}`;
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
datetime: function () {
|
|
92
|
+
let date = formatFactory.date();
|
|
93
|
+
let time = formatFactory.time();
|
|
94
|
+
return (value) => date(value) + " " + time(value);
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
ellipsis: function (part0, length, where) {
|
|
98
|
+
length = Number(length);
|
|
99
|
+
if (!(length > 3)) length = 10;
|
|
100
|
+
switch (where) {
|
|
101
|
+
default:
|
|
102
|
+
case "end":
|
|
103
|
+
return (value) => {
|
|
104
|
+
let s = String(value);
|
|
105
|
+
if (s.length > length) return s.substring(0, length - 3) + "...";
|
|
106
|
+
return s;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
case "start":
|
|
110
|
+
return (value) => {
|
|
111
|
+
let s = String(value);
|
|
112
|
+
if (s.length > length) return "..." + s.substring(s.length - length + 3);
|
|
113
|
+
return s;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
case "middle":
|
|
117
|
+
return (value) => {
|
|
118
|
+
let s = String(value);
|
|
119
|
+
if (s.length > length) {
|
|
120
|
+
let x = Math.floor(length - 2) / 2;
|
|
121
|
+
return s.substring(0, x) + "..." + s.substring(s.length - (length - 3 - x));
|
|
122
|
+
}
|
|
123
|
+
return s;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
formatFactory.s = formatFactory.str = formatFactory.string;
|
|
130
|
+
formatFactory.f = formatFactory.fixed;
|
|
131
|
+
formatFactory.n = formatFactory.number;
|
|
132
|
+
formatFactory.p = formatFactory.percentage;
|
|
133
|
+
formatFactory.ps = formatFactory.percentageSign;
|
|
134
|
+
formatFactory.d = formatFactory.date;
|
|
135
|
+
formatFactory.t = formatFactory.time;
|
|
136
|
+
formatFactory.dt = formatFactory.datetime;
|
|
137
|
+
|
|
138
|
+
function buildFormatter(format) {
|
|
139
|
+
let formatter = defaultFormatter,
|
|
140
|
+
nullText = "";
|
|
141
|
+
if (format) {
|
|
142
|
+
let pipeParts = format.split("|");
|
|
143
|
+
nullText = pipeParts[1] || "";
|
|
144
|
+
let colonSepParts = pipeParts[0].split(":");
|
|
145
|
+
for (let i = 0; i < colonSepParts.length; i++) {
|
|
146
|
+
let parts = colonSepParts[i].split(";");
|
|
147
|
+
let factory = formatFactory[parts[0]];
|
|
148
|
+
if (!factory) debug("Unknown string format: " + format);
|
|
149
|
+
else if (i == 0) formatter = factory(...parts);
|
|
150
|
+
else {
|
|
151
|
+
let outerFmt = factory(...parts);
|
|
152
|
+
let innerFmt = formatter;
|
|
153
|
+
formatter = (v) => outerFmt(innerFmt(v));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return (v) => (v == null || v === "" ? nullText : formatter(v));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
let format = {
|
|
161
|
+
cache: {},
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
function getDefaultFormatCache() {
|
|
165
|
+
if (format.cacheIdentifier != GlobalCacheIdentifier.get()) {
|
|
166
|
+
format = {
|
|
167
|
+
cache: {},
|
|
168
|
+
cacheIdentifier: GlobalCacheIdentifier.get(),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
return format.cache;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
let getFormatCache = getDefaultFormatCache;
|
|
175
|
+
|
|
176
|
+
export function setGetFormatCacheCallback(callback) {
|
|
177
|
+
getFormatCache = callback;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function getFormatter(format) {
|
|
181
|
+
if (!format) format = "";
|
|
182
|
+
let formatCache = getFormatCache();
|
|
183
|
+
let formatter = formatCache[format];
|
|
184
|
+
if (!formatter) formatter = formatCache[format] = buildFormatter(format);
|
|
185
|
+
|
|
186
|
+
return formatter;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export class Format {
|
|
190
|
+
static value(v, format) {
|
|
191
|
+
let formatter = getFormatter(format);
|
|
192
|
+
return formatter(v);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
static parse(format) {
|
|
196
|
+
return getFormatter(format);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
static register(format, formatter) {
|
|
200
|
+
this.registerFactory(format, () => formatter);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
static registerFactory(format, factory) {
|
|
204
|
+
if (isArray(format)) format.forEach((f) => this.registerFactory(f, factory));
|
|
205
|
+
else formatFactory[format] = factory;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export function resolveMinMaxFractionDigits(minimumFractionDigits, maximumFractionDigits) {
|
|
210
|
+
minimumFractionDigits = minimumFractionDigits != null ? Number(minimumFractionDigits) : minimumFractionDigits;
|
|
211
|
+
maximumFractionDigits = maximumFractionDigits != null ? Number(maximumFractionDigits) : maximumFractionDigits;
|
|
212
|
+
|
|
213
|
+
if (isNumber(minimumFractionDigits)) {
|
|
214
|
+
if (isUndefined(maximumFractionDigits)) maximumFractionDigits = minimumFractionDigits;
|
|
215
|
+
else if (isNumber(maximumFractionDigits) && maximumFractionDigits < minimumFractionDigits)
|
|
216
|
+
maximumFractionDigits = minimumFractionDigits;
|
|
217
|
+
} else if (minimumFractionDigits == null && maximumFractionDigits == null) {
|
|
218
|
+
minimumFractionDigits = 0;
|
|
219
|
+
maximumFractionDigits = 18;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return {
|
|
223
|
+
minimumFractionDigits,
|
|
224
|
+
maximumFractionDigits,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export function trimFractionZeros(str, max) {
|
|
229
|
+
let cnt = 0,
|
|
230
|
+
l = str.length;
|
|
231
|
+
while (cnt < max && (str[l - 1 - cnt] === "0" || str[l - 1 - cnt] === ".")) cnt++;
|
|
232
|
+
|
|
233
|
+
return cnt > 0 ? str.substring(0, l - cnt) : str;
|
|
234
|
+
}
|
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 = {
|