cx 26.1.13 → 26.2.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.
Files changed (130) hide show
  1. package/build/charts/Marker.d.ts +1 -1
  2. package/build/charts/Marker.d.ts.map +1 -1
  3. package/build/charts/Marker.js +16 -6
  4. package/build/charts/MouseTracker.d.ts +2 -0
  5. package/build/charts/MouseTracker.d.ts.map +1 -1
  6. package/build/charts/helpers/PointReducer.d.ts +2 -2
  7. package/build/charts/helpers/PointReducer.d.ts.map +1 -1
  8. package/build/data/View.d.ts +5 -3
  9. package/build/data/View.d.ts.map +1 -1
  10. package/build/data/View.js +3 -1
  11. package/build/data/ops/findTreeNode.d.ts +20 -1
  12. package/build/data/ops/findTreeNode.d.ts.map +1 -1
  13. package/build/data/ops/findTreeNode.js +19 -0
  14. package/build/data/ops/findTreePath.d.ts +1 -1
  15. package/build/data/ops/findTreePath.d.ts.map +1 -1
  16. package/build/data/ops/findTreePath.js +1 -1
  17. package/build/data/ops/removeTreeNodes.d.ts +14 -1
  18. package/build/data/ops/removeTreeNodes.d.ts.map +1 -1
  19. package/build/data/ops/removeTreeNodes.js +13 -0
  20. package/build/data/ops/updateArray.d.ts +1 -1
  21. package/build/data/ops/updateArray.d.ts.map +1 -1
  22. package/build/data/ops/updateArray.js +1 -1
  23. package/build/data/ops/updateTree.d.ts +20 -1
  24. package/build/data/ops/updateTree.d.ts.map +1 -1
  25. package/build/data/ops/updateTree.js +19 -0
  26. package/build/jsx-runtime.d.ts +1 -0
  27. package/build/jsx-runtime.d.ts.map +1 -1
  28. package/build/jsx-runtime.js +3 -1
  29. package/build/svg/Rectangle.d.ts +6 -4
  30. package/build/svg/Rectangle.d.ts.map +1 -1
  31. package/build/svg/Rectangle.js +9 -7
  32. package/build/ui/Instance.d.ts +1 -1
  33. package/build/ui/Instance.d.ts.map +1 -1
  34. package/build/ui/Instance.js +18 -8
  35. package/build/ui/IsolatedScope.d.ts +2 -1
  36. package/build/ui/IsolatedScope.d.ts.map +1 -1
  37. package/build/ui/Prop.d.ts +1 -1
  38. package/build/ui/Prop.d.ts.map +1 -1
  39. package/build/ui/Widget.d.ts +2 -0
  40. package/build/ui/Widget.d.ts.map +1 -1
  41. package/build/ui/Widget.js +4 -0
  42. package/build/ui/adapter/GroupAdapter.d.ts +4 -4
  43. package/build/ui/adapter/GroupAdapter.d.ts.map +1 -1
  44. package/build/ui/adapter/GroupAdapter.js +4 -4
  45. package/build/ui/adapter/TreeAdapter.d.ts +5 -3
  46. package/build/ui/adapter/TreeAdapter.d.ts.map +1 -1
  47. package/build/ui/adapter/TreeAdapter.js +12 -5
  48. package/build/ui/app/startAppLoop.d.ts +2 -2
  49. package/build/ui/app/startAppLoop.d.ts.map +1 -1
  50. package/build/ui/app/startHotAppLoop.d.ts +4 -4
  51. package/build/ui/app/startHotAppLoop.d.ts.map +1 -1
  52. package/build/ui/app/startHotAppLoop.js +1 -1
  53. package/build/ui/batchUpdates.d.ts.map +1 -1
  54. package/build/ui/batchUpdates.js +3 -4
  55. package/build/widgets/Button.d.ts +0 -7
  56. package/build/widgets/Button.d.ts.map +1 -1
  57. package/build/widgets/HtmlElement.d.ts +2 -2
  58. package/build/widgets/HtmlElement.d.ts.map +1 -1
  59. package/build/widgets/form/Checkbox.d.ts +3 -3
  60. package/build/widgets/form/Checkbox.d.ts.map +1 -1
  61. package/build/widgets/form/Checkbox.js +11 -6
  62. package/build/widgets/form/DateTimeField.d.ts +4 -0
  63. package/build/widgets/form/DateTimeField.d.ts.map +1 -1
  64. package/build/widgets/form/LookupField.d.ts +14 -27
  65. package/build/widgets/form/LookupField.d.ts.map +1 -1
  66. package/build/widgets/form/TextField.d.ts +2 -2
  67. package/build/widgets/form/TextField.d.ts.map +1 -1
  68. package/build/widgets/grid/Grid.d.ts +20 -16
  69. package/build/widgets/grid/Grid.d.ts.map +1 -1
  70. package/build/widgets/grid/Grid.js +200 -86
  71. package/build/widgets/nav/Menu.d.ts +2 -0
  72. package/build/widgets/nav/Menu.d.ts.map +1 -1
  73. package/build/widgets/nav/Route.js +1 -1
  74. package/build/widgets/overlay/FlyweightTooltipTracker.d.ts +6 -4
  75. package/build/widgets/overlay/FlyweightTooltipTracker.d.ts.map +1 -1
  76. package/build/widgets/overlay/FlyweightTooltipTracker.js +3 -0
  77. package/build/widgets/overlay/Overlay.d.ts +2 -2
  78. package/build/widgets/overlay/Overlay.d.ts.map +1 -1
  79. package/dist/data.js +52 -1
  80. package/dist/jsx-runtime.js +4 -2
  81. package/dist/manifest.js +879 -873
  82. package/dist/svg.js +3 -0
  83. package/dist/ui.js +1548 -1544
  84. package/dist/widgets.css +1 -1
  85. package/dist/widgets.js +395 -4
  86. package/package.json +2 -2
  87. package/src/charts/Marker.tsx +448 -394
  88. package/src/charts/MouseTracker.tsx +3 -0
  89. package/src/charts/helpers/PointReducer.ts +2 -2
  90. package/src/data/View.ts +76 -19
  91. package/src/data/ops/findTreeNode.ts +20 -1
  92. package/src/data/ops/findTreePath.ts +7 -2
  93. package/src/data/ops/removeTreeNodes.ts +14 -1
  94. package/src/data/ops/updateArray.ts +4 -4
  95. package/src/data/ops/updateTree.ts +32 -6
  96. package/src/index.scss +6 -6
  97. package/src/jsx-runtime.spec.tsx +40 -0
  98. package/src/jsx-runtime.ts +87 -84
  99. package/src/svg/Rectangle.tsx +80 -73
  100. package/src/ui/DataProxy.ts +55 -55
  101. package/src/ui/Instance.ts +142 -45
  102. package/src/ui/IsolatedScope.ts +4 -2
  103. package/src/ui/Prop.ts +141 -141
  104. package/src/ui/Rescope.ts +50 -50
  105. package/src/ui/Widget.tsx +292 -234
  106. package/src/ui/adapter/ArrayAdapter.ts +229 -229
  107. package/src/ui/adapter/GroupAdapter.ts +8 -10
  108. package/src/ui/adapter/TreeAdapter.ts +75 -15
  109. package/src/ui/app/Url.spec.ts +1 -1
  110. package/src/ui/app/startAppLoop.tsx +56 -45
  111. package/src/ui/app/startHotAppLoop.ts +4 -4
  112. package/src/ui/batchUpdates.ts +16 -21
  113. package/src/ui/exprHelpers.ts +96 -96
  114. package/src/widgets/Button.tsx +0 -8
  115. package/src/widgets/HtmlElement.spec.tsx +100 -72
  116. package/src/widgets/HtmlElement.tsx +11 -10
  117. package/src/widgets/Sandbox.ts +104 -104
  118. package/src/widgets/Section.scss +55 -55
  119. package/src/widgets/drag-drop/DropZone.scss +74 -74
  120. package/src/widgets/form/Checkbox.tsx +296 -243
  121. package/src/widgets/form/DateTimeField.tsx +6 -0
  122. package/src/widgets/form/LookupField.tsx +70 -73
  123. package/src/widgets/form/TextField.tsx +2 -2
  124. package/src/widgets/grid/Grid.scss +43 -10
  125. package/src/widgets/grid/Grid.tsx +4401 -3848
  126. package/src/widgets/nav/Menu.tsx +3 -0
  127. package/src/widgets/nav/Route.ts +1 -1
  128. package/src/widgets/overlay/FlyweightTooltipTracker.ts +15 -4
  129. package/src/widgets/overlay/Overlay.tsx +2 -1
  130. package/src/widgets/overlay/index.d.ts +11 -11
@@ -1,229 +1,229 @@
1
- import { DataAdapter, DataAdapterRecord, DataAdapterConfig } 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 { Accessor, getAccessor } from "../../data/getAccessor";
7
- import { Culture } from "../Culture";
8
- import { isDefined, isObject } from "../../util";
9
- import { RenderingContext } from "../RenderingContext";
10
- import { Instance } from "../Instance";
11
- import { View } from "../../data/View";
12
- import { Prop, Sorter, CollatorOptions } from "../Prop";
13
-
14
- export interface RecordStoreCache {
15
- recordStoreCache: WeakMap<any, View>;
16
- cacheByKey: Record<string | number, View>;
17
- recordsAccessor?: Accessor;
18
- }
19
-
20
- export interface ArrayAdapterConfig extends DataAdapterConfig {
21
- recordsBinding?: Prop<any[]>;
22
- recordsAccessor?: Accessor | string;
23
- keyField?: string;
24
- cacheByKeyField?: boolean;
25
- sortOptions?: CollatorOptions;
26
- preserveOrder?: boolean;
27
- }
28
-
29
- export interface ExtendedSorter extends Sorter {
30
- comparer?: (a: any, b: any) => number;
31
- sortOptions?: CollatorOptions;
32
- }
33
-
34
- export interface ResolvedSorter {
35
- getter: (x: any) => any;
36
- factor: number;
37
- compare: (a: any, b: any) => number;
38
- }
39
-
40
- export class ArrayAdapter<T = any> extends DataAdapter<T> {
41
- declare public recordsAccessor: Accessor;
42
- declare public recordsBinding?: Prop<T[]>;
43
- declare public keyField: string | null;
44
- declare public cacheByKeyField: boolean;
45
- declare public sortOptions?: CollatorOptions;
46
- declare public preserveOrder?: boolean;
47
- declare isTreeAdapter: boolean;
48
-
49
- declare protected sorter?: (data: DataAdapterRecord<T>[]) => DataAdapterRecord<T>[];
50
-
51
- constructor(config?: ArrayAdapterConfig) {
52
- super(config);
53
- }
54
-
55
- public init(): void {
56
- this.recordsAccessor = this.recordsBinding ? getAccessor(this.recordsBinding) : getAccessor(this.recordsAccessor);
57
- this.recordName = this.recordName?.toString() || "$record";
58
- this.indexName = this.indexName?.toString() || "$index";
59
- }
60
-
61
- public initInstance(context: RenderingContext, instance: Instance & Partial<RecordStoreCache>): void {
62
- if (!instance.recordStoreCache) {
63
- instance.recordStoreCache = new WeakMap();
64
- instance.cacheByKey = {};
65
- }
66
-
67
- if (!instance.recordsAccessor && this.recordsAccessor) {
68
- instance.recordsAccessor = this.recordsAccessor.bindInstance
69
- ? this.recordsAccessor.bindInstance(instance)
70
- : this.recordsAccessor;
71
- }
72
- }
73
-
74
- public getRecords(
75
- context: RenderingContext,
76
- instance: Instance & Partial<RecordStoreCache>,
77
- records: T[],
78
- parentStore: View,
79
- ): DataAdapterRecord<T>[] {
80
- if (!instance.recordStoreCache) {
81
- this.initInstance(context, instance);
82
- }
83
-
84
- return this.mapRecords(context, instance, records, parentStore, instance.recordsAccessor);
85
- }
86
-
87
- public mapRecords(
88
- context: RenderingContext,
89
- instance: Instance & Partial<RecordStoreCache>,
90
- records: T[],
91
- parentStore: View,
92
- recordsAccessor?: Accessor,
93
- ): DataAdapterRecord<T>[] {
94
- let result: DataAdapterRecord<T>[] = [];
95
-
96
- if (!instance.recordStoreCache) {
97
- this.initInstance(context, instance);
98
- }
99
-
100
- if (isArray(records)) {
101
- records.forEach((data, index) => {
102
- if (this.filterFn && !this.filterFn(data)) return;
103
-
104
- const record = this.mapRecord(context, instance, data, parentStore, recordsAccessor, index);
105
- result.push(record);
106
- });
107
- }
108
-
109
- if (this.sorter && !this.preserveOrder) {
110
- result = this.sorter(result);
111
- }
112
-
113
- return result;
114
- }
115
-
116
- public mapRecord(
117
- context: RenderingContext,
118
- instance: Instance & Partial<RecordStoreCache>,
119
- data: T,
120
- parentStore: View,
121
- recordsAccessor: Accessor | undefined,
122
- index: number,
123
- ): DataAdapterRecord<T> {
124
- const key = this.cacheByKeyField && this.keyField && isObject(data) ? (data as any)[this.keyField] : null;
125
- let recordStore = key != null ? instance.cacheByKey![key] : instance.recordStoreCache!.get(data);
126
-
127
- if (recordsAccessor) {
128
- if (!recordStore) {
129
- recordStore = new ArrayElementView({
130
- store: parentStore,
131
- arrayAccessor: recordsAccessor,
132
- itemIndex: index,
133
- recordAlias: this.recordName,
134
- indexAlias: this.indexName,
135
- immutable: this.immutable,
136
- sealed: this.sealed,
137
- });
138
- } else {
139
- (recordStore as ArrayElementView).setStore(parentStore);
140
- (recordStore as ArrayElementView).setIndex(index);
141
- }
142
- } else {
143
- if (!recordStore) {
144
- recordStore = new ReadOnlyDataView({
145
- store: parentStore,
146
- data: {
147
- [this.recordName]: data,
148
- [this.indexName]: index,
149
- },
150
- immutable: this.immutable,
151
- sealed: this.sealed,
152
- });
153
- } else {
154
- (recordStore as ReadOnlyDataView).setStore(parentStore);
155
- (recordStore as ReadOnlyDataView).setData({
156
- [this.recordName]: data,
157
- [this.indexName]: index,
158
- });
159
- }
160
- }
161
-
162
- if (key != null) {
163
- instance.cacheByKey![key] = recordStore;
164
- } else if (isObject(data)) {
165
- instance.recordStoreCache!.set(data, recordStore);
166
- }
167
-
168
- return {
169
- store: recordStore,
170
- index: index,
171
- data: data,
172
- type: "data",
173
- key: this.keyField && isObject(data) ? (data as any)[this.keyField] : index,
174
- };
175
- }
176
-
177
- public setFilter(filterFn?: (data: T) => boolean): void {
178
- this.filterFn = filterFn;
179
- }
180
-
181
- public getComparer(sortOptions?: CollatorOptions): ((a: any, b: any) => number) | undefined {
182
- return sortOptions ? Culture.getComparer(sortOptions) : undefined;
183
- }
184
-
185
- public buildSorter(sorters: ExtendedSorter[]): void {
186
- if (isArray(sorters) && sorters.length > 0) {
187
- let dataAccessor: (x: DataAdapterRecord<T>) => any;
188
- let fieldValueMapper: (x: ExtendedSorter) => Prop<any>;
189
-
190
- if (sorters.every((x) => x.field && x.value == null)) {
191
- dataAccessor = (x) => x.data;
192
- fieldValueMapper = (x) => ({ bind: x.field! });
193
- } else {
194
- dataAccessor = (x) => x.store.getData();
195
- fieldValueMapper = (x) => ({ bind: this.recordName + "." + x.field });
196
- }
197
-
198
- this.sorter = sorter(
199
- sorters.map((x) => {
200
- const s: ExtendedSorter = Object.assign({}, x);
201
- if (s.field && s.value == null) {
202
- s.value = fieldValueMapper(s);
203
- }
204
- if (!s.comparer) {
205
- s.comparer = this.getComparer(isDefined(s.sortOptions) ? s.sortOptions : this.sortOptions);
206
- }
207
- return s;
208
- }),
209
- dataAccessor,
210
- );
211
- } else {
212
- this.sorter = undefined;
213
- }
214
- }
215
-
216
- public sort(sorters?: Sorter[] | ExtendedSorter[]): void {
217
- if (sorters) {
218
- this.buildSorter(sorters as ExtendedSorter[]);
219
- }
220
- }
221
- }
222
-
223
- ArrayAdapter.prototype.immutable = false;
224
- ArrayAdapter.prototype.sealed = false;
225
- ArrayAdapter.prototype.keyField = null;
226
- ArrayAdapter.prototype.cacheByKeyField = true;
227
- ArrayAdapter.prototype.isTreeAdapter = false;
228
-
229
- ArrayAdapter.autoInit = true;
1
+ import { DataAdapter, DataAdapterRecord, DataAdapterConfig } 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 { Accessor, getAccessor } from "../../data/getAccessor";
7
+ import { Culture } from "../Culture";
8
+ import { isDefined, isObject } from "../../util";
9
+ import { RenderingContext } from "../RenderingContext";
10
+ import { Instance } from "../Instance";
11
+ import { View } from "../../data/View";
12
+ import { Prop, Sorter, CollatorOptions } from "../Prop";
13
+
14
+ export interface RecordStoreCache {
15
+ recordStoreCache: WeakMap<any, View>;
16
+ cacheByKey: Record<string | number, View>;
17
+ recordsAccessor?: Accessor;
18
+ }
19
+
20
+ export interface ArrayAdapterConfig extends DataAdapterConfig {
21
+ recordsBinding?: Prop<any[]>;
22
+ recordsAccessor?: Accessor | string;
23
+ keyField?: string;
24
+ cacheByKeyField?: boolean;
25
+ sortOptions?: CollatorOptions;
26
+ preserveOrder?: boolean;
27
+ }
28
+
29
+ export interface ExtendedSorter extends Sorter {
30
+ comparer?: (a: any, b: any) => number;
31
+ sortOptions?: CollatorOptions;
32
+ }
33
+
34
+ export interface ResolvedSorter {
35
+ getter: (x: any) => any;
36
+ factor: number;
37
+ compare: (a: any, b: any) => number;
38
+ }
39
+
40
+ export class ArrayAdapter<T = any> extends DataAdapter<T> {
41
+ declare public recordsAccessor: Accessor;
42
+ declare public recordsBinding?: Prop<T[]>;
43
+ declare public keyField: string | null;
44
+ declare public cacheByKeyField: boolean;
45
+ declare public sortOptions?: CollatorOptions;
46
+ declare public preserveOrder?: boolean;
47
+ declare isTreeAdapter: boolean;
48
+
49
+ declare protected sorter?: (data: DataAdapterRecord<T>[]) => DataAdapterRecord<T>[];
50
+
51
+ constructor(config?: ArrayAdapterConfig) {
52
+ super(config);
53
+ }
54
+
55
+ public init(): void {
56
+ this.recordsAccessor = this.recordsBinding ? getAccessor(this.recordsBinding) : getAccessor(this.recordsAccessor);
57
+ this.recordName = this.recordName?.toString() || "$record";
58
+ this.indexName = this.indexName?.toString() || "$index";
59
+ }
60
+
61
+ public initInstance(context: RenderingContext, instance: Instance & Partial<RecordStoreCache>): void {
62
+ if (!instance.recordStoreCache) {
63
+ instance.recordStoreCache = new WeakMap();
64
+ instance.cacheByKey = {};
65
+ }
66
+
67
+ if (!instance.recordsAccessor && this.recordsAccessor) {
68
+ instance.recordsAccessor = this.recordsAccessor.bindInstance
69
+ ? this.recordsAccessor.bindInstance(instance)
70
+ : this.recordsAccessor;
71
+ }
72
+ }
73
+
74
+ public getRecords(
75
+ context: RenderingContext,
76
+ instance: Instance & Partial<RecordStoreCache>,
77
+ records: T[],
78
+ parentStore: View,
79
+ ): DataAdapterRecord<T>[] {
80
+ if (!instance.recordStoreCache) {
81
+ this.initInstance(context, instance);
82
+ }
83
+
84
+ return this.mapRecords(context, instance, records, parentStore, instance.recordsAccessor);
85
+ }
86
+
87
+ public mapRecords(
88
+ context: RenderingContext,
89
+ instance: Instance & Partial<RecordStoreCache>,
90
+ records: T[],
91
+ parentStore: View,
92
+ recordsAccessor?: Accessor,
93
+ ): DataAdapterRecord<T>[] {
94
+ let result: DataAdapterRecord<T>[] = [];
95
+
96
+ if (!instance.recordStoreCache) {
97
+ this.initInstance(context, instance);
98
+ }
99
+
100
+ if (isArray(records)) {
101
+ records.forEach((data, index) => {
102
+ if (this.filterFn && !this.filterFn(data)) return;
103
+
104
+ const record = this.mapRecord(context, instance, data, parentStore, recordsAccessor, index);
105
+ result.push(record);
106
+ });
107
+ }
108
+
109
+ if (this.sorter && !this.preserveOrder) {
110
+ result = this.sorter(result);
111
+ }
112
+
113
+ return result;
114
+ }
115
+
116
+ public mapRecord(
117
+ context: RenderingContext,
118
+ instance: Instance & Partial<RecordStoreCache>,
119
+ data: T,
120
+ parentStore: View,
121
+ recordsAccessor: Accessor | undefined,
122
+ index: number,
123
+ ): DataAdapterRecord<T> {
124
+ const key = this.cacheByKeyField && this.keyField && isObject(data) ? (data as any)[this.keyField] : null;
125
+ let recordStore = key != null ? instance.cacheByKey![key] : instance.recordStoreCache!.get(data);
126
+
127
+ if (recordsAccessor) {
128
+ if (!recordStore) {
129
+ recordStore = new ArrayElementView({
130
+ store: parentStore,
131
+ arrayAccessor: recordsAccessor,
132
+ itemIndex: index,
133
+ recordAlias: this.recordName,
134
+ indexAlias: this.indexName,
135
+ immutable: this.immutable,
136
+ sealed: this.sealed,
137
+ });
138
+ } else {
139
+ (recordStore as ArrayElementView).setStore(parentStore);
140
+ (recordStore as ArrayElementView).setIndex(index);
141
+ }
142
+ } else {
143
+ if (!recordStore) {
144
+ recordStore = new ReadOnlyDataView({
145
+ store: parentStore,
146
+ data: {
147
+ [this.recordName]: data,
148
+ [this.indexName]: index,
149
+ },
150
+ immutable: this.immutable,
151
+ sealed: this.sealed,
152
+ });
153
+ } else {
154
+ (recordStore as ReadOnlyDataView).setStore(parentStore);
155
+ (recordStore as ReadOnlyDataView).setData({
156
+ [this.recordName]: data,
157
+ [this.indexName]: index,
158
+ });
159
+ }
160
+ }
161
+
162
+ if (key != null) {
163
+ instance.cacheByKey![key] = recordStore;
164
+ } else if (isObject(data)) {
165
+ instance.recordStoreCache!.set(data, recordStore);
166
+ }
167
+
168
+ return {
169
+ store: recordStore,
170
+ index: index,
171
+ data: data,
172
+ type: "data",
173
+ key: this.keyField && isObject(data) ? (data as any)[this.keyField] : index,
174
+ };
175
+ }
176
+
177
+ public setFilter(filterFn?: (data: T) => boolean): void {
178
+ this.filterFn = filterFn;
179
+ }
180
+
181
+ public getComparer(sortOptions?: CollatorOptions): ((a: any, b: any) => number) | undefined {
182
+ return sortOptions ? Culture.getComparer(sortOptions) : undefined;
183
+ }
184
+
185
+ public buildSorter(sorters: ExtendedSorter[]): void {
186
+ if (isArray(sorters) && sorters.length > 0) {
187
+ let dataAccessor: (x: DataAdapterRecord<T>) => any;
188
+ let fieldValueMapper: (x: ExtendedSorter) => Prop<any>;
189
+
190
+ if (sorters.every((x) => x.field && x.value == null)) {
191
+ dataAccessor = (x) => x.data;
192
+ fieldValueMapper = (x) => ({ bind: x.field! });
193
+ } else {
194
+ dataAccessor = (x) => x.store.getData();
195
+ fieldValueMapper = (x) => ({ bind: this.recordName + "." + x.field });
196
+ }
197
+
198
+ this.sorter = sorter(
199
+ sorters.map((x) => {
200
+ const s: ExtendedSorter = Object.assign({}, x);
201
+ if (s.field && s.value == null) {
202
+ s.value = fieldValueMapper(s);
203
+ }
204
+ if (!s.comparer) {
205
+ s.comparer = this.getComparer(isDefined(s.sortOptions) ? s.sortOptions : this.sortOptions);
206
+ }
207
+ return s;
208
+ }),
209
+ dataAccessor,
210
+ );
211
+ } else {
212
+ this.sorter = undefined;
213
+ }
214
+ }
215
+
216
+ public sort(sorters?: Sorter[] | ExtendedSorter[]): void {
217
+ if (sorters) {
218
+ this.buildSorter(sorters as ExtendedSorter[]);
219
+ }
220
+ }
221
+ }
222
+
223
+ ArrayAdapter.prototype.immutable = false;
224
+ ArrayAdapter.prototype.sealed = false;
225
+ ArrayAdapter.prototype.keyField = null;
226
+ ArrayAdapter.prototype.cacheByKeyField = true;
227
+ ArrayAdapter.prototype.isTreeAdapter = false;
228
+
229
+ ArrayAdapter.autoInit = true;
@@ -1,17 +1,15 @@
1
- import { ArrayAdapter, ArrayAdapterConfig, RecordStoreCache } from "./ArrayAdapter";
2
- import { DataAdapterRecord } from "./DataAdapter";
3
- import { ReadOnlyDataView } from "../../data/ReadOnlyDataView";
1
+ import { getComparer } from "../../data/comparer";
4
2
  import { Grouper } from "../../data/Grouper";
3
+ import { ReadOnlyDataView } from "../../data/ReadOnlyDataView";
4
+ import { View } from "../../data/View";
5
+ import { isDataRecord } from "../../util";
5
6
  import { isArray } from "../../util/isArray";
6
- import { isDefined } from "../../util/isDefined";
7
- import { getComparer } from "../../data/comparer";
8
7
  import { Culture } from "../Culture";
9
- import { isObject } from "../../util/isObject";
10
- import { RenderingContext } from "../RenderingContext";
11
8
  import { Instance } from "../Instance";
12
- import { View } from "../../data/View";
13
- import { Prop, Sorter, SortDirection, StructuredProp } from "../Prop";
14
- import { isDataRecord } from "../../util";
9
+ import { Prop, SortDirection, Sorter, StructuredProp } from "../Prop";
10
+ import { RenderingContext } from "../RenderingContext";
11
+ import { ArrayAdapter, ArrayAdapterConfig, RecordStoreCache } from "./ArrayAdapter";
12
+ import { DataAdapterRecord } from "./DataAdapter";
15
13
 
16
14
  export interface GroupKey {
17
15
  [field: string]: Prop<any> | { value: Prop<any>; direction: SortDirection };
@@ -1,13 +1,17 @@
1
1
  import { Accessor, getAccessor } from "../../data/getAccessor";
2
2
  import { isArray } from "../../util/isArray";
3
- import { ArrayAdapter, ArrayAdapterConfig, RecordStoreCache } from "./ArrayAdapter";
3
+ import {
4
+ ArrayAdapter,
5
+ ArrayAdapterConfig,
6
+ RecordStoreCache,
7
+ } from "./ArrayAdapter";
4
8
  import { DataAdapterRecord } from "./DataAdapter";
5
9
  import { RenderingContext } from "../RenderingContext";
6
10
  import { Instance } from "../Instance";
7
11
  import { View } from "../../data/View";
8
12
  import { Sorter } from "../Prop";
9
13
 
10
- export interface TreeNode {
14
+ export interface DefaultTreeNode {
11
15
  $level?: number;
12
16
  $expanded?: boolean;
13
17
  $leaf?: boolean;
@@ -31,10 +35,21 @@ export interface TreeAdapterConfig extends ArrayAdapterConfig {
31
35
  foldersFirst?: boolean;
32
36
  hideRootNodes?: boolean;
33
37
  restoreExpandedNodesOnLoad?: boolean;
34
- load?: (context: RenderingContext, instance: Instance, data: TreeNode) => Promise<any[]> | any[];
38
+ load?: (
39
+ context: RenderingContext,
40
+ instance: Instance,
41
+ node: any,
42
+ ) => Promise<any[] | null | undefined> | any[] | null | undefined;
43
+ onLoad?: (
44
+ context: RenderingContext,
45
+ instance: Instance,
46
+ node: any,
47
+ ) => Promise<any[] | null | undefined> | any[] | null | undefined;
35
48
  }
36
49
 
37
- export class TreeAdapter<T extends TreeNode = TreeNode> extends ArrayAdapter<T> {
50
+ export class TreeAdapter<
51
+ T extends object = DefaultTreeNode,
52
+ > extends ArrayAdapter<T> {
38
53
  declare public childrenField: string;
39
54
  declare public expandedField: string;
40
55
  declare public leafField: string;
@@ -44,7 +59,17 @@ export class TreeAdapter<T extends TreeNode = TreeNode> extends ArrayAdapter<T>
44
59
  declare public foldersFirst: boolean;
45
60
  declare public hideRootNodes: boolean;
46
61
  declare public restoreExpandedNodesOnLoad?: boolean;
47
- declare public load?: (context: RenderingContext, instance: Instance, data: T) => Promise<any[]> | any[];
62
+ declare public load?: (
63
+ context: RenderingContext,
64
+ instance: Instance,
65
+ data: T,
66
+ ) => Promise<any[]> | any[];
67
+
68
+ declare public onLoad?: (
69
+ context: RenderingContext,
70
+ instance: Instance,
71
+ data: T,
72
+ ) => Promise<any[]> | any[];
48
73
 
49
74
  declare protected childrenAccessor?: Accessor;
50
75
  declare protected expandedState?: ExpandedState;
@@ -55,7 +80,9 @@ export class TreeAdapter<T extends TreeNode = TreeNode> extends ArrayAdapter<T>
55
80
 
56
81
  public init(): void {
57
82
  super.init();
58
- this.childrenAccessor = getAccessor({ bind: `${this.recordName}.${this.childrenField}` });
83
+ this.childrenAccessor = getAccessor({
84
+ bind: `${this.recordName}.${this.childrenField}`,
85
+ });
59
86
 
60
87
  if (this.restoreExpandedNodesOnLoad) {
61
88
  if (!this.keyField) {
@@ -68,6 +95,8 @@ export class TreeAdapter<T extends TreeNode = TreeNode> extends ArrayAdapter<T>
68
95
  next: new Set(),
69
96
  };
70
97
  }
98
+
99
+ if (this.load) this.onLoad = this.load;
71
100
  }
72
101
 
73
102
  public mapRecords(
@@ -77,7 +106,13 @@ export class TreeAdapter<T extends TreeNode = TreeNode> extends ArrayAdapter<T>
77
106
  parentStore: View,
78
107
  recordsAccessor?: Accessor,
79
108
  ): DataAdapterRecord<T>[] {
80
- const nodes = super.mapRecords(context, instance, data, parentStore, recordsAccessor);
109
+ const nodes = super.mapRecords(
110
+ context,
111
+ instance,
112
+ data,
113
+ parentStore,
114
+ recordsAccessor,
115
+ );
81
116
  const result: DataAdapterRecord<T>[] = [];
82
117
 
83
118
  if (this.restoreExpandedNodesOnLoad) {
@@ -123,8 +158,13 @@ export class TreeAdapter<T extends TreeNode = TreeNode> extends ArrayAdapter<T>
123
158
  dataRecord.$level = this.hideRootNodes ? level - 1 : level;
124
159
 
125
160
  if (!dataRecord[this.leafField]) {
126
- if (this.restoreExpandedNodesOnLoad && dataRecord[this.expandedField] == null) {
127
- dataRecord[this.expandedField] = this.expandedState!.current!.has(dataRecord[this.keyField!]);
161
+ if (
162
+ this.restoreExpandedNodesOnLoad &&
163
+ dataRecord[this.expandedField] == null
164
+ ) {
165
+ dataRecord[this.expandedField] = this.expandedState!.current!.has(
166
+ dataRecord[this.keyField!],
167
+ );
128
168
  }
129
169
 
130
170
  if (dataRecord[this.expandedField] || isHiddenRootNode) {
@@ -140,18 +180,38 @@ export class TreeAdapter<T extends TreeNode = TreeNode> extends ArrayAdapter<T>
140
180
  store,
141
181
  this.childrenAccessor,
142
182
  );
143
- this.processList(context, instance, level + 1, record.key + ":", childNodes, result);
144
- } else if (this.load && !dataRecord[this.loadedField] && !dataRecord[this.loadingField]) {
183
+ this.processList(
184
+ context,
185
+ instance,
186
+ level + 1,
187
+ record.key + ":",
188
+ childNodes,
189
+ result,
190
+ );
191
+ } else if (
192
+ this.onLoad &&
193
+ !dataRecord[this.loadedField] &&
194
+ !dataRecord[this.loadingField]
195
+ ) {
145
196
  store.set(`${this.recordName}.${this.loadingField}`, true);
146
- const response = this.load(context, instance, data);
197
+ const response = this.onLoad(context, instance, data);
147
198
  Promise.resolve(response)
148
199
  .then((children) => {
149
- store.set(`${this.recordName}.${this.childrenField}`, children);
200
+ store.set(
201
+ `${this.recordName}.${this.childrenField}`,
202
+ children,
203
+ );
150
204
  store.set(`${this.recordName}.${this.loadedField}`, true);
151
- store.set(`${this.recordName}.${this.loadingField}`, false);
205
+ store.set(
206
+ `${this.recordName}.${this.loadingField}`,
207
+ false,
208
+ );
152
209
  })
153
210
  .catch((response) => {
154
- store.set(`${this.recordName}.${this.loadingField}`, false);
211
+ store.set(
212
+ `${this.recordName}.${this.loadingField}`,
213
+ false,
214
+ );
155
215
  if (this.onLoadError) {
156
216
  this.onLoadError(response);
157
217
  }
@@ -1,5 +1,5 @@
1
1
  import { Url } from "./Url";
2
- import Route from "route-parser";
2
+ import Route from "route-parser-ts";
3
3
  import assert from "assert";
4
4
  describe("Url", function () {
5
5
  describe(".unresolve", function () {