cx 26.4.1 → 26.4.2
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/build/charts/shapes.d.ts.map +1 -1
- package/build/charts/shapes.js +14 -7
- package/build/widgets/overlay/ContextMenu.d.ts.map +1 -1
- package/build/widgets/overlay/ContextMenu.js +1 -0
- package/build/widgets/overlay/Dropdown.d.ts +11 -3
- package/build/widgets/overlay/Dropdown.d.ts.map +1 -1
- package/build/widgets/overlay/Dropdown.js +52 -25
- package/build/widgets/overlay/Overlay.d.ts.map +1 -1
- package/build/widgets/overlay/Overlay.js +1 -1
- package/dist/charts.js +80 -45
- package/dist/manifest.js +744 -744
- package/dist/widgets.css +13 -12
- package/dist/widgets.js +215 -85
- package/package.json +1 -1
- package/src/charts/BarGraph.scss +31 -31
- package/src/charts/Legend.scss +57 -57
- package/src/charts/LegendEntry.scss +35 -35
- package/src/charts/LineGraph.scss +28 -28
- package/src/charts/helpers/SnapPointFinder.ts +136 -136
- package/src/charts/helpers/ValueAtFinder.ts +72 -72
- package/src/charts/shapes.tsx +14 -7
- package/src/data/createAccessorModelProxy.ts +66 -66
- package/src/ui/DataProxy.ts +55 -55
- package/src/ui/Repeater.spec.tsx +181 -181
- package/src/ui/Rescope.ts +50 -50
- package/src/ui/adapter/ArrayAdapter.ts +229 -229
- package/src/ui/exprHelpers.ts +96 -96
- package/src/util/scss/include.scss +69 -69
- package/src/widgets/Button.maps.scss +103 -103
- package/src/widgets/Sandbox.ts +104 -104
- package/src/widgets/form/Calendar.tsx +772 -772
- package/src/widgets/form/ColorField.scss +112 -112
- package/src/widgets/form/DateTimeField.scss +111 -111
- package/src/widgets/form/LookupField.maps.scss +26 -26
- package/src/widgets/form/LookupField.scss +227 -227
- package/src/widgets/form/MonthField.scss +113 -113
- package/src/widgets/form/NumberField.scss +72 -72
- package/src/widgets/form/Select.scss +104 -104
- package/src/widgets/form/TextField.scss +66 -66
- package/src/widgets/grid/Grid.scss +657 -657
- package/src/widgets/grid/variables.scss +47 -47
- package/src/widgets/index.ts +63 -63
- package/src/widgets/nav/MenuItem.scss +150 -150
- package/src/widgets/nav/MenuItem.tsx +525 -525
- package/src/widgets/nav/Tab.ts +122 -122
- package/src/widgets/overlay/ContextMenu.ts +1 -0
- package/src/widgets/overlay/Dropdown.scss +7 -6
- package/src/widgets/overlay/Dropdown.tsx +59 -16
- package/src/widgets/overlay/Overlay.tsx +1029 -1028
- package/src/widgets/variables.scss +61 -61
package/src/ui/Rescope.ts
CHANGED
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
import { Widget } from "./Widget";
|
|
2
|
-
import { PureContainerBase, PureContainerConfig } from "./PureContainer";
|
|
3
|
-
import { Binding } from "../data/Binding";
|
|
4
|
-
import { ZoomIntoPropertyView } from "../data/ZoomIntoPropertyView";
|
|
5
|
-
import { StructuredInstanceDataAccessor } from "./StructuredInstanceDataAccessor";
|
|
6
|
-
import { isObject } from "../util/isObject";
|
|
7
|
-
import { StructuredProp } from "./Prop";
|
|
8
|
-
import { AccessorChain } from "../data/createAccessorModelProxy";
|
|
9
|
-
|
|
10
|
-
export interface RescopeConfig extends PureContainerConfig {
|
|
11
|
-
bind: string | AccessorChain<any>;
|
|
12
|
-
rootName?: string | AccessorChain<any>;
|
|
13
|
-
rootAlias?: string | AccessorChain<any>;
|
|
14
|
-
data?: StructuredProp;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class Rescope extends PureContainerBase<RescopeConfig> {
|
|
18
|
-
declare bind: string;
|
|
19
|
-
declare binding: any;
|
|
20
|
-
declare rootAlias?: string;
|
|
21
|
-
declare rootName: string;
|
|
22
|
-
declare data?: any;
|
|
23
|
-
|
|
24
|
-
init() {
|
|
25
|
-
this.binding = Binding.get(this.bind);
|
|
26
|
-
if (this.rootAlias) this.rootName = this.rootAlias;
|
|
27
|
-
super.init();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
initInstance(context: any, instance: any) {
|
|
31
|
-
instance.store = new ZoomIntoPropertyView({
|
|
32
|
-
store: instance.parentStore,
|
|
33
|
-
binding: this.binding,
|
|
34
|
-
rootName: this.rootName,
|
|
35
|
-
nestedData: isObject(this.data)
|
|
36
|
-
? new StructuredInstanceDataAccessor({ instance, data: this.data, useParentStore: true })
|
|
37
|
-
: undefined,
|
|
38
|
-
});
|
|
39
|
-
super.initInstance(context, instance);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
applyParentStore(instance: any) {
|
|
43
|
-
instance.store.setStore(instance.parentStore);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
Rescope.prototype.bind = "$page";
|
|
48
|
-
Rescope.prototype.rootName = "$root";
|
|
49
|
-
|
|
50
|
-
Widget.alias("rescope", Rescope);
|
|
1
|
+
import { Widget } from "./Widget";
|
|
2
|
+
import { PureContainerBase, PureContainerConfig } from "./PureContainer";
|
|
3
|
+
import { Binding } from "../data/Binding";
|
|
4
|
+
import { ZoomIntoPropertyView } from "../data/ZoomIntoPropertyView";
|
|
5
|
+
import { StructuredInstanceDataAccessor } from "./StructuredInstanceDataAccessor";
|
|
6
|
+
import { isObject } from "../util/isObject";
|
|
7
|
+
import { StructuredProp } from "./Prop";
|
|
8
|
+
import { AccessorChain } from "../data/createAccessorModelProxy";
|
|
9
|
+
|
|
10
|
+
export interface RescopeConfig extends PureContainerConfig {
|
|
11
|
+
bind: string | AccessorChain<any>;
|
|
12
|
+
rootName?: string | AccessorChain<any>;
|
|
13
|
+
rootAlias?: string | AccessorChain<any>;
|
|
14
|
+
data?: StructuredProp;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class Rescope extends PureContainerBase<RescopeConfig> {
|
|
18
|
+
declare bind: string;
|
|
19
|
+
declare binding: any;
|
|
20
|
+
declare rootAlias?: string;
|
|
21
|
+
declare rootName: string;
|
|
22
|
+
declare data?: any;
|
|
23
|
+
|
|
24
|
+
init() {
|
|
25
|
+
this.binding = Binding.get(this.bind);
|
|
26
|
+
if (this.rootAlias) this.rootName = this.rootAlias;
|
|
27
|
+
super.init();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
initInstance(context: any, instance: any) {
|
|
31
|
+
instance.store = new ZoomIntoPropertyView({
|
|
32
|
+
store: instance.parentStore,
|
|
33
|
+
binding: this.binding,
|
|
34
|
+
rootName: this.rootName,
|
|
35
|
+
nestedData: isObject(this.data)
|
|
36
|
+
? new StructuredInstanceDataAccessor({ instance, data: this.data, useParentStore: true })
|
|
37
|
+
: undefined,
|
|
38
|
+
});
|
|
39
|
+
super.initInstance(context, instance);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
applyParentStore(instance: any) {
|
|
43
|
+
instance.store.setStore(instance.parentStore);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
Rescope.prototype.bind = "$page";
|
|
48
|
+
Rescope.prototype.rootName = "$root";
|
|
49
|
+
|
|
50
|
+
Widget.alias("rescope", Rescope);
|
|
@@ -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;
|