@visactor/vbi 0.4.14 → 0.4.16
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/builder/{sub-builders → features}/chart-type/chart-type-builder.d.ts +1 -1
- package/dist/builder/{sub-builders → features}/dimensions/dim-builder.d.ts +1 -1
- package/dist/builder/{sub-builders → features}/dimensions/dim-node-builder.d.ts +1 -1
- package/dist/builder/{sub-builders/havingFilters → features/havingFilter}/having-builder.d.ts +13 -13
- package/dist/builder/{sub-builders/havingFilters → features/havingFilter}/having-group-builder.d.ts +4 -3
- package/dist/builder/{sub-builders/havingFilters → features/havingFilter}/having-node-builder.d.ts +2 -2
- package/dist/builder/features/havingFilter/having-utils.d.ts +9 -0
- package/dist/builder/features/havingFilter/index.d.ts +3 -0
- package/dist/builder/features/index.d.ts +9 -0
- package/dist/builder/features/limit/index.d.ts +1 -0
- package/dist/builder/features/limit/limit-builder.d.ts +31 -0
- package/dist/builder/features/locale/index.d.ts +1 -0
- package/dist/builder/features/locale/locale-builder.d.ts +31 -0
- package/dist/builder/{sub-builders → features}/measures/mea-builder.d.ts +1 -1
- package/dist/builder/{sub-builders → features}/measures/mea-node-builder.d.ts +1 -1
- package/dist/builder/features/theme/index.d.ts +1 -0
- package/dist/builder/features/theme/theme-builder.d.ts +31 -0
- package/dist/builder/features/undo-manager/index.d.ts +1 -0
- package/dist/builder/{sub-builders/whereFilters → features/whereFilter}/index.d.ts +1 -1
- package/dist/builder/{sub-builders/whereFilters → features/whereFilter}/where-builder.d.ts +11 -11
- package/dist/builder/{sub-builders/whereFilters → features/whereFilter}/where-group-builder.d.ts +2 -1
- package/dist/builder/{sub-builders/whereFilters → features/whereFilter}/where-node-builder.d.ts +6 -1
- package/dist/builder/features/whereFilter/where-utils.d.ts +9 -0
- package/dist/builder/index.d.ts +1 -2
- package/dist/builder/vbi-builder.d.ts +6 -11
- package/dist/builder/vbi.d.ts +2 -2
- package/dist/index.cjs +521 -334
- package/dist/index.d.ts +1 -1
- package/dist/index.js +498 -329
- package/dist/types/builder/VBIInterface.d.ts +6 -5
- package/dist/types/dsl/{havingFilters → havingFilter}/having.d.ts +10 -6
- package/dist/types/dsl/index.d.ts +4 -5
- package/dist/types/dsl/measures/measures.d.ts +16 -2
- package/dist/types/dsl/vbi/vbi.d.ts +40 -4
- package/dist/types/dsl/{whereFilters → whereFilter}/filters.d.ts +10 -6
- package/dist/utils/filter-guards.d.ts +5 -0
- package/dist/utils/index.d.ts +1 -0
- package/package.json +5 -5
- package/dist/builder/sub-builders/havingFilters/index.d.ts +0 -3
- package/dist/builder/sub-builders/index.d.ts +0 -5
- /package/dist/builder/{sub-builders → features}/chart-type/index.d.ts +0 -0
- /package/dist/builder/{sub-builders → features}/dimensions/index.d.ts +0 -0
- /package/dist/builder/{sub-builders → features}/measures/index.d.ts +0 -0
- /package/dist/builder/{undo-manager.d.ts → features/undo-manager/undo-manager.d.ts} +0 -0
package/dist/index.js
CHANGED
|
@@ -2,8 +2,7 @@ import { Array as external_yjs_Array, Doc, Map as external_yjs_Map, UndoManager,
|
|
|
2
2
|
import { ChartTypeEnum, findTreeNodesBy, preorderTraverse } from "@visactor/vseed";
|
|
3
3
|
import { v4 } from "uuid";
|
|
4
4
|
import { pipe } from "remeda";
|
|
5
|
-
|
|
6
|
-
class DimensionNodeBuilder {
|
|
5
|
+
class MeasureNodeBuilder {
|
|
7
6
|
yMap;
|
|
8
7
|
constructor(yMap){
|
|
9
8
|
this.yMap = yMap;
|
|
@@ -15,71 +14,83 @@ class DimensionNodeBuilder {
|
|
|
15
14
|
this.yMap.set('alias', alias);
|
|
16
15
|
return this;
|
|
17
16
|
}
|
|
18
|
-
|
|
17
|
+
setEncoding(encoding) {
|
|
18
|
+
this.yMap.set('encoding', encoding);
|
|
19
|
+
return this;
|
|
20
|
+
}
|
|
21
|
+
setAggregate(aggregate) {
|
|
22
|
+
this.yMap.set('aggregate', aggregate);
|
|
23
|
+
return this;
|
|
24
|
+
}
|
|
25
|
+
toJSON() {
|
|
19
26
|
return this.yMap.toJSON();
|
|
20
27
|
}
|
|
21
28
|
}
|
|
22
|
-
class
|
|
29
|
+
class MeasuresBuilder {
|
|
23
30
|
dsl;
|
|
24
31
|
constructor(_doc, dsl){
|
|
25
32
|
this.dsl = dsl;
|
|
26
33
|
}
|
|
27
34
|
add(field, callback) {
|
|
28
|
-
const
|
|
35
|
+
const measure = {
|
|
29
36
|
alias: field,
|
|
30
|
-
field
|
|
37
|
+
field,
|
|
38
|
+
encoding: 'yAxis',
|
|
39
|
+
aggregate: {
|
|
40
|
+
func: 'sum'
|
|
41
|
+
}
|
|
31
42
|
};
|
|
32
43
|
const yMap = new external_yjs_Map();
|
|
33
|
-
for (const [key, value] of Object.entries(
|
|
34
|
-
this.dsl.get('
|
|
44
|
+
for (const [key, value] of Object.entries(measure))yMap.set(key, value);
|
|
45
|
+
this.dsl.get('measures').push([
|
|
35
46
|
yMap
|
|
36
47
|
]);
|
|
37
|
-
const node = new
|
|
48
|
+
const node = new MeasureNodeBuilder(yMap);
|
|
38
49
|
callback(node);
|
|
39
50
|
return this;
|
|
40
51
|
}
|
|
41
52
|
remove(field) {
|
|
42
|
-
const
|
|
43
|
-
const index =
|
|
44
|
-
if (-1 !== index) this.dsl.get('
|
|
53
|
+
const measures = this.dsl.get('measures');
|
|
54
|
+
const index = measures.toArray().findIndex((item)=>item.get('field') === field);
|
|
55
|
+
if (-1 !== index) this.dsl.get('measures').delete(index, 1);
|
|
45
56
|
return this;
|
|
46
57
|
}
|
|
47
58
|
update(field, callback) {
|
|
48
|
-
const
|
|
49
|
-
const index =
|
|
50
|
-
if (-1 === index) throw new Error(`
|
|
51
|
-
const
|
|
52
|
-
const node = new
|
|
59
|
+
const measures = this.dsl.get('measures');
|
|
60
|
+
const index = measures.toArray().findIndex((item)=>item.get('field') === field);
|
|
61
|
+
if (-1 === index) throw new Error(`Measure with field "${field}" not found`);
|
|
62
|
+
const measureYMap = measures.get(index);
|
|
63
|
+
const node = new MeasureNodeBuilder(measureYMap);
|
|
53
64
|
callback(node);
|
|
54
65
|
return this;
|
|
55
66
|
}
|
|
56
67
|
find(field) {
|
|
57
|
-
const
|
|
58
|
-
const index =
|
|
68
|
+
const measures = this.dsl.get('measures');
|
|
69
|
+
const index = measures.toArray().findIndex((item)=>item.get('field') === field);
|
|
59
70
|
if (-1 === index) return;
|
|
60
|
-
return new
|
|
71
|
+
return new MeasureNodeBuilder(measures.get(index));
|
|
61
72
|
}
|
|
62
73
|
findAll() {
|
|
63
|
-
const
|
|
64
|
-
return
|
|
74
|
+
const measures = this.dsl.get('measures');
|
|
75
|
+
return measures.toArray().map((yMap)=>new MeasureNodeBuilder(yMap));
|
|
65
76
|
}
|
|
66
|
-
|
|
67
|
-
return this.dsl.get('
|
|
77
|
+
toJSON() {
|
|
78
|
+
return this.dsl.get('measures').toJSON();
|
|
68
79
|
}
|
|
69
80
|
observe(callback) {
|
|
70
|
-
this.dsl.get('
|
|
81
|
+
this.dsl.get('measures').observe(callback);
|
|
71
82
|
return ()=>{
|
|
72
|
-
this.dsl.get('
|
|
83
|
+
this.dsl.get('measures').unobserve(callback);
|
|
73
84
|
};
|
|
74
85
|
}
|
|
75
|
-
static
|
|
76
|
-
return '
|
|
86
|
+
static isMeasureNode(node) {
|
|
87
|
+
return 'encoding' in node || 'aggregate' in node;
|
|
77
88
|
}
|
|
78
|
-
static
|
|
89
|
+
static isMeasureGroup(node) {
|
|
79
90
|
return 'children' in node;
|
|
80
91
|
}
|
|
81
92
|
}
|
|
82
|
-
class
|
|
93
|
+
class DimensionNodeBuilder {
|
|
83
94
|
yMap;
|
|
84
95
|
constructor(yMap){
|
|
85
96
|
this.yMap = yMap;
|
|
@@ -91,86 +102,161 @@ class MeasureNodeBuilder {
|
|
|
91
102
|
this.yMap.set('alias', alias);
|
|
92
103
|
return this;
|
|
93
104
|
}
|
|
94
|
-
|
|
95
|
-
this.yMap.set('encoding', encoding);
|
|
96
|
-
return this;
|
|
97
|
-
}
|
|
98
|
-
setAggregate(aggregate) {
|
|
99
|
-
this.yMap.set('aggregate', aggregate);
|
|
100
|
-
return this;
|
|
101
|
-
}
|
|
102
|
-
toJson() {
|
|
105
|
+
toJSON() {
|
|
103
106
|
return this.yMap.toJSON();
|
|
104
107
|
}
|
|
105
108
|
}
|
|
106
|
-
class
|
|
109
|
+
class DimensionsBuilder {
|
|
107
110
|
dsl;
|
|
108
111
|
constructor(_doc, dsl){
|
|
109
112
|
this.dsl = dsl;
|
|
110
113
|
}
|
|
111
114
|
add(field, callback) {
|
|
112
|
-
const
|
|
115
|
+
const dimension = {
|
|
113
116
|
alias: field,
|
|
114
|
-
field
|
|
115
|
-
encoding: 'yAxis',
|
|
116
|
-
aggregate: {
|
|
117
|
-
func: 'sum'
|
|
118
|
-
}
|
|
117
|
+
field
|
|
119
118
|
};
|
|
120
119
|
const yMap = new external_yjs_Map();
|
|
121
|
-
for (const [key, value] of Object.entries(
|
|
122
|
-
this.dsl.get('
|
|
120
|
+
for (const [key, value] of Object.entries(dimension))yMap.set(key, value);
|
|
121
|
+
this.dsl.get('dimensions').push([
|
|
123
122
|
yMap
|
|
124
123
|
]);
|
|
125
|
-
const node = new
|
|
124
|
+
const node = new DimensionNodeBuilder(yMap);
|
|
126
125
|
callback(node);
|
|
127
126
|
return this;
|
|
128
127
|
}
|
|
129
128
|
remove(field) {
|
|
130
|
-
const
|
|
131
|
-
const index =
|
|
132
|
-
if (-1 !== index) this.dsl.get('
|
|
129
|
+
const dimensions = this.dsl.get('dimensions');
|
|
130
|
+
const index = dimensions.toArray().findIndex((item)=>item.get('field') === field);
|
|
131
|
+
if (-1 !== index) this.dsl.get('dimensions').delete(index, 1);
|
|
133
132
|
return this;
|
|
134
133
|
}
|
|
135
134
|
update(field, callback) {
|
|
136
|
-
const
|
|
137
|
-
const index =
|
|
138
|
-
if (-1 === index) throw new Error(`
|
|
139
|
-
const
|
|
140
|
-
const node = new
|
|
135
|
+
const dimensions = this.dsl.get('dimensions');
|
|
136
|
+
const index = dimensions.toArray().findIndex((item)=>item.get('field') === field);
|
|
137
|
+
if (-1 === index) throw new Error(`Dimension with field "${field}" not found`);
|
|
138
|
+
const dimensionYMap = dimensions.get(index);
|
|
139
|
+
const node = new DimensionNodeBuilder(dimensionYMap);
|
|
141
140
|
callback(node);
|
|
142
141
|
return this;
|
|
143
142
|
}
|
|
144
143
|
find(field) {
|
|
145
|
-
const
|
|
146
|
-
const index =
|
|
144
|
+
const dimensions = this.dsl.get('dimensions');
|
|
145
|
+
const index = dimensions.toArray().findIndex((item)=>item.get('field') === field);
|
|
147
146
|
if (-1 === index) return;
|
|
148
|
-
return new
|
|
147
|
+
return new DimensionNodeBuilder(dimensions.get(index));
|
|
149
148
|
}
|
|
150
149
|
findAll() {
|
|
151
|
-
const
|
|
152
|
-
return
|
|
150
|
+
const dimensions = this.dsl.get('dimensions');
|
|
151
|
+
return dimensions.toArray().map((yMap)=>new DimensionNodeBuilder(yMap));
|
|
153
152
|
}
|
|
154
|
-
|
|
155
|
-
return this.dsl.get('
|
|
153
|
+
toJSON() {
|
|
154
|
+
return this.dsl.get('dimensions').toJSON();
|
|
156
155
|
}
|
|
157
156
|
observe(callback) {
|
|
158
|
-
this.dsl.get('
|
|
157
|
+
this.dsl.get('dimensions').observe(callback);
|
|
159
158
|
return ()=>{
|
|
160
|
-
this.dsl.get('
|
|
159
|
+
this.dsl.get('dimensions').unobserve(callback);
|
|
161
160
|
};
|
|
162
161
|
}
|
|
163
|
-
static
|
|
164
|
-
return '
|
|
162
|
+
static isDimensionNode(node) {
|
|
163
|
+
return 'alias' in node && !('children' in node);
|
|
165
164
|
}
|
|
166
|
-
static
|
|
165
|
+
static isDimensionGroup(node) {
|
|
167
166
|
return 'children' in node;
|
|
168
167
|
}
|
|
169
168
|
}
|
|
169
|
+
class ChartTypeBuilder {
|
|
170
|
+
dsl;
|
|
171
|
+
constructor(_doc, dsl){
|
|
172
|
+
this.dsl = dsl;
|
|
173
|
+
}
|
|
174
|
+
observe(callback) {
|
|
175
|
+
const wrapper = (e, trans)=>{
|
|
176
|
+
if (e.keysChanged.has('chartType')) callback(e, trans);
|
|
177
|
+
};
|
|
178
|
+
this.dsl.observe(wrapper);
|
|
179
|
+
return ()=>{
|
|
180
|
+
this.dsl.unobserve(wrapper);
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
changeChartType(chartType) {
|
|
184
|
+
this.dsl.set('chartType', chartType);
|
|
185
|
+
}
|
|
186
|
+
getChartType() {
|
|
187
|
+
return this.dsl.get('chartType') || 'table';
|
|
188
|
+
}
|
|
189
|
+
toJSON() {
|
|
190
|
+
return this.dsl.get('chartType') || 'table';
|
|
191
|
+
}
|
|
192
|
+
getAvailableChartTypes() {
|
|
193
|
+
return [
|
|
194
|
+
ChartTypeEnum.Table,
|
|
195
|
+
ChartTypeEnum.PivotTable,
|
|
196
|
+
ChartTypeEnum.Line,
|
|
197
|
+
ChartTypeEnum.Column,
|
|
198
|
+
ChartTypeEnum.ColumnPercent,
|
|
199
|
+
ChartTypeEnum.ColumnParallel,
|
|
200
|
+
ChartTypeEnum.BarPercent,
|
|
201
|
+
ChartTypeEnum.BarParallel,
|
|
202
|
+
ChartTypeEnum.Area,
|
|
203
|
+
ChartTypeEnum.AreaPercent,
|
|
204
|
+
ChartTypeEnum.DualAxis,
|
|
205
|
+
ChartTypeEnum.Scatter,
|
|
206
|
+
ChartTypeEnum.Rose,
|
|
207
|
+
ChartTypeEnum.RoseParallel,
|
|
208
|
+
ChartTypeEnum.Pie,
|
|
209
|
+
ChartTypeEnum.Donut,
|
|
210
|
+
ChartTypeEnum.Radar,
|
|
211
|
+
ChartTypeEnum.Funnel,
|
|
212
|
+
ChartTypeEnum.Heatmap,
|
|
213
|
+
ChartTypeEnum.Boxplot,
|
|
214
|
+
ChartTypeEnum.Histogram
|
|
215
|
+
];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
170
218
|
const id_id = {
|
|
171
219
|
uuid: ()=>v4()
|
|
172
220
|
};
|
|
173
|
-
|
|
221
|
+
function isVBIFilter(clause) {
|
|
222
|
+
return 'field' in clause;
|
|
223
|
+
}
|
|
224
|
+
function isVBIWhereGroup(clause) {
|
|
225
|
+
return 'conditions' in clause;
|
|
226
|
+
}
|
|
227
|
+
function isVBIHavingFilter(clause) {
|
|
228
|
+
return 'field' in clause;
|
|
229
|
+
}
|
|
230
|
+
function isVBIHavingGroup(clause) {
|
|
231
|
+
return 'conditions' in clause;
|
|
232
|
+
}
|
|
233
|
+
function createWhereGroup(op = 'and', groupId = 'root') {
|
|
234
|
+
const yMap = new external_yjs_Map();
|
|
235
|
+
yMap.set('id', groupId);
|
|
236
|
+
yMap.set('op', op);
|
|
237
|
+
yMap.set('conditions', new external_yjs_Array());
|
|
238
|
+
return yMap;
|
|
239
|
+
}
|
|
240
|
+
function isWhereGroup(yMap) {
|
|
241
|
+
return void 0 !== yMap.get('op') && void 0 !== yMap.get('conditions');
|
|
242
|
+
}
|
|
243
|
+
function findEntry(collection, entryId) {
|
|
244
|
+
const items = collection.toArray();
|
|
245
|
+
for(let index = 0; index < items.length; index++){
|
|
246
|
+
const item = items[index];
|
|
247
|
+
if (item.get('id') === entryId) return {
|
|
248
|
+
collection,
|
|
249
|
+
index,
|
|
250
|
+
item
|
|
251
|
+
};
|
|
252
|
+
if (isWhereGroup(item)) {
|
|
253
|
+
const nestedCollection = item.get('conditions');
|
|
254
|
+
const nestedMatch = findEntry(nestedCollection, entryId);
|
|
255
|
+
if (nestedMatch) return nestedMatch;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
class WhereFilterNodeBuilder {
|
|
174
260
|
yMap;
|
|
175
261
|
constructor(yMap){
|
|
176
262
|
this.yMap = yMap;
|
|
@@ -181,26 +267,33 @@ class HavingFiltersNodeBuilder {
|
|
|
181
267
|
getField() {
|
|
182
268
|
return this.yMap.get('field');
|
|
183
269
|
}
|
|
270
|
+
setField(field) {
|
|
271
|
+
this.yMap.set('field', field);
|
|
272
|
+
return this;
|
|
273
|
+
}
|
|
184
274
|
getOperator() {
|
|
185
275
|
return this.yMap.get('op');
|
|
186
276
|
}
|
|
187
|
-
setValue(value) {
|
|
188
|
-
this.yMap.set('value', value);
|
|
189
|
-
return this;
|
|
190
|
-
}
|
|
191
277
|
setOperator(operator) {
|
|
192
278
|
this.yMap.set('op', operator);
|
|
193
279
|
return this;
|
|
194
280
|
}
|
|
195
|
-
|
|
281
|
+
setValue(value) {
|
|
282
|
+
this.yMap.set('value', value);
|
|
283
|
+
return this;
|
|
284
|
+
}
|
|
285
|
+
toJSON() {
|
|
196
286
|
return this.yMap.toJSON();
|
|
197
287
|
}
|
|
198
288
|
}
|
|
199
|
-
class
|
|
289
|
+
class WhereGroupBuilder {
|
|
200
290
|
yMap;
|
|
201
291
|
constructor(yMap){
|
|
202
292
|
this.yMap = yMap;
|
|
203
293
|
}
|
|
294
|
+
getConditions() {
|
|
295
|
+
return this.yMap.get('conditions');
|
|
296
|
+
}
|
|
204
297
|
getId() {
|
|
205
298
|
return this.yMap.get('id');
|
|
206
299
|
}
|
|
@@ -215,29 +308,24 @@ class HavingGroupBuilder {
|
|
|
215
308
|
const yMap = new external_yjs_Map();
|
|
216
309
|
yMap.set('id', id_id.uuid());
|
|
217
310
|
yMap.set('field', field);
|
|
218
|
-
|
|
219
|
-
conditions.push([
|
|
311
|
+
this.getConditions().push([
|
|
220
312
|
yMap
|
|
221
313
|
]);
|
|
222
|
-
const node = new
|
|
314
|
+
const node = new WhereFilterNodeBuilder(yMap);
|
|
223
315
|
callback(node);
|
|
224
316
|
return this;
|
|
225
317
|
}
|
|
226
318
|
addGroup(op, callback) {
|
|
227
|
-
const yMap =
|
|
228
|
-
|
|
229
|
-
yMap.set('op', op);
|
|
230
|
-
yMap.set('conditions', new external_yjs_Array());
|
|
231
|
-
const conditions = this.yMap.get('conditions');
|
|
232
|
-
conditions.push([
|
|
319
|
+
const yMap = createWhereGroup(op, id_id.uuid());
|
|
320
|
+
this.getConditions().push([
|
|
233
321
|
yMap
|
|
234
322
|
]);
|
|
235
|
-
const group = new
|
|
323
|
+
const group = new WhereGroupBuilder(yMap);
|
|
236
324
|
callback(group);
|
|
237
325
|
return this;
|
|
238
326
|
}
|
|
239
327
|
remove(idOrIndex) {
|
|
240
|
-
const conditions = this.
|
|
328
|
+
const conditions = this.getConditions();
|
|
241
329
|
if ('number' == typeof idOrIndex) {
|
|
242
330
|
if (idOrIndex >= 0 && idOrIndex < conditions.length) conditions.delete(idOrIndex, 1);
|
|
243
331
|
} else {
|
|
@@ -247,154 +335,138 @@ class HavingGroupBuilder {
|
|
|
247
335
|
return this;
|
|
248
336
|
}
|
|
249
337
|
clear() {
|
|
250
|
-
const conditions = this.
|
|
338
|
+
const conditions = this.getConditions();
|
|
251
339
|
conditions.delete(0, conditions.length);
|
|
252
340
|
return this;
|
|
253
341
|
}
|
|
254
|
-
|
|
342
|
+
toJSON() {
|
|
255
343
|
return this.yMap.toJSON();
|
|
256
344
|
}
|
|
257
345
|
}
|
|
258
|
-
class
|
|
259
|
-
|
|
260
|
-
doc;
|
|
346
|
+
class WhereFilterBuilder {
|
|
347
|
+
whereFilter;
|
|
261
348
|
constructor(doc, dsl){
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
349
|
+
doc.transact(()=>{
|
|
350
|
+
const existingWhereFilter = dsl.get('whereFilter');
|
|
351
|
+
if (existingWhereFilter instanceof external_yjs_Map) this.whereFilter = existingWhereFilter;
|
|
352
|
+
else {
|
|
353
|
+
this.whereFilter = createWhereGroup();
|
|
354
|
+
dsl.set('whereFilter', this.whereFilter);
|
|
355
|
+
}
|
|
356
|
+
if (!(this.whereFilter.get('conditions') instanceof external_yjs_Array)) this.whereFilter.set('conditions', new external_yjs_Array());
|
|
357
|
+
if (!this.whereFilter.get('id')) this.whereFilter.set('id', 'root');
|
|
358
|
+
if (!this.whereFilter.get('op')) this.whereFilter.set('op', 'and');
|
|
266
359
|
});
|
|
267
360
|
}
|
|
361
|
+
getConditions() {
|
|
362
|
+
return this.whereFilter.get('conditions');
|
|
363
|
+
}
|
|
268
364
|
add(field, callback) {
|
|
269
365
|
const yMap = new external_yjs_Map();
|
|
270
366
|
yMap.set('id', id_id.uuid());
|
|
271
367
|
yMap.set('field', field);
|
|
272
|
-
this.
|
|
368
|
+
this.getConditions().push([
|
|
273
369
|
yMap
|
|
274
370
|
]);
|
|
275
|
-
const node = new
|
|
371
|
+
const node = new WhereFilterNodeBuilder(yMap);
|
|
276
372
|
callback(node);
|
|
277
373
|
return this;
|
|
278
374
|
}
|
|
279
375
|
addGroup(op, callback) {
|
|
280
|
-
const yMap =
|
|
281
|
-
|
|
282
|
-
yMap.set('op', op);
|
|
283
|
-
yMap.set('conditions', new external_yjs_Array());
|
|
284
|
-
this.dsl.get('havingFilters').push([
|
|
376
|
+
const yMap = createWhereGroup(op, id_id.uuid());
|
|
377
|
+
this.getConditions().push([
|
|
285
378
|
yMap
|
|
286
379
|
]);
|
|
287
|
-
const group = new
|
|
380
|
+
const group = new WhereGroupBuilder(yMap);
|
|
288
381
|
callback(group);
|
|
289
382
|
return this;
|
|
290
383
|
}
|
|
291
384
|
update(id, callback) {
|
|
292
|
-
const
|
|
293
|
-
const
|
|
294
|
-
if (
|
|
295
|
-
|
|
296
|
-
const
|
|
385
|
+
const conditions = this.getConditions();
|
|
386
|
+
const match = findEntry(conditions, id);
|
|
387
|
+
if (!match) throw new Error(`Where filter with id ${id} not found`);
|
|
388
|
+
if (!WhereFilterBuilder.isNode(match.item)) throw new Error(`Item with id ${id} is not a filter`);
|
|
389
|
+
const filterYMap = match.item;
|
|
390
|
+
const node = new WhereFilterNodeBuilder(filterYMap);
|
|
297
391
|
callback(node);
|
|
298
392
|
return this;
|
|
299
393
|
}
|
|
300
394
|
updateGroup(id, callback) {
|
|
301
|
-
const
|
|
302
|
-
const
|
|
303
|
-
if (
|
|
304
|
-
const yMap =
|
|
305
|
-
if (!
|
|
306
|
-
const group = new
|
|
395
|
+
const conditions = this.getConditions();
|
|
396
|
+
const match = findEntry(conditions, id);
|
|
397
|
+
if (!match) throw new Error(`Where group with id ${id} not found`);
|
|
398
|
+
const yMap = match.item;
|
|
399
|
+
if (!WhereFilterBuilder.isGroup(yMap)) throw new Error(`Item with id ${id} is not a group`);
|
|
400
|
+
const group = new WhereGroupBuilder(yMap);
|
|
307
401
|
callback(group);
|
|
308
402
|
return this;
|
|
309
403
|
}
|
|
310
404
|
remove(idOrIndex) {
|
|
311
|
-
const
|
|
405
|
+
const conditions = this.getConditions();
|
|
312
406
|
if ('number' == typeof idOrIndex) {
|
|
313
|
-
if (idOrIndex >= 0 && idOrIndex <
|
|
407
|
+
if (idOrIndex >= 0 && idOrIndex < conditions.length) conditions.delete(idOrIndex, 1);
|
|
314
408
|
} else {
|
|
315
|
-
const
|
|
316
|
-
if (
|
|
409
|
+
const match = findEntry(conditions, idOrIndex);
|
|
410
|
+
if (match) match.collection.delete(match.index, 1);
|
|
317
411
|
}
|
|
318
412
|
return this;
|
|
319
413
|
}
|
|
320
414
|
find(id) {
|
|
321
|
-
const
|
|
322
|
-
const
|
|
415
|
+
const conditions = this.getConditions();
|
|
416
|
+
const match = findEntry(conditions, id);
|
|
417
|
+
const yMap = match?.item;
|
|
323
418
|
if (!yMap) return;
|
|
324
|
-
if (
|
|
325
|
-
return new
|
|
419
|
+
if (WhereFilterBuilder.isGroup(yMap)) return new WhereGroupBuilder(yMap);
|
|
420
|
+
return new WhereFilterNodeBuilder(yMap);
|
|
326
421
|
}
|
|
327
422
|
clear() {
|
|
328
|
-
const
|
|
329
|
-
|
|
423
|
+
const conditions = this.getConditions();
|
|
424
|
+
conditions.delete(0, conditions.length);
|
|
330
425
|
return this;
|
|
331
426
|
}
|
|
332
|
-
|
|
333
|
-
return this.
|
|
427
|
+
toJSON() {
|
|
428
|
+
return this.whereFilter.toJSON();
|
|
334
429
|
}
|
|
335
430
|
observe(callback) {
|
|
336
|
-
this.
|
|
431
|
+
this.whereFilter.observeDeep(callback);
|
|
337
432
|
return ()=>{
|
|
338
|
-
this.
|
|
433
|
+
this.whereFilter.unobserveDeep(callback);
|
|
339
434
|
};
|
|
340
435
|
}
|
|
341
436
|
static isGroup(yMap) {
|
|
342
|
-
return
|
|
437
|
+
return isWhereGroup(yMap);
|
|
343
438
|
}
|
|
344
439
|
static isNode(yMap) {
|
|
345
440
|
return void 0 !== yMap.get('field');
|
|
346
441
|
}
|
|
347
442
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
443
|
+
function createHavingGroup(op = 'and', groupId = 'root') {
|
|
444
|
+
const yMap = new external_yjs_Map();
|
|
445
|
+
yMap.set('id', groupId);
|
|
446
|
+
yMap.set('op', op);
|
|
447
|
+
yMap.set('conditions', new external_yjs_Array());
|
|
448
|
+
return yMap;
|
|
449
|
+
}
|
|
450
|
+
function isHavingGroup(yMap) {
|
|
451
|
+
return void 0 !== yMap.get('op') && void 0 !== yMap.get('conditions');
|
|
452
|
+
}
|
|
453
|
+
function having_utils_findEntry(collection, entryId) {
|
|
454
|
+
const items = collection.toArray();
|
|
455
|
+
for(let index = 0; index < items.length; index++){
|
|
456
|
+
const item = items[index];
|
|
457
|
+
if (item.get('id') === entryId) return {
|
|
458
|
+
collection,
|
|
459
|
+
index,
|
|
460
|
+
item
|
|
360
461
|
};
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
return this.dsl.get('chartType') || 'table';
|
|
367
|
-
}
|
|
368
|
-
toJson() {
|
|
369
|
-
return this.dsl.get('chartType') || 'table';
|
|
370
|
-
}
|
|
371
|
-
getAvailableChartTypes() {
|
|
372
|
-
return [
|
|
373
|
-
ChartTypeEnum.Table,
|
|
374
|
-
ChartTypeEnum.PivotTable,
|
|
375
|
-
ChartTypeEnum.Line,
|
|
376
|
-
ChartTypeEnum.Column,
|
|
377
|
-
ChartTypeEnum.ColumnPercent,
|
|
378
|
-
ChartTypeEnum.ColumnParallel,
|
|
379
|
-
ChartTypeEnum.BarPercent,
|
|
380
|
-
ChartTypeEnum.BarParallel,
|
|
381
|
-
ChartTypeEnum.Area,
|
|
382
|
-
ChartTypeEnum.AreaPercent,
|
|
383
|
-
ChartTypeEnum.DualAxis,
|
|
384
|
-
ChartTypeEnum.Scatter,
|
|
385
|
-
ChartTypeEnum.Rose,
|
|
386
|
-
ChartTypeEnum.RoseParallel,
|
|
387
|
-
ChartTypeEnum.Pie,
|
|
388
|
-
ChartTypeEnum.Donut,
|
|
389
|
-
ChartTypeEnum.Radar,
|
|
390
|
-
ChartTypeEnum.Funnel,
|
|
391
|
-
ChartTypeEnum.Heatmap,
|
|
392
|
-
ChartTypeEnum.Boxplot,
|
|
393
|
-
ChartTypeEnum.Histogram
|
|
394
|
-
];
|
|
462
|
+
if (isHavingGroup(item)) {
|
|
463
|
+
const nestedCollection = item.get('conditions');
|
|
464
|
+
const nestedMatch = having_utils_findEntry(nestedCollection, entryId);
|
|
465
|
+
if (nestedMatch) return nestedMatch;
|
|
466
|
+
}
|
|
395
467
|
}
|
|
396
468
|
}
|
|
397
|
-
class
|
|
469
|
+
class HavingFilterNodeBuilder {
|
|
398
470
|
yMap;
|
|
399
471
|
constructor(yMap){
|
|
400
472
|
this.yMap = yMap;
|
|
@@ -408,23 +480,26 @@ class WhereFilterNodeBuilder {
|
|
|
408
480
|
getOperator() {
|
|
409
481
|
return this.yMap.get('op');
|
|
410
482
|
}
|
|
411
|
-
setOperator(operator) {
|
|
412
|
-
this.yMap.set('op', operator);
|
|
413
|
-
return this;
|
|
414
|
-
}
|
|
415
483
|
setValue(value) {
|
|
416
484
|
this.yMap.set('value', value);
|
|
417
485
|
return this;
|
|
418
486
|
}
|
|
419
|
-
|
|
487
|
+
setOperator(operator) {
|
|
488
|
+
this.yMap.set('op', operator);
|
|
489
|
+
return this;
|
|
490
|
+
}
|
|
491
|
+
toJSON() {
|
|
420
492
|
return this.yMap.toJSON();
|
|
421
493
|
}
|
|
422
494
|
}
|
|
423
|
-
class
|
|
495
|
+
class HavingGroupBuilder {
|
|
424
496
|
yMap;
|
|
425
497
|
constructor(yMap){
|
|
426
498
|
this.yMap = yMap;
|
|
427
499
|
}
|
|
500
|
+
getConditions() {
|
|
501
|
+
return this.yMap.get('conditions');
|
|
502
|
+
}
|
|
428
503
|
getId() {
|
|
429
504
|
return this.yMap.get('id');
|
|
430
505
|
}
|
|
@@ -439,29 +514,24 @@ class WhereGroupBuilder {
|
|
|
439
514
|
const yMap = new external_yjs_Map();
|
|
440
515
|
yMap.set('id', id_id.uuid());
|
|
441
516
|
yMap.set('field', field);
|
|
442
|
-
|
|
443
|
-
conditions.push([
|
|
517
|
+
this.getConditions().push([
|
|
444
518
|
yMap
|
|
445
519
|
]);
|
|
446
|
-
const node = new
|
|
520
|
+
const node = new HavingFilterNodeBuilder(yMap);
|
|
447
521
|
callback(node);
|
|
448
522
|
return this;
|
|
449
523
|
}
|
|
450
524
|
addGroup(op, callback) {
|
|
451
|
-
const yMap =
|
|
452
|
-
|
|
453
|
-
yMap.set('op', op);
|
|
454
|
-
yMap.set('conditions', new external_yjs_Array());
|
|
455
|
-
const conditions = this.yMap.get('conditions');
|
|
456
|
-
conditions.push([
|
|
525
|
+
const yMap = createHavingGroup(op, id_id.uuid());
|
|
526
|
+
this.getConditions().push([
|
|
457
527
|
yMap
|
|
458
528
|
]);
|
|
459
|
-
const group = new
|
|
529
|
+
const group = new HavingGroupBuilder(yMap);
|
|
460
530
|
callback(group);
|
|
461
531
|
return this;
|
|
462
532
|
}
|
|
463
533
|
remove(idOrIndex) {
|
|
464
|
-
const conditions = this.
|
|
534
|
+
const conditions = this.getConditions();
|
|
465
535
|
if ('number' == typeof idOrIndex) {
|
|
466
536
|
if (idOrIndex >= 0 && idOrIndex < conditions.length) conditions.delete(idOrIndex, 1);
|
|
467
537
|
} else {
|
|
@@ -471,104 +541,183 @@ class WhereGroupBuilder {
|
|
|
471
541
|
return this;
|
|
472
542
|
}
|
|
473
543
|
clear() {
|
|
474
|
-
const conditions = this.
|
|
544
|
+
const conditions = this.getConditions();
|
|
475
545
|
conditions.delete(0, conditions.length);
|
|
476
546
|
return this;
|
|
477
547
|
}
|
|
478
|
-
|
|
548
|
+
toJSON() {
|
|
479
549
|
return this.yMap.toJSON();
|
|
480
550
|
}
|
|
481
551
|
}
|
|
482
|
-
class
|
|
483
|
-
|
|
484
|
-
doc;
|
|
552
|
+
class HavingFilterBuilder {
|
|
553
|
+
havingFilter;
|
|
485
554
|
constructor(doc, dsl){
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
555
|
+
doc.transact(()=>{
|
|
556
|
+
const existingHavingFilter = dsl.get('havingFilter');
|
|
557
|
+
if (existingHavingFilter instanceof external_yjs_Map) this.havingFilter = existingHavingFilter;
|
|
558
|
+
else {
|
|
559
|
+
this.havingFilter = createHavingGroup();
|
|
560
|
+
dsl.set('havingFilter', this.havingFilter);
|
|
561
|
+
}
|
|
562
|
+
if (!(this.havingFilter.get('conditions') instanceof external_yjs_Array)) this.havingFilter.set('conditions', new external_yjs_Array());
|
|
563
|
+
if (!this.havingFilter.get('id')) this.havingFilter.set('id', 'root');
|
|
564
|
+
if (!this.havingFilter.get('op')) this.havingFilter.set('op', 'and');
|
|
490
565
|
});
|
|
491
566
|
}
|
|
567
|
+
getConditions() {
|
|
568
|
+
return this.havingFilter.get('conditions');
|
|
569
|
+
}
|
|
492
570
|
add(field, callback) {
|
|
493
571
|
const yMap = new external_yjs_Map();
|
|
494
572
|
yMap.set('id', id_id.uuid());
|
|
495
573
|
yMap.set('field', field);
|
|
496
|
-
this.
|
|
574
|
+
this.getConditions().push([
|
|
497
575
|
yMap
|
|
498
576
|
]);
|
|
499
|
-
const node = new
|
|
577
|
+
const node = new HavingFilterNodeBuilder(yMap);
|
|
500
578
|
callback(node);
|
|
501
579
|
return this;
|
|
502
580
|
}
|
|
503
581
|
addGroup(op, callback) {
|
|
504
|
-
const yMap =
|
|
505
|
-
|
|
506
|
-
yMap.set('op', op);
|
|
507
|
-
yMap.set('conditions', new external_yjs_Array());
|
|
508
|
-
this.dsl.get('whereFilters').push([
|
|
582
|
+
const yMap = createHavingGroup(op, id_id.uuid());
|
|
583
|
+
this.getConditions().push([
|
|
509
584
|
yMap
|
|
510
585
|
]);
|
|
511
|
-
const group = new
|
|
586
|
+
const group = new HavingGroupBuilder(yMap);
|
|
512
587
|
callback(group);
|
|
513
588
|
return this;
|
|
514
589
|
}
|
|
515
590
|
update(id, callback) {
|
|
516
|
-
const
|
|
517
|
-
const
|
|
518
|
-
if (
|
|
519
|
-
|
|
520
|
-
const
|
|
591
|
+
const conditions = this.getConditions();
|
|
592
|
+
const match = having_utils_findEntry(conditions, id);
|
|
593
|
+
if (!match) throw new Error(`Having filter with id ${id} not found`);
|
|
594
|
+
if (!HavingFilterBuilder.isNode(match.item)) throw new Error(`Item with id ${id} is not a filter`);
|
|
595
|
+
const filterYMap = match.item;
|
|
596
|
+
const node = new HavingFilterNodeBuilder(filterYMap);
|
|
521
597
|
callback(node);
|
|
522
598
|
return this;
|
|
523
599
|
}
|
|
524
600
|
updateGroup(id, callback) {
|
|
525
|
-
const
|
|
526
|
-
const
|
|
527
|
-
if (
|
|
528
|
-
const yMap =
|
|
529
|
-
if (!
|
|
530
|
-
const group = new
|
|
601
|
+
const conditions = this.getConditions();
|
|
602
|
+
const match = having_utils_findEntry(conditions, id);
|
|
603
|
+
if (!match) throw new Error(`Having group with id ${id} not found`);
|
|
604
|
+
const yMap = match.item;
|
|
605
|
+
if (!HavingFilterBuilder.isGroup(yMap)) throw new Error(`Item with id ${id} is not a group`);
|
|
606
|
+
const group = new HavingGroupBuilder(yMap);
|
|
531
607
|
callback(group);
|
|
532
608
|
return this;
|
|
533
609
|
}
|
|
534
610
|
remove(idOrIndex) {
|
|
535
|
-
const
|
|
611
|
+
const conditions = this.getConditions();
|
|
536
612
|
if ('number' == typeof idOrIndex) {
|
|
537
|
-
if (idOrIndex >= 0 && idOrIndex <
|
|
613
|
+
if (idOrIndex >= 0 && idOrIndex < conditions.length) conditions.delete(idOrIndex, 1);
|
|
538
614
|
} else {
|
|
539
|
-
const
|
|
540
|
-
if (
|
|
615
|
+
const match = having_utils_findEntry(conditions, idOrIndex);
|
|
616
|
+
if (match) match.collection.delete(match.index, 1);
|
|
541
617
|
}
|
|
542
618
|
return this;
|
|
543
619
|
}
|
|
544
620
|
find(id) {
|
|
545
|
-
const
|
|
546
|
-
const
|
|
621
|
+
const conditions = this.getConditions();
|
|
622
|
+
const match = having_utils_findEntry(conditions, id);
|
|
623
|
+
const yMap = match?.item;
|
|
547
624
|
if (!yMap) return;
|
|
548
|
-
if (
|
|
549
|
-
return new
|
|
625
|
+
if (HavingFilterBuilder.isGroup(yMap)) return new HavingGroupBuilder(yMap);
|
|
626
|
+
return new HavingFilterNodeBuilder(yMap);
|
|
550
627
|
}
|
|
551
628
|
clear() {
|
|
552
|
-
const
|
|
553
|
-
|
|
629
|
+
const conditions = this.getConditions();
|
|
630
|
+
conditions.delete(0, conditions.length);
|
|
554
631
|
return this;
|
|
555
632
|
}
|
|
556
|
-
|
|
557
|
-
return this.
|
|
633
|
+
toJSON() {
|
|
634
|
+
return this.havingFilter.toJSON();
|
|
558
635
|
}
|
|
559
636
|
observe(callback) {
|
|
560
|
-
this.
|
|
637
|
+
this.havingFilter.observeDeep(callback);
|
|
561
638
|
return ()=>{
|
|
562
|
-
this.
|
|
639
|
+
this.havingFilter.unobserveDeep(callback);
|
|
563
640
|
};
|
|
564
641
|
}
|
|
565
642
|
static isGroup(yMap) {
|
|
566
|
-
return
|
|
643
|
+
return isHavingGroup(yMap);
|
|
567
644
|
}
|
|
568
645
|
static isNode(yMap) {
|
|
569
646
|
return void 0 !== yMap.get('field');
|
|
570
647
|
}
|
|
571
648
|
}
|
|
649
|
+
class ThemeBuilder {
|
|
650
|
+
dsl;
|
|
651
|
+
constructor(_doc, dsl){
|
|
652
|
+
this.dsl = dsl;
|
|
653
|
+
}
|
|
654
|
+
observe(callback) {
|
|
655
|
+
const wrapper = (e, trans)=>{
|
|
656
|
+
if (e.keysChanged.has('theme')) callback(e, trans);
|
|
657
|
+
};
|
|
658
|
+
this.dsl.observe(wrapper);
|
|
659
|
+
return ()=>{
|
|
660
|
+
this.dsl.unobserve(wrapper);
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
setTheme(theme) {
|
|
664
|
+
this.dsl.set('theme', theme);
|
|
665
|
+
}
|
|
666
|
+
getTheme() {
|
|
667
|
+
return this.dsl.get('theme') || 'light';
|
|
668
|
+
}
|
|
669
|
+
toJSON() {
|
|
670
|
+
return this.getTheme();
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
class LocaleBuilder {
|
|
674
|
+
dsl;
|
|
675
|
+
constructor(_doc, dsl){
|
|
676
|
+
this.dsl = dsl;
|
|
677
|
+
}
|
|
678
|
+
observe(callback) {
|
|
679
|
+
const wrapper = (e, trans)=>{
|
|
680
|
+
if (e.keysChanged.has('locale')) callback(e, trans);
|
|
681
|
+
};
|
|
682
|
+
this.dsl.observe(wrapper);
|
|
683
|
+
return ()=>{
|
|
684
|
+
this.dsl.unobserve(wrapper);
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
setLocale(locale) {
|
|
688
|
+
this.dsl.set('locale', locale);
|
|
689
|
+
}
|
|
690
|
+
getLocale() {
|
|
691
|
+
return this.dsl.get('locale') || 'zh-CN';
|
|
692
|
+
}
|
|
693
|
+
toJSON() {
|
|
694
|
+
return this.getLocale();
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
class LimitBuilder {
|
|
698
|
+
dsl;
|
|
699
|
+
constructor(_doc, dsl){
|
|
700
|
+
this.dsl = dsl;
|
|
701
|
+
}
|
|
702
|
+
observe(callback) {
|
|
703
|
+
const wrapper = (e, trans)=>{
|
|
704
|
+
if (e.keysChanged.has('limit')) callback(e, trans);
|
|
705
|
+
};
|
|
706
|
+
this.dsl.observe(wrapper);
|
|
707
|
+
return ()=>{
|
|
708
|
+
this.dsl.unobserve(wrapper);
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
setLimit(limit) {
|
|
712
|
+
this.dsl.set('limit', limit);
|
|
713
|
+
}
|
|
714
|
+
getLimit() {
|
|
715
|
+
return this.dsl.get('limit');
|
|
716
|
+
}
|
|
717
|
+
toJSON() {
|
|
718
|
+
return this.getLimit();
|
|
719
|
+
}
|
|
720
|
+
}
|
|
572
721
|
class undo_manager_UndoManager {
|
|
573
722
|
manager;
|
|
574
723
|
constructor(scope){
|
|
@@ -623,22 +772,19 @@ const buildGroupBy = (queryDSL, context)=>{
|
|
|
623
772
|
};
|
|
624
773
|
const buildWhere = (queryDSL, context)=>{
|
|
625
774
|
const { vbiDSL } = context;
|
|
626
|
-
const
|
|
627
|
-
if (0 ===
|
|
775
|
+
const whereFilter = vbiDSL.whereFilter;
|
|
776
|
+
if (!whereFilter || 0 === whereFilter.conditions.length) return queryDSL;
|
|
628
777
|
const result = {
|
|
629
778
|
...queryDSL
|
|
630
779
|
};
|
|
631
|
-
result.where =
|
|
632
|
-
op: 'and',
|
|
633
|
-
conditions: whereFilters.flatMap(mapClauseToCondition)
|
|
634
|
-
};
|
|
780
|
+
result.where = mapGroupToCondition(whereFilter);
|
|
635
781
|
return result;
|
|
636
782
|
};
|
|
637
|
-
function
|
|
783
|
+
function buildWhere_isWhereGroup(clause) {
|
|
638
784
|
return 'op' in clause && 'conditions' in clause;
|
|
639
785
|
}
|
|
640
786
|
function mapClauseToCondition(clause) {
|
|
641
|
-
if (
|
|
787
|
+
if (buildWhere_isWhereGroup(clause)) return [
|
|
642
788
|
mapGroupToCondition(clause)
|
|
643
789
|
];
|
|
644
790
|
return mapFilterToCondition(clause);
|
|
@@ -650,23 +796,62 @@ function mapGroupToCondition(group) {
|
|
|
650
796
|
};
|
|
651
797
|
}
|
|
652
798
|
function mapFilterToCondition(filter) {
|
|
653
|
-
if ('between' === filter.op) return handleBetweenFilter(filter);
|
|
799
|
+
if ('between' === filter.op || 'not between' === filter.op) return handleBetweenFilter(filter);
|
|
654
800
|
return handleSimpleFilter(filter);
|
|
655
801
|
}
|
|
656
802
|
function handleBetweenFilter(filter) {
|
|
657
|
-
const
|
|
658
|
-
const
|
|
659
|
-
if (void 0 !== value.min && null !== value.min && '' !== value.min) conditions.push({
|
|
803
|
+
const value = normalizeBetweenValue(filter.value);
|
|
804
|
+
const lowerCondition = void 0 !== value.min && null !== value.min && '' !== value.min ? {
|
|
660
805
|
field: filter.field,
|
|
661
806
|
op: '<' === value.leftOp ? '>' : '>=',
|
|
662
807
|
value: value.min
|
|
663
|
-
}
|
|
664
|
-
|
|
808
|
+
} : void 0;
|
|
809
|
+
const upperCondition = void 0 !== value.max && null !== value.max && '' !== value.max ? {
|
|
665
810
|
field: filter.field,
|
|
666
811
|
op: '<' === value.rightOp ? '<' : '<=',
|
|
667
812
|
value: value.max
|
|
668
|
-
}
|
|
669
|
-
|
|
813
|
+
} : void 0;
|
|
814
|
+
if ('not between' === filter.op) {
|
|
815
|
+
const outsideConditions = [
|
|
816
|
+
lowerCondition && invertLowerBound(lowerCondition),
|
|
817
|
+
upperCondition && invertUpperBound(upperCondition)
|
|
818
|
+
].filter(Boolean);
|
|
819
|
+
if (outsideConditions.length <= 1) return outsideConditions;
|
|
820
|
+
return [
|
|
821
|
+
{
|
|
822
|
+
op: 'or',
|
|
823
|
+
conditions: outsideConditions
|
|
824
|
+
}
|
|
825
|
+
];
|
|
826
|
+
}
|
|
827
|
+
return [
|
|
828
|
+
lowerCondition,
|
|
829
|
+
upperCondition
|
|
830
|
+
].filter(Boolean);
|
|
831
|
+
}
|
|
832
|
+
function normalizeBetweenValue(value) {
|
|
833
|
+
if (Array.isArray(value)) return {
|
|
834
|
+
min: value[0],
|
|
835
|
+
max: value[1],
|
|
836
|
+
leftOp: '<=',
|
|
837
|
+
rightOp: '<='
|
|
838
|
+
};
|
|
839
|
+
if ('object' == typeof value && null !== value) return value;
|
|
840
|
+
return {};
|
|
841
|
+
}
|
|
842
|
+
function invertLowerBound(condition) {
|
|
843
|
+
return {
|
|
844
|
+
field: condition.field,
|
|
845
|
+
op: '>' === condition.op ? '<=' : '<',
|
|
846
|
+
value: condition.value
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
function invertUpperBound(condition) {
|
|
850
|
+
return {
|
|
851
|
+
field: condition.field,
|
|
852
|
+
op: '<' === condition.op ? '>=' : '>',
|
|
853
|
+
value: condition.value
|
|
854
|
+
};
|
|
670
855
|
}
|
|
671
856
|
function handleSimpleFilter(filter) {
|
|
672
857
|
let mappedOp = filter.op ?? '=';
|
|
@@ -685,22 +870,22 @@ function handleSimpleFilter(filter) {
|
|
|
685
870
|
}
|
|
686
871
|
const buildHaving = (queryDSL, context)=>{
|
|
687
872
|
const { vbiDSL } = context;
|
|
688
|
-
const
|
|
689
|
-
if (0 ===
|
|
873
|
+
const havingFilter = vbiDSL.havingFilter;
|
|
874
|
+
if (!havingFilter || 0 === havingFilter.conditions.length) return queryDSL;
|
|
690
875
|
const result = {
|
|
691
876
|
...queryDSL
|
|
692
877
|
};
|
|
693
878
|
result.having = {
|
|
694
|
-
op:
|
|
695
|
-
conditions:
|
|
879
|
+
op: havingFilter.op,
|
|
880
|
+
conditions: havingFilter.conditions.flatMap(buildHaving_mapClauseToCondition)
|
|
696
881
|
};
|
|
697
882
|
return result;
|
|
698
883
|
};
|
|
699
|
-
function
|
|
884
|
+
function buildHaving_isHavingGroup(clause) {
|
|
700
885
|
return 'op' in clause && 'conditions' in clause;
|
|
701
886
|
}
|
|
702
887
|
function buildHaving_mapClauseToCondition(clause) {
|
|
703
|
-
if (
|
|
888
|
+
if (buildHaving_isHavingGroup(clause)) return [
|
|
704
889
|
buildHaving_mapGroupToCondition(clause)
|
|
705
890
|
];
|
|
706
891
|
return buildHaving_mapFilterToCondition(clause);
|
|
@@ -753,8 +938,11 @@ class VBIBuilder {
|
|
|
753
938
|
chartType;
|
|
754
939
|
measures;
|
|
755
940
|
dimensions;
|
|
756
|
-
|
|
757
|
-
|
|
941
|
+
havingFilter;
|
|
942
|
+
whereFilter;
|
|
943
|
+
theme;
|
|
944
|
+
locale;
|
|
945
|
+
limit;
|
|
758
946
|
constructor(doc){
|
|
759
947
|
this.doc = doc;
|
|
760
948
|
this.dsl = doc.getMap('dsl');
|
|
@@ -762,8 +950,11 @@ class VBIBuilder {
|
|
|
762
950
|
this.chartType = new ChartTypeBuilder(doc, this.dsl);
|
|
763
951
|
this.measures = new MeasuresBuilder(doc, this.dsl);
|
|
764
952
|
this.dimensions = new DimensionsBuilder(doc, this.dsl);
|
|
765
|
-
this.
|
|
766
|
-
this.
|
|
953
|
+
this.havingFilter = new HavingFilterBuilder(doc, this.dsl);
|
|
954
|
+
this.whereFilter = new WhereFilterBuilder(doc, this.dsl);
|
|
955
|
+
this.theme = new ThemeBuilder(doc, this.dsl);
|
|
956
|
+
this.locale = new LocaleBuilder(doc, this.dsl);
|
|
957
|
+
this.limit = new LimitBuilder(doc, this.dsl);
|
|
767
958
|
}
|
|
768
959
|
applyUpdate(update) {
|
|
769
960
|
applyUpdate(this.doc, update);
|
|
@@ -800,18 +991,6 @@ class VBIBuilder {
|
|
|
800
991
|
const result = await con.discoverSchema();
|
|
801
992
|
return result;
|
|
802
993
|
};
|
|
803
|
-
setLimit(limit) {
|
|
804
|
-
this.dsl.set('limit', limit);
|
|
805
|
-
return this;
|
|
806
|
-
}
|
|
807
|
-
setLocale(locale) {
|
|
808
|
-
this.dsl.set('locale', locale);
|
|
809
|
-
return this;
|
|
810
|
-
}
|
|
811
|
-
setTheme(theme) {
|
|
812
|
-
this.dsl.set('theme', theme);
|
|
813
|
-
return this;
|
|
814
|
-
}
|
|
815
994
|
}
|
|
816
995
|
const createVBI = ()=>({
|
|
817
996
|
connectorMap: connectorMap,
|
|
@@ -822,8 +1001,16 @@ const createVBI = ()=>({
|
|
|
822
1001
|
chartType: 'table',
|
|
823
1002
|
measures: [],
|
|
824
1003
|
dimensions: [],
|
|
825
|
-
|
|
826
|
-
|
|
1004
|
+
whereFilter: {
|
|
1005
|
+
id: 'root',
|
|
1006
|
+
op: 'and',
|
|
1007
|
+
conditions: []
|
|
1008
|
+
},
|
|
1009
|
+
havingFilter: {
|
|
1010
|
+
id: 'root',
|
|
1011
|
+
op: 'and',
|
|
1012
|
+
conditions: []
|
|
1013
|
+
},
|
|
827
1014
|
theme: 'light',
|
|
828
1015
|
locale: 'zh-CN',
|
|
829
1016
|
version: 0
|
|
@@ -837,7 +1024,7 @@ const createVBI = ()=>({
|
|
|
837
1024
|
if (vbi.theme) dsl.set('theme', vbi.theme);
|
|
838
1025
|
if (vbi.limit) dsl.set('limit', vbi.limit);
|
|
839
1026
|
if (vbi.locale) dsl.set('locale', vbi.locale);
|
|
840
|
-
if (vbi.version) dsl.set('version', vbi.version);
|
|
1027
|
+
if (void 0 !== vbi.version) dsl.set('version', vbi.version);
|
|
841
1028
|
const toYMap = (obj, ensureId = false)=>{
|
|
842
1029
|
const yMap = new external_yjs_Map();
|
|
843
1030
|
if (ensureId && !obj.id) yMap.set('id', id_id.uuid());
|
|
@@ -875,8 +1062,38 @@ const createVBI = ()=>({
|
|
|
875
1062
|
});
|
|
876
1063
|
return yArr;
|
|
877
1064
|
};
|
|
878
|
-
|
|
879
|
-
|
|
1065
|
+
const whereFilter = vbi.whereFilter ?? {
|
|
1066
|
+
id: 'root',
|
|
1067
|
+
op: 'and',
|
|
1068
|
+
conditions: []
|
|
1069
|
+
};
|
|
1070
|
+
const whereGroup = whereFilter instanceof external_yjs_Map ? whereFilter : createWhereGroup();
|
|
1071
|
+
if (whereFilter instanceof external_yjs_Map) {
|
|
1072
|
+
if (!(whereGroup.get('conditions') instanceof external_yjs_Array)) whereGroup.set('conditions', new external_yjs_Array());
|
|
1073
|
+
if (!whereGroup.get('id')) whereGroup.set('id', 'root');
|
|
1074
|
+
if (!whereGroup.get('op')) whereGroup.set('op', 'and');
|
|
1075
|
+
} else {
|
|
1076
|
+
whereGroup.set('id', whereFilter.id ?? 'root');
|
|
1077
|
+
whereGroup.set('op', whereFilter.op ?? 'and');
|
|
1078
|
+
whereGroup.set('conditions', ensureYArray(whereFilter.conditions, true));
|
|
1079
|
+
}
|
|
1080
|
+
dsl.set('whereFilter', whereGroup);
|
|
1081
|
+
const havingFilter = vbi.havingFilter ?? {
|
|
1082
|
+
id: 'root',
|
|
1083
|
+
op: 'and',
|
|
1084
|
+
conditions: []
|
|
1085
|
+
};
|
|
1086
|
+
const havingGroup = havingFilter instanceof external_yjs_Map ? havingFilter : createHavingGroup();
|
|
1087
|
+
if (havingFilter instanceof external_yjs_Map) {
|
|
1088
|
+
if (!(havingGroup.get('conditions') instanceof external_yjs_Array)) havingGroup.set('conditions', new external_yjs_Array());
|
|
1089
|
+
if (!havingGroup.get('id')) havingGroup.set('id', 'root');
|
|
1090
|
+
if (!havingGroup.get('op')) havingGroup.set('op', 'and');
|
|
1091
|
+
} else {
|
|
1092
|
+
havingGroup.set('id', havingFilter.id ?? 'root');
|
|
1093
|
+
havingGroup.set('op', havingFilter.op ?? 'and');
|
|
1094
|
+
havingGroup.set('conditions', ensureYArray(havingFilter.conditions, true));
|
|
1095
|
+
}
|
|
1096
|
+
dsl.set('havingFilter', havingGroup);
|
|
880
1097
|
dsl.set('measures', ensureYArray(vbi.measures));
|
|
881
1098
|
dsl.set('dimensions', ensureYArray(vbi.dimensions));
|
|
882
1099
|
});
|
|
@@ -884,52 +1101,4 @@ const createVBI = ()=>({
|
|
|
884
1101
|
}
|
|
885
1102
|
});
|
|
886
1103
|
const VBI = createVBI();
|
|
887
|
-
|
|
888
|
-
id: z.string(),
|
|
889
|
-
field: z.string(),
|
|
890
|
-
op: z.string().optional(),
|
|
891
|
-
value: z.any().optional()
|
|
892
|
-
});
|
|
893
|
-
const zVBIWhereGroup = z.lazy(()=>z.object({
|
|
894
|
-
id: z.string(),
|
|
895
|
-
op: z["enum"]([
|
|
896
|
-
'and',
|
|
897
|
-
'or'
|
|
898
|
-
]),
|
|
899
|
-
conditions: z.array(zVBIWhereClause)
|
|
900
|
-
}));
|
|
901
|
-
const zVBIWhereClause = z.lazy(()=>z.union([
|
|
902
|
-
zVBIFilter,
|
|
903
|
-
zVBIWhereGroup
|
|
904
|
-
]));
|
|
905
|
-
function isVBIFilter(clause) {
|
|
906
|
-
return 'field' in clause;
|
|
907
|
-
}
|
|
908
|
-
function isVBIWhereGroup(clause) {
|
|
909
|
-
return 'conditions' in clause;
|
|
910
|
-
}
|
|
911
|
-
const zVBIHavingFilter = z.object({
|
|
912
|
-
id: z.string(),
|
|
913
|
-
field: z.string(),
|
|
914
|
-
op: z.string().optional(),
|
|
915
|
-
value: z.any().optional()
|
|
916
|
-
});
|
|
917
|
-
const zVBIHavingGroup = z.lazy(()=>z.object({
|
|
918
|
-
id: z.string(),
|
|
919
|
-
op: z["enum"]([
|
|
920
|
-
'and',
|
|
921
|
-
'or'
|
|
922
|
-
]),
|
|
923
|
-
conditions: z.array(zVBIHavingClause)
|
|
924
|
-
}));
|
|
925
|
-
const zVBIHavingClause = z.lazy(()=>z.union([
|
|
926
|
-
zVBIHavingFilter,
|
|
927
|
-
zVBIHavingGroup
|
|
928
|
-
]));
|
|
929
|
-
function isVBIHavingFilter(clause) {
|
|
930
|
-
return 'field' in clause;
|
|
931
|
-
}
|
|
932
|
-
function isVBIHavingGroup(clause) {
|
|
933
|
-
return 'conditions' in clause;
|
|
934
|
-
}
|
|
935
|
-
export { ChartTypeBuilder, DimensionsBuilder, MeasuresBuilder, VBI, VBIBuilder, buildVQuery, findTreeNodesBy, id_id as id, isVBIFilter, isVBIHavingFilter, isVBIHavingGroup, isVBIWhereGroup, preorderTraverse };
|
|
1104
|
+
export { ChartTypeBuilder, DimensionsBuilder, HavingFilterBuilder, LimitBuilder, LocaleBuilder, MeasuresBuilder, ThemeBuilder, undo_manager_UndoManager as UndoManager, VBI, VBIBuilder, WhereFilterBuilder, buildVQuery, findTreeNodesBy, id_id as id, isVBIFilter, isVBIHavingFilter, isVBIHavingGroup, isVBIWhereGroup, preorderTraverse };
|