cx 25.10.0 → 25.11.1

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
@@ -979,7 +979,7 @@ var ArrayAdapter = /*#__PURE__*/ (function (_DataAdapter) {
979
979
  var record = _this.mapRecord(context, instance, data, parentStore, recordsAccessor, index);
980
980
  result.push(record);
981
981
  });
982
- if (this.sorter) result = this.sorter(result);
982
+ if (this.sorter && !this.preserveOrder) result = this.sorter(result);
983
983
  return result;
984
984
  };
985
985
  _proto.mapRecord = function mapRecord(context, instance, data, parentStore, recordsAccessor, index) {
@@ -1666,12 +1666,10 @@ var Instance = /*#__PURE__*/ (function () {
1666
1666
  // widget is initialized when the first instance is initialized
1667
1667
  if (!this.widget.initialized) {
1668
1668
  this.widget.init(context);
1669
-
1670
- // init default values
1671
- this.widget.selector.init(this.parentStore);
1672
1669
  this.widget.initialized = true;
1673
1670
  }
1674
1671
  if (!this.dataSelector) {
1672
+ this.widget.selector.init(this.parentStore);
1675
1673
  this.dataSelector = this.widget.selector.createStoreSelector();
1676
1674
  }
1677
1675
 
@@ -4288,6 +4286,7 @@ var GroupAdapter = /*#__PURE__*/ (function (_ArrayAdapter) {
4288
4286
  var level = keys.length;
4289
4287
  var inverseLevel = this.groupings.length - level;
4290
4288
  if (inverseLevel == 0) {
4289
+ if (this.preserveOrder && this.sorter) records = this.sorter(records);
4291
4290
  for (var i = 0; i < records.length; i++) {
4292
4291
  records[i].store.setStore(parentStore);
4293
4292
  result.push(records[i]);
@@ -4299,7 +4298,7 @@ var GroupAdapter = /*#__PURE__*/ (function (_ArrayAdapter) {
4299
4298
  grouper.reset();
4300
4299
  grouper.processAll(records);
4301
4300
  var results = grouper.getResults();
4302
- if (grouping.comparer) results.sort(grouping.comparer);
4301
+ if (grouping.comparer && !this.preserveOrder) results.sort(grouping.comparer);
4303
4302
  results.forEach(function (gr) {
4304
4303
  var _data;
4305
4304
  keys.push(gr.key);
@@ -4388,6 +4387,7 @@ var GroupAdapter = /*#__PURE__*/ (function (_ArrayAdapter) {
4388
4387
  return GroupAdapter;
4389
4388
  })(ArrayAdapter);
4390
4389
  GroupAdapter.prototype.groupName = "$group";
4390
+ GroupAdapter.prototype.preserveOrder = false;
4391
4391
  function serializeKey(data) {
4392
4392
  var _data$toString;
4393
4393
  if (isObject(data))
package/dist/widgets.js CHANGED
@@ -15826,6 +15826,7 @@ var Grid = /*#__PURE__*/ (function (_Container) {
15826
15826
  indexName: this.indexName,
15827
15827
  sortOptions: this.sortOptions,
15828
15828
  groupings: grouping,
15829
+ preserveOrder: this.preserveGroupOrder,
15829
15830
  },
15830
15831
  this.dataAdapter,
15831
15832
  );
@@ -16860,6 +16861,7 @@ Grid.prototype.preciseMeasurements = false;
16860
16861
  Grid.prototype.hoverChannel = "default";
16861
16862
  Grid.prototype.focusable = null; // automatically resolved
16862
16863
  Grid.prototype.allowsFileDrops = false;
16864
+ Grid.prototype.preserveGroupOrder = false;
16863
16865
  Widget.alias("grid", Grid);
16864
16866
  Localization.registerPrototype("cx/widgets/Grid", Grid);
16865
16867
  var GridComponent = /*#__PURE__*/ (function (_VDOM$Component) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cx",
3
- "version": "25.10.0",
3
+ "version": "25.11.1",
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,57 +1,57 @@
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
- });
1
+ import { Grouper } from "./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
+ });
@@ -36,14 +36,11 @@ export class Instance {
36
36
  // widget is initialized when the first instance is initialized
37
37
  if (!this.widget.initialized) {
38
38
  this.widget.init(context);
39
-
40
- // init default values
41
- this.widget.selector.init(this.parentStore);
42
-
43
39
  this.widget.initialized = true;
44
40
  }
45
41
 
46
42
  if (!this.dataSelector) {
43
+ this.widget.selector.init(this.parentStore);
47
44
  this.dataSelector = this.widget.selector.createStoreSelector();
48
45
  }
49
46
 
@@ -1,152 +1,152 @@
1
- import { DataAdapter } from "./DataAdapter";
2
- import { ReadOnlyDataView } from "../../data/ReadOnlyDataView";
3
- import { sorter } from "../../data/comparer";
4
- import { isArray } from "../../util/isArray";
5
- import { ArrayElementView } from "../../data/ArrayElementView";
6
- import { getAccessor } from "../../data/getAccessor";
7
- import { Culture } from "../Culture";
8
- import { isDefined, isObject } from "../../util";
9
-
10
- export class ArrayAdapter extends DataAdapter {
11
- init() {
12
- this.recordsAccessor = getAccessor(this.recordsBinding ? this.recordsBinding : this.recordsAccessor);
13
-
14
- //resolve accessor chains
15
- this.recordName = this.recordName.toString();
16
- this.indexName = this.indexName.toString();
17
- }
18
-
19
- initInstance(context, instance) {
20
- if (!instance.recordStoreCache) {
21
- instance.recordStoreCache = new WeakMap();
22
- instance.cacheByKey = {};
23
- }
24
-
25
- if (!instance.recordsAccessor && this.recordsAccessor) {
26
- instance.recordsAccessor = this.recordsAccessor.bindInstance
27
- ? this.recordsAccessor.bindInstance(instance)
28
- : this.recordsAccessor;
29
- }
30
- }
31
-
32
- getRecords(context, instance, records, parentStore) {
33
- if (!instance.recordStoreCache) this.initInstance(context, instance);
34
-
35
- return this.mapRecords(context, instance, records, parentStore, instance.recordsAccessor);
36
- }
37
-
38
- mapRecords(context, instance, records, parentStore, recordsAccessor) {
39
- let result = [];
40
-
41
- if (!instance.recordStoreCache) this.initInstance(context, instance);
42
-
43
- if (isArray(records))
44
- records.forEach((data, index) => {
45
- if (this.filterFn && !this.filterFn(data)) return;
46
-
47
- let record = this.mapRecord(context, instance, data, parentStore, recordsAccessor, index);
48
-
49
- result.push(record);
50
- });
51
-
52
- if (this.sorter) result = this.sorter(result);
53
-
54
- return result;
55
- }
56
-
57
- mapRecord(context, instance, data, parentStore, recordsAccessor, index) {
58
- let key = this.cacheByKeyField && this.keyField ? data[this.keyField] : null;
59
- let recordStore = key != null ? instance.cacheByKey[key] : instance.recordStoreCache.get(data);
60
-
61
- if (recordsAccessor) {
62
- if (!recordStore)
63
- recordStore = new ArrayElementView({
64
- store: parentStore,
65
- arrayAccessor: recordsAccessor,
66
- itemIndex: index,
67
- recordAlias: this.recordName,
68
- indexAlias: this.indexName,
69
- immutable: this.immutable,
70
- sealed: this.sealed,
71
- });
72
- else {
73
- recordStore.setStore(parentStore);
74
- recordStore.setIndex(index);
75
- }
76
- } else {
77
- if (!recordStore)
78
- recordStore = new ReadOnlyDataView({
79
- store: parentStore,
80
- data: {
81
- [this.recordName]: data,
82
- [this.indexName]: index,
83
- },
84
- immutable: this.immutable,
85
- sealed: this.sealed,
86
- });
87
- else {
88
- recordStore.setStore(parentStore);
89
- recordStore.setData(data);
90
- }
91
- }
92
-
93
- // cache by the key or by data reference
94
- if (key != null) instance.cacheByKey[key] = recordStore;
95
- else if (isObject(data)) instance.recordStoreCache.set(data, recordStore);
96
-
97
- return {
98
- store: recordStore,
99
- index: index,
100
- data: data,
101
- type: "data",
102
- key: this.keyField ? data[this.keyField] : index,
103
- };
104
- }
105
-
106
- setFilter(filterFn) {
107
- this.filterFn = filterFn;
108
- }
109
-
110
- getComparer(sortOptions) {
111
- return sortOptions ? Culture.getComparer(sortOptions) : null;
112
- }
113
-
114
- buildSorter(sorters) {
115
- if (isArray(sorters) && sorters.length > 0) {
116
- let fieldValueMapper;
117
- let dataAccessor;
118
-
119
- //if all sorters are based on record fields access data directly (faster)
120
- if (sorters.every((x) => x.field && x.value == null)) {
121
- dataAccessor = (x) => x.data;
122
- fieldValueMapper = (x) => ({ bind: x.field });
123
- } else {
124
- dataAccessor = (x) => x.store.getData();
125
- fieldValueMapper = (x) => ({ bind: this.recordName + "." + x.field });
126
- }
127
- this.sorter = sorter(
128
- sorters.map((x) => {
129
- let s = Object.assign({}, x);
130
- if (s.field && s.value == null) s.value = fieldValueMapper(s);
131
- if (!s.comparer)
132
- s.comparer = this.getComparer(isDefined(s.sortOptions) ? s.sortOptions : this.sortOptions);
133
- return s;
134
- }),
135
- dataAccessor,
136
- );
137
- } else {
138
- this.sorter = null;
139
- }
140
- }
141
-
142
- sort(sorters) {
143
- this.buildSorter(sorters);
144
- }
145
- }
146
-
147
- ArrayAdapter.prototype.immutable = false;
148
- ArrayAdapter.prototype.sealed = false;
149
- ArrayAdapter.prototype.keyField = null;
150
- ArrayAdapter.prototype.cacheByKeyField = true;
151
-
152
- ArrayAdapter.autoInit = true;
1
+ import { DataAdapter } from "./DataAdapter";
2
+ import { ReadOnlyDataView } from "../../data/ReadOnlyDataView";
3
+ import { sorter } from "../../data/comparer";
4
+ import { isArray } from "../../util/isArray";
5
+ import { ArrayElementView } from "../../data/ArrayElementView";
6
+ import { getAccessor } from "../../data/getAccessor";
7
+ import { Culture } from "../Culture";
8
+ import { isDefined, isObject } from "../../util";
9
+
10
+ export class ArrayAdapter extends DataAdapter {
11
+ init() {
12
+ this.recordsAccessor = getAccessor(this.recordsBinding ? this.recordsBinding : this.recordsAccessor);
13
+
14
+ //resolve accessor chains
15
+ this.recordName = this.recordName.toString();
16
+ this.indexName = this.indexName.toString();
17
+ }
18
+
19
+ initInstance(context, instance) {
20
+ if (!instance.recordStoreCache) {
21
+ instance.recordStoreCache = new WeakMap();
22
+ instance.cacheByKey = {};
23
+ }
24
+
25
+ if (!instance.recordsAccessor && this.recordsAccessor) {
26
+ instance.recordsAccessor = this.recordsAccessor.bindInstance
27
+ ? this.recordsAccessor.bindInstance(instance)
28
+ : this.recordsAccessor;
29
+ }
30
+ }
31
+
32
+ getRecords(context, instance, records, parentStore) {
33
+ if (!instance.recordStoreCache) this.initInstance(context, instance);
34
+
35
+ return this.mapRecords(context, instance, records, parentStore, instance.recordsAccessor);
36
+ }
37
+
38
+ mapRecords(context, instance, records, parentStore, recordsAccessor) {
39
+ let result = [];
40
+
41
+ if (!instance.recordStoreCache) this.initInstance(context, instance);
42
+
43
+ if (isArray(records))
44
+ records.forEach((data, index) => {
45
+ if (this.filterFn && !this.filterFn(data)) return;
46
+
47
+ let record = this.mapRecord(context, instance, data, parentStore, recordsAccessor, index);
48
+
49
+ result.push(record);
50
+ });
51
+
52
+ if (this.sorter && !this.preserveOrder) result = this.sorter(result);
53
+
54
+ return result;
55
+ }
56
+
57
+ mapRecord(context, instance, data, parentStore, recordsAccessor, index) {
58
+ let key = this.cacheByKeyField && this.keyField ? data[this.keyField] : null;
59
+ let recordStore = key != null ? instance.cacheByKey[key] : instance.recordStoreCache.get(data);
60
+
61
+ if (recordsAccessor) {
62
+ if (!recordStore)
63
+ recordStore = new ArrayElementView({
64
+ store: parentStore,
65
+ arrayAccessor: recordsAccessor,
66
+ itemIndex: index,
67
+ recordAlias: this.recordName,
68
+ indexAlias: this.indexName,
69
+ immutable: this.immutable,
70
+ sealed: this.sealed,
71
+ });
72
+ else {
73
+ recordStore.setStore(parentStore);
74
+ recordStore.setIndex(index);
75
+ }
76
+ } else {
77
+ if (!recordStore)
78
+ recordStore = new ReadOnlyDataView({
79
+ store: parentStore,
80
+ data: {
81
+ [this.recordName]: data,
82
+ [this.indexName]: index,
83
+ },
84
+ immutable: this.immutable,
85
+ sealed: this.sealed,
86
+ });
87
+ else {
88
+ recordStore.setStore(parentStore);
89
+ recordStore.setData(data);
90
+ }
91
+ }
92
+
93
+ // cache by the key or by data reference
94
+ if (key != null) instance.cacheByKey[key] = recordStore;
95
+ else if (isObject(data)) instance.recordStoreCache.set(data, recordStore);
96
+
97
+ return {
98
+ store: recordStore,
99
+ index: index,
100
+ data: data,
101
+ type: "data",
102
+ key: this.keyField ? data[this.keyField] : index,
103
+ };
104
+ }
105
+
106
+ setFilter(filterFn) {
107
+ this.filterFn = filterFn;
108
+ }
109
+
110
+ getComparer(sortOptions) {
111
+ return sortOptions ? Culture.getComparer(sortOptions) : null;
112
+ }
113
+
114
+ buildSorter(sorters) {
115
+ if (isArray(sorters) && sorters.length > 0) {
116
+ let fieldValueMapper;
117
+ let dataAccessor;
118
+
119
+ //if all sorters are based on record fields access data directly (faster)
120
+ if (sorters.every((x) => x.field && x.value == null)) {
121
+ dataAccessor = (x) => x.data;
122
+ fieldValueMapper = (x) => ({ bind: x.field });
123
+ } else {
124
+ dataAccessor = (x) => x.store.getData();
125
+ fieldValueMapper = (x) => ({ bind: this.recordName + "." + x.field });
126
+ }
127
+ this.sorter = sorter(
128
+ sorters.map((x) => {
129
+ let s = Object.assign({}, x);
130
+ if (s.field && s.value == null) s.value = fieldValueMapper(s);
131
+ if (!s.comparer)
132
+ s.comparer = this.getComparer(isDefined(s.sortOptions) ? s.sortOptions : this.sortOptions);
133
+ return s;
134
+ }),
135
+ dataAccessor,
136
+ );
137
+ } else {
138
+ this.sorter = null;
139
+ }
140
+ }
141
+
142
+ sort(sorters) {
143
+ this.buildSorter(sorters);
144
+ }
145
+ }
146
+
147
+ ArrayAdapter.prototype.immutable = false;
148
+ ArrayAdapter.prototype.sealed = false;
149
+ ArrayAdapter.prototype.keyField = null;
150
+ ArrayAdapter.prototype.cacheByKeyField = true;
151
+
152
+ ArrayAdapter.autoInit = true;