cx 24.3.6 → 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/ui.js CHANGED
@@ -4149,15 +4149,7 @@ var GroupAdapter = /*#__PURE__*/ (function (_ArrayAdapter) {
4149
4149
  results.forEach(function (gr) {
4150
4150
  var _data;
4151
4151
  keys.push(gr.key);
4152
- var key = keys
4153
- .map(function (key) {
4154
- return Object.keys(key)
4155
- .map(function (k) {
4156
- return key[k];
4157
- })
4158
- .join(":");
4159
- })
4160
- .join("|");
4152
+ var key = keys.map(serializeKey).join("|");
4161
4153
  var $group = _extends({}, gr.key, gr.aggregates, {
4162
4154
  $name: gr.name,
4163
4155
  $level: inverseLevel,
@@ -4243,6 +4235,16 @@ var GroupAdapter = /*#__PURE__*/ (function (_ArrayAdapter) {
4243
4235
  return GroupAdapter;
4244
4236
  })(ArrayAdapter);
4245
4237
  GroupAdapter.prototype.groupName = "$group";
4238
+ function serializeKey(data) {
4239
+ var _data$toString;
4240
+ if (isObject(data))
4241
+ return Object.keys(data)
4242
+ .map(function (k) {
4243
+ return serializeKey(data[k]);
4244
+ })
4245
+ .join(":");
4246
+ return (_data$toString = data == null ? void 0 : data.toString()) != null ? _data$toString : "";
4247
+ }
4246
4248
 
4247
4249
  var TreeAdapter = /*#__PURE__*/ (function (_ArrayAdapter) {
4248
4250
  _inheritsLoose(TreeAdapter, _ArrayAdapter);
package/dist/widgets.js CHANGED
@@ -16190,9 +16190,9 @@ var Grid = /*#__PURE__*/ (function (_Container) {
16190
16190
  colSpan++;
16191
16191
  }
16192
16192
  if (colSpan > 1) skip = colSpan - 1;
16193
- } else if (c.aggregate && c.aggregateAlias && c.caption !== false) {
16193
+ } else if (c.aggregate && c.aggregateAliasGetter && c.caption !== false) {
16194
16194
  empty = false;
16195
- v = group[c.aggregateAlias];
16195
+ v = c.aggregateAliasGetter(group);
16196
16196
  if (isString(ci.data.format)) v = Format.value(v, ci.data.format);
16197
16197
  }
16198
16198
  if (cls) cls += " ";
@@ -16282,9 +16282,9 @@ var Grid = /*#__PURE__*/ (function (_Container) {
16282
16282
  colSpan++;
16283
16283
  }
16284
16284
  if (colSpan > 1) skip = colSpan - 1;
16285
- } else if (c.aggregate && c.aggregateAlias && c.footer !== false) {
16285
+ } else if (c.aggregate && c.aggregateAliasGetter && c.footer !== false) {
16286
16286
  empty = false;
16287
- v = group[c.aggregateAlias];
16287
+ v = c.aggregateAliasGetter(group);
16288
16288
  if (isString(ci.data.format)) v = Format.value(v, ci.data.format);
16289
16289
  }
16290
16290
  if (cls) cls += " ";
@@ -16921,44 +16921,34 @@ var GridComponent = /*#__PURE__*/ (function (_VDOM$Component) {
16921
16921
  },
16922
16922
  "dropzone",
16923
16923
  );
16924
+ var dataRecordClass = CSS.element(baseClass, "data");
16925
+ var isDataRecord = widget.buffered
16926
+ ? function (item) {
16927
+ var _item$props;
16928
+ return (
16929
+ (item == null ||
16930
+ (_item$props = item.props) == null ||
16931
+ (_item$props = _item$props.instance) == null ||
16932
+ (_item$props = _item$props.data) == null
16933
+ ? void 0
16934
+ : _item$props["class"]) == dataRecordClass
16935
+ );
16936
+ }
16937
+ : function (item) {
16938
+ var _item$props2;
16939
+ return item == null || (_item$props2 = item.props) == null || (_item$props2 = _item$props2.record) == null
16940
+ ? void 0
16941
+ : _item$props2.type;
16942
+ };
16924
16943
  var index = 0;
16925
- while (
16926
- index < children.length &&
16927
- ((_children$index = children[index]) == null ||
16928
- (_children$index = _children$index.props) == null ||
16929
- (_children$index = _children$index.record) == null
16930
- ? void 0
16931
- : _children$index.type) != "data"
16932
- ) {
16933
- var _children$index;
16934
- index++;
16935
- }
16944
+ while (index < children.length && !isDataRecord(children[index])) index++;
16936
16945
  var count = 0;
16937
16946
  while (index < children.length && count < this.state.dropInsertionIndex) {
16938
- var _children$index2;
16939
- if (
16940
- ((_children$index2 = children[index]) == null ||
16941
- (_children$index2 = _children$index2.props) == null ||
16942
- (_children$index2 = _children$index2.record) == null
16943
- ? void 0
16944
- : _children$index2.type) == "data"
16945
- )
16946
- count++;
16947
+ if (isDataRecord(children[index])) count++;
16947
16948
  index++;
16948
16949
  }
16949
16950
  var savedIndexPos = index;
16950
- if (!this.state.dropNextToTheRowAbove)
16951
- while (
16952
- index < children.length &&
16953
- ((_children$index3 = children[index]) == null ||
16954
- (_children$index3 = _children$index3.props) == null ||
16955
- (_children$index3 = _children$index3.record) == null
16956
- ? void 0
16957
- : _children$index3.type) != "data"
16958
- ) {
16959
- var _children$index3;
16960
- index++;
16961
- }
16951
+ if (!this.state.dropNextToTheRowAbove) while (index < children.length && !isDataRecord(children[index])) index++;
16962
16952
 
16963
16953
  // do not allow insertion after the last group footer
16964
16954
  if (savedIndexPos < index && index == children.length) index = savedIndexPos;
@@ -17353,15 +17343,15 @@ var GridComponent = /*#__PURE__*/ (function (_VDOM$Component) {
17353
17343
  if (dropTarget == "grid" && widget.onDrop && dropInsertionIndex != null) {
17354
17344
  e.target = {
17355
17345
  insertionIndex: start + dropInsertionIndex,
17356
- recordBefore: this.getRecordAt(start + dropInsertionIndex - 1),
17357
- recordAfter: this.getRecordAt(start + dropInsertionIndex),
17346
+ recordBefore: this.getDataRecordAt(start + dropInsertionIndex - 1),
17347
+ recordAfter: this.getDataRecordAt(start + dropInsertionIndex),
17358
17348
  dropNextToTheRowAbove: dropNextToTheRowAbove,
17359
17349
  };
17360
17350
  instance.invoke("onDrop", e, instance);
17361
17351
  } else if (dropTarget == "row") {
17362
17352
  e.target = {
17363
17353
  index: start + dropInsertionIndex,
17364
- record: this.getRecordAt(start + dropInsertionIndex),
17354
+ record: this.getDataRecordAt(start + dropInsertionIndex),
17365
17355
  };
17366
17356
  instance.invoke("onRowDrop", e, instance);
17367
17357
  } else if (dropTarget == "column" && widget.onColumnDrop) {
@@ -18034,6 +18024,14 @@ var GridComponent = /*#__PURE__*/ (function (_VDOM$Component) {
18034
18024
  }
18035
18025
  widget.selection.selectMultiple(instance.store, selection, indexes, options);
18036
18026
  };
18027
+ _proto2.getDataRecordAt = function getDataRecordAt(index) {
18028
+ var records = this.props.instance.records;
18029
+ if (!records) return this.getRecordAt(index);
18030
+ var dataRecords = records.filter(function (r) {
18031
+ return r.type == "data";
18032
+ });
18033
+ return dataRecords[index];
18034
+ };
18037
18035
  _proto2.getRecordAt = function getRecordAt(cursor) {
18038
18036
  var _this$props7 = this.props,
18039
18037
  instance = _this$props7.instance,
@@ -18412,6 +18410,7 @@ var GridColumnHeader = /*#__PURE__*/ (function (_Widget) {
18412
18410
  };
18413
18411
  if (!this.aggregateField && this.field) this.aggregateField = this.field;
18414
18412
  if (!this.aggregateAlias) this.aggregateAlias = this.aggregateField;
18413
+ if (this.aggregateAlias) this.aggregateAliasGetter = Binding.get(this.aggregateAlias).value;
18415
18414
  if (this.footer && isSelector(this.footer))
18416
18415
  this.footer = {
18417
18416
  value: this.footer,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cx",
3
- "version": "24.3.6",
3
+ "version": "24.3.8",
4
4
  "description": "Advanced JavaScript UI framework for admin and dashboard applications with ready to use grid, form and chart components.",
5
5
  "main": "index.js",
6
6
  "jsnext:main": "src/index.js",
@@ -1,120 +1,144 @@
1
- import {getSelector} from './getSelector';
2
- import {AggregateFunction} from './AggregateFunction';
3
-
4
- /*
5
- 'column': {
6
- index: 0,
7
- sort: 'asc',
8
- group: true
9
- aggregate: 'count'
10
- }
11
- */
12
-
13
- function transform(o, f) {
14
- var res = {};
15
- for (var k in o)
16
- res[k] = f(o[k], k);
17
- return res;
18
- }
19
-
20
- export class Grouper {
21
- constructor(key, aggregates, dataGetter, nameGetter) {
22
- this.keys = Object.keys(key).map(k => {
23
- return {
24
- name: k,
25
- value: getSelector(key[k])
26
- }
27
- });
28
- if (nameGetter)
29
- this.nameGetter = getSelector(nameGetter);
30
- this.dataGetter = dataGetter || (x=>x);
31
- this.aggregates = aggregates && transform(aggregates, prop => {
32
- if (!AggregateFunction[prop.type])
33
- throw new Error(`Unknown aggregate function '${prop.type}'.`);
34
-
35
- return {
36
- value: getSelector(prop.value),
37
- weight: getSelector(prop.weight || 1),
38
- type: prop.type
39
- }
40
- });
41
- this.reset();
42
- }
43
-
44
- reset() {
45
- this.groups = this.initGroup(this.keys.length == 0)
46
- }
47
-
48
- initGroup(leaf) {
49
- if (!leaf)
50
- return {};
51
-
52
- return {
53
- records: [],
54
- indexes: [],
55
- aggregates: this.aggregates && transform(this.aggregates, prop => {
56
- var f = AggregateFunction[prop.type];
57
- return {
58
- processor: f(),
59
- value: prop.value,
60
- weight: prop.weight
61
- }
62
- })
63
- }
64
- }
65
-
66
- process(record, index) {
67
- var data = this.dataGetter(record);
68
- var key = this.keys.map(k=>k.value(data));
69
- var g = this.groups;
70
- for (var i = 0; i < key.length; i++) {
71
- var sg = g[key[i]];
72
- if (!sg) {
73
- sg = g[key[i]] = this.initGroup(i + 1 == key.length);
74
- if (this.nameGetter)
75
- sg.name = this.nameGetter(data);
76
- }
77
- g = sg;
78
- }
79
-
80
- g.records.push(record);
81
- g.indexes.push(index);
82
-
83
- if (g.aggregates) {
84
- for (var k in g.aggregates)
85
- g.aggregates[k].processor.process(g.aggregates[k].value(data), g.aggregates[k].weight(data));
86
- }
87
- }
88
-
89
- processAll(records, indexes) {
90
- if (indexes) {
91
- for (var i = 0; i < records.length; i++)
92
- this.process(records[i], indexes[i]);
93
- }
94
- else
95
- records.forEach((r, i)=>this.process(r, i));
96
- }
97
-
98
- report(g, path, level, results) {
99
- if (level == this.keys.length) {
100
- var key = {};
101
- this.keys.forEach((k, i) => key[k.name] = path[i]);
102
- results.push({
103
- key: key,
104
- name: g.name,
105
- records: g.records,
106
- indexes: g.indexes,
107
- aggregates: transform(g.aggregates, p=>p.processor.getResult())
108
- })
109
- } else {
110
- Object.keys(g).forEach(k=>this.report(g[k], [...path, k], level + 1, results));
111
- }
112
- }
113
-
114
- getResults() {
115
- var g = this.groups;
116
- var results = [];
117
- this.report(g, [], 0, results);
118
- return results;
119
- }
120
- }
1
+ import { getSelector } from "./getSelector";
2
+ import { AggregateFunction } from "./AggregateFunction";
3
+ import { Binding } from "./Binding";
4
+
5
+ /*
6
+ 'column': {
7
+ index: 0,
8
+ sort: 'asc',
9
+ group: true
10
+ aggregate: 'count'
11
+ }
12
+ */
13
+
14
+ export class Grouper {
15
+ constructor(key, aggregates, dataGetter, nameGetter) {
16
+ this.keys = Object.keys(key).map((keyField) => {
17
+ let isSimpleField = keyField.indexOf(".") === -1;
18
+ let keySetter;
19
+ if (isSimpleField) {
20
+ // use simple field setter wherever possible
21
+ keySetter = function set(result, value) {
22
+ result[keyField] = value;
23
+ return result;
24
+ };
25
+ } else {
26
+ // for complex paths, use deep setter
27
+ let binding = Binding.get(keyField);
28
+ keySetter = (result, value) => binding.set(result, value);
29
+ }
30
+ return {
31
+ name: keyField,
32
+ keySetter,
33
+ value: getSelector(key[keyField]),
34
+ };
35
+ });
36
+ if (nameGetter) this.nameGetter = getSelector(nameGetter);
37
+ this.dataGetter = dataGetter || ((x) => x);
38
+ this.aggregates =
39
+ aggregates &&
40
+ transformValues(aggregates, (prop) => {
41
+ if (!AggregateFunction[prop.type]) throw new Error(`Unknown aggregate function '${prop.type}'.`);
42
+
43
+ return {
44
+ value: getSelector(prop.value),
45
+ weight: getSelector(prop.weight ?? 1),
46
+ type: prop.type,
47
+ };
48
+ });
49
+ this.reset();
50
+ }
51
+
52
+ reset() {
53
+ this.groups = this.initGroup(this.keys.length == 0);
54
+ }
55
+
56
+ initGroup(leaf) {
57
+ if (!leaf) return {};
58
+
59
+ return {
60
+ records: [],
61
+ indexes: [],
62
+ aggregates:
63
+ this.aggregates &&
64
+ transformValues(this.aggregates, (prop) => {
65
+ let f = AggregateFunction[prop.type];
66
+ return {
67
+ processor: f(),
68
+ value: prop.value,
69
+ weight: prop.weight,
70
+ };
71
+ }),
72
+ };
73
+ }
74
+
75
+ process(record, index) {
76
+ let data = this.dataGetter(record);
77
+ let key = this.keys.map((k) => k.value(data));
78
+ let g = this.groups;
79
+ for (let i = 0; i < key.length; i++) {
80
+ let sg = g[key[i]];
81
+ if (!sg) {
82
+ sg = g[key[i]] = this.initGroup(i + 1 == key.length);
83
+ if (this.nameGetter) sg.name = this.nameGetter(data);
84
+ }
85
+ g = sg;
86
+ }
87
+
88
+ g.records.push(record);
89
+ g.indexes.push(index);
90
+
91
+ if (g.aggregates) {
92
+ for (let k in g.aggregates)
93
+ g.aggregates[k].processor.process(g.aggregates[k].value(data), g.aggregates[k].weight(data));
94
+ }
95
+ }
96
+
97
+ processAll(records, indexes) {
98
+ if (indexes) {
99
+ for (let i = 0; i < records.length; i++) this.process(records[i], indexes[i]);
100
+ } else records.forEach((r, i) => this.process(r, i));
101
+ }
102
+
103
+ report(g, path, level, results) {
104
+ if (level == this.keys.length) {
105
+ let key = {};
106
+ this.keys.forEach((k, i) => {
107
+ key = k.keySetter(key, path[i]);
108
+ });
109
+ results.push({
110
+ key: key,
111
+ name: g.name,
112
+ records: g.records,
113
+ indexes: g.indexes,
114
+ aggregates: resolveKeyPaths(transformValues(g.aggregates, (p) => p.processor.getResult())),
115
+ });
116
+ } else {
117
+ Object.keys(g).forEach((k) => this.report(g[k], [...path, k], level + 1, results));
118
+ }
119
+ }
120
+
121
+ getResults() {
122
+ let g = this.groups;
123
+ let results = [];
124
+ this.report(g, [], 0, results);
125
+ return results;
126
+ }
127
+ }
128
+
129
+ // transform object values using a function
130
+ function transformValues(o, f) {
131
+ let res = {};
132
+ for (let k in o) res[k] = f(o[k], k);
133
+ return res;
134
+ }
135
+
136
+ // transform keys like 'a.b.c' into nested objects
137
+ function resolveKeyPaths(o) {
138
+ let res = {};
139
+ for (let k in o) {
140
+ if (k.indexOf(".") > 0) res = Binding.get(k).set(res, o[k]);
141
+ else res[k] = o[k];
142
+ }
143
+ return res;
144
+ }
@@ -1,42 +1,57 @@
1
- var Grouper = require("./Grouper").Grouper;
2
- import assert from "assert";
3
-
4
- describe("Grouper", function () {
5
- describe("single grouping", function () {
6
- it("should work", function () {
7
- var data = [
8
- { name: "John", age: 12 },
9
- { name: "Jane", age: 12 },
10
- ];
11
-
12
- var grouper = new Grouper({ name: { bind: "name" } });
13
- grouper.processAll(data);
14
-
15
- var results = grouper.getResults();
16
- // console.log(results);
17
- assert.equal(results.length, 2);
18
- });
19
- });
20
-
21
- describe("multi grouping", function () {
22
- it("should work", function () {
23
- var data = [
24
- { name: "John", age: 12 },
25
- { name: "John", age: 12 },
26
- { name: "John", age: 13 },
27
- { name: "John", age: 14 },
28
- { name: "Jane", age: 12 },
29
- { name: "Jane", age: 13 },
30
- { name: "Jane", age: 14 },
31
- ];
32
-
33
- var grouper = new Grouper({ name: { bind: "name" }, age: { bind: "age" } });
34
- grouper.processAll(data);
35
-
36
- var results = grouper.getResults();
37
- // console.log(results);
38
- assert.equal(results.length, 6);
39
- assert.equal(results[0].records.length, 2);
40
- });
41
- });
42
- });
1
+ let Grouper = require("./Grouper").Grouper;
2
+ import assert from "assert";
3
+
4
+ describe("Grouper", function () {
5
+ describe("single grouping", function () {
6
+ it("should work", function () {
7
+ let data = [
8
+ { name: "John", age: 12 },
9
+ { name: "Jane", age: 12 },
10
+ ];
11
+
12
+ let grouper = new Grouper({ name: { bind: "name" } });
13
+ grouper.processAll(data);
14
+
15
+ let results = grouper.getResults();
16
+ // console.log(results);
17
+ assert.equal(results.length, 2);
18
+ });
19
+
20
+ it("keys can have nested properties", function () {
21
+ let data = [
22
+ { name: "John", age: 12 },
23
+ { name: "Jane", age: 12 },
24
+ ];
25
+
26
+ let grouper = new Grouper({ "person.name": { bind: "name" } });
27
+ grouper.processAll(data);
28
+
29
+ let results = grouper.getResults();
30
+ assert.equal(results.length, 2);
31
+ assert.equal(results[0].key.person?.name, "John");
32
+ assert.equal(results[1].key.person?.name, "Jane");
33
+ });
34
+ });
35
+
36
+ describe("multi grouping", function () {
37
+ it("should work", function () {
38
+ let data = [
39
+ { name: "John", age: 12 },
40
+ { name: "John", age: 12 },
41
+ { name: "John", age: 13 },
42
+ { name: "John", age: 14 },
43
+ { name: "Jane", age: 12 },
44
+ { name: "Jane", age: 13 },
45
+ { name: "Jane", age: 14 },
46
+ ];
47
+
48
+ let grouper = new Grouper({ name: { bind: "name" }, age: { bind: "age" } });
49
+ grouper.processAll(data);
50
+
51
+ let results = grouper.getResults();
52
+ // console.log(results);
53
+ assert.equal(results.length, 6);
54
+ assert.equal(results[0].records.length, 2);
55
+ });
56
+ });
57
+ });