@nocobase/plugin-data-visualization 0.11.1-alpha.2 → 0.11.1-alpha.4
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/lib/client/block/ChartConfigure.js +20 -37
- package/lib/client/block/schemas/configure.js +30 -5
- package/lib/client/renderer/ChartRenderer.js +1 -3
- package/lib/client/renderer/library/G2PlotLibrary.js +3 -2
- package/lib/locale/tr-TR.d.ts +2 -0
- package/lib/locale/tr-TR.js +8 -0
- package/lib/server/actions/query.js +10 -10
- package/package.json +10 -10
- package/src/client/__tests__/hooks.test.ts +2 -3
- package/src/client/block/ChartConfigure.tsx +76 -101
- package/src/client/block/schemas/configure.ts +61 -31
- package/src/client/renderer/ChartRenderer.tsx +1 -5
- package/src/client/renderer/library/G2PlotLibrary.tsx +2 -1
- package/src/locale/tr-TR.ts +1 -0
- package/src/server/actions/query.ts +12 -22
- /package/lib/{client/locale → locale}/en-US.d.ts +0 -0
- /package/lib/{client/locale → locale}/en-US.js +0 -0
- /package/lib/{client/locale/ja-JP.d.ts → locale/fr-FR.d.ts} +0 -0
- /package/lib/{client/locale/ja-JP.js → locale/fr-FR.js} +0 -0
- /package/lib/{client/locale/ru-RU.d.ts → locale/ja-JP.d.ts} +0 -0
- /package/lib/{client/locale/ru-RU.js → locale/ja-JP.js} +0 -0
- /package/lib/{client/locale → locale}/pt-BR.d.ts +0 -0
- /package/lib/{client/locale → locale}/pt-BR.js +0 -0
- /package/lib/{client/locale/tr-TR.d.ts → locale/ru-RU.d.ts} +0 -0
- /package/lib/{client/locale/tr-TR.js → locale/ru-RU.js} +0 -0
- /package/lib/{client/locale → locale}/zh-CN.d.ts +0 -0
- /package/lib/{client/locale → locale}/zh-CN.js +0 -0
- /package/src/{client/locale → locale}/en-US.ts +0 -0
- /package/src/{client/locale/ja-JP.ts → locale/fr-FR.ts} +0 -0
- /package/src/{client/locale/ru-RU.ts → locale/ja-JP.ts} +0 -0
- /package/src/{client/locale → locale}/pt-BR.ts +0 -0
- /package/src/{client/locale/tr-TR.ts → locale/ru-RU.ts} +0 -0
- /package/src/{client/locale → locale}/zh-CN.ts +0 -0
|
@@ -157,23 +157,19 @@ const ChartConfigure = props => {
|
|
|
157
157
|
setDimensions((0, _lodash().cloneDeep)(currentDimensions));
|
|
158
158
|
};
|
|
159
159
|
const chartType = (0, _renderer.useDefaultChartType)();
|
|
160
|
-
const form = (0, _react2().useMemo)(() => {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
chartType
|
|
165
|
-
}
|
|
166
|
-
}, initialValues || (field === null || field === void 0 ? void 0 : field.decoratorProps)), {}, {
|
|
167
|
-
collection
|
|
168
|
-
}),
|
|
169
|
-
effects: form => {
|
|
170
|
-
(0, _core().onFieldChange)('config.chartType', () => initChart(true));
|
|
171
|
-
(0, _core().onFormInit)(() => {
|
|
172
|
-
queryReact(form);
|
|
173
|
-
});
|
|
160
|
+
const form = (0, _react2().useMemo)(() => (0, _core().createForm)({
|
|
161
|
+
values: _objectSpread(_objectSpread({
|
|
162
|
+
config: {
|
|
163
|
+
chartType
|
|
174
164
|
}
|
|
175
|
-
})
|
|
176
|
-
|
|
165
|
+
}, initialValues || (field === null || field === void 0 ? void 0 : field.decoratorProps)), {}, {
|
|
166
|
+
collection
|
|
167
|
+
}),
|
|
168
|
+
effects: form => {
|
|
169
|
+
(0, _core().onFieldChange)('config.chartType', () => initChart(true));
|
|
170
|
+
(0, _core().onFormInit)(() => queryReact(form));
|
|
171
|
+
}
|
|
172
|
+
}),
|
|
177
173
|
// visible, collection added here to re-initialize form when visible, collection change
|
|
178
174
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
179
175
|
[field, visible, collection]);
|
|
@@ -238,9 +234,8 @@ const ChartConfigure = props => {
|
|
|
238
234
|
afterSave();
|
|
239
235
|
return;
|
|
240
236
|
}
|
|
241
|
-
insert((0, _utils.createRendererSchema)(rendererProps), {
|
|
242
|
-
onSuccess: afterSave
|
|
243
|
-
wrap: _client().gridRowColWrap
|
|
237
|
+
insert((0, _client().gridRowColWrap)((0, _utils.createRendererSchema)(rendererProps)), {
|
|
238
|
+
onSuccess: afterSave
|
|
244
239
|
});
|
|
245
240
|
},
|
|
246
241
|
onCancel: () => {
|
|
@@ -262,9 +257,10 @@ const ChartConfigure = props => {
|
|
|
262
257
|
bodyStyle: {
|
|
263
258
|
background: 'rgba(128, 128, 128, 0.08)'
|
|
264
259
|
}
|
|
265
|
-
}, _react2().default.createElement(
|
|
266
|
-
layout: "vertical",
|
|
260
|
+
}, _react2().default.createElement(_client().FormProvider, {
|
|
267
261
|
form: form
|
|
262
|
+
}, _react2().default.createElement(_antdV().FormLayout, {
|
|
263
|
+
layout: "vertical"
|
|
268
264
|
}, _react2().default.createElement(_antd().Row, {
|
|
269
265
|
gutter: 8
|
|
270
266
|
}, _react2().default.createElement(_antd().Col, {
|
|
@@ -312,7 +308,7 @@ const ChartConfigure = props => {
|
|
|
312
308
|
style: {
|
|
313
309
|
margin: '12px 12px 12px 0'
|
|
314
310
|
}
|
|
315
|
-
}, _react2().default.createElement(ChartConfigure.Renderer, null))))));
|
|
311
|
+
}, _react2().default.createElement(ChartConfigure.Renderer, null)))))));
|
|
316
312
|
};
|
|
317
313
|
exports.ChartConfigure = ChartConfigure;
|
|
318
314
|
ChartConfigure.Renderer = function Renderer(props) {
|
|
@@ -396,19 +392,10 @@ ChartConfigure.Query = function Query() {
|
|
|
396
392
|
ArrayItems: _antdV().ArrayItems,
|
|
397
393
|
Editable: _antdV().Editable,
|
|
398
394
|
FormCollapse: _antdV().FormCollapse,
|
|
399
|
-
Card: _antd().Card,
|
|
400
|
-
Switch: _antdV().Switch,
|
|
401
|
-
Select: _client().Select,
|
|
402
|
-
Input: _client().Input,
|
|
403
|
-
InputNumber: _client().InputNumber,
|
|
404
395
|
FormItem: _antdV().FormItem,
|
|
405
|
-
Radio: _client().Radio,
|
|
406
396
|
Space: _antd().Space,
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
Text,
|
|
410
|
-
FromSql,
|
|
411
|
-
Cascader: _client().Cascader
|
|
397
|
+
Switch: _antdV().Switch,
|
|
398
|
+
FromSql
|
|
412
399
|
}
|
|
413
400
|
});
|
|
414
401
|
};
|
|
@@ -445,9 +432,6 @@ ChartConfigure.Config = function Config() {
|
|
|
445
432
|
getReference
|
|
446
433
|
},
|
|
447
434
|
components: {
|
|
448
|
-
Card: _antd().Card,
|
|
449
|
-
Select: _client().Select,
|
|
450
|
-
Input: _client().Input,
|
|
451
435
|
FormItem: _antdV().FormItem,
|
|
452
436
|
ArrayItems: _antdV().ArrayItems,
|
|
453
437
|
Space: _antd().Space,
|
|
@@ -465,7 +449,6 @@ ChartConfigure.Transform = function Transform() {
|
|
|
465
449
|
return _react2().default.createElement(_client().SchemaComponent, {
|
|
466
450
|
schema: _configure.transformSchema,
|
|
467
451
|
components: {
|
|
468
|
-
Select: _client().Select,
|
|
469
452
|
FormItem: _antdV().FormItem,
|
|
470
453
|
ArrayItems: _antdV().ArrayItems,
|
|
471
454
|
Space: _antd().Space
|
|
@@ -240,11 +240,19 @@ const querySchema = {
|
|
|
240
240
|
'x-decorator': 'FormItem',
|
|
241
241
|
'x-component': 'Input',
|
|
242
242
|
'x-component-props': {
|
|
243
|
-
placeholder: '{{t("Alias")}}'
|
|
243
|
+
placeholder: '{{t("Alias")}}',
|
|
244
|
+
style: {
|
|
245
|
+
minWidth: '100px'
|
|
246
|
+
}
|
|
244
247
|
}
|
|
245
248
|
}
|
|
246
249
|
}, {
|
|
247
|
-
required: true
|
|
250
|
+
required: true,
|
|
251
|
+
'x-component-props': {
|
|
252
|
+
style: {
|
|
253
|
+
overflow: 'auto'
|
|
254
|
+
}
|
|
255
|
+
}
|
|
248
256
|
})
|
|
249
257
|
}
|
|
250
258
|
},
|
|
@@ -290,7 +298,16 @@ const querySchema = {
|
|
|
290
298
|
'x-decorator': 'FormItem',
|
|
291
299
|
'x-component': 'Input',
|
|
292
300
|
'x-component-props': {
|
|
293
|
-
placeholder: '{{t("Alias")}}'
|
|
301
|
+
placeholder: '{{t("Alias")}}',
|
|
302
|
+
style: {
|
|
303
|
+
minWidth: '100px'
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}, {
|
|
308
|
+
'x-component-props': {
|
|
309
|
+
style: {
|
|
310
|
+
overflow: 'auto'
|
|
294
311
|
}
|
|
295
312
|
}
|
|
296
313
|
})
|
|
@@ -346,12 +363,20 @@ const querySchema = {
|
|
|
346
363
|
'x-component': 'Radio.Group',
|
|
347
364
|
'x-component-props': {
|
|
348
365
|
defaultValue: 'ASC',
|
|
349
|
-
optionType: 'button'
|
|
366
|
+
optionType: 'button',
|
|
367
|
+
style: {
|
|
368
|
+
width: '128px'
|
|
369
|
+
}
|
|
350
370
|
},
|
|
351
371
|
enum: ['ASC', 'DESC']
|
|
352
372
|
}
|
|
353
373
|
}, {
|
|
354
|
-
'x-reactions': '{{ useOrderReaction }}'
|
|
374
|
+
'x-reactions': '{{ useOrderReaction }}',
|
|
375
|
+
'x-component-props': {
|
|
376
|
+
style: {
|
|
377
|
+
overflow: 'auto'
|
|
378
|
+
}
|
|
379
|
+
}
|
|
355
380
|
})
|
|
356
381
|
}
|
|
357
382
|
}
|
|
@@ -146,9 +146,7 @@ ChartRenderer.Designer = function Designer() {
|
|
|
146
146
|
}
|
|
147
147
|
}, t('Configure')), _react2().default.createElement(_client().SchemaSettings.Item, {
|
|
148
148
|
key: "duplicate",
|
|
149
|
-
onClick: () => insertAdjacent('afterEnd', (0, _utils.createRendererSchema)(schema === null || schema === void 0 ? void 0 : schema['x-decorator-props'])
|
|
150
|
-
wrap: _client().gridRowColWrap
|
|
151
|
-
})
|
|
149
|
+
onClick: () => insertAdjacent('afterEnd', (0, _client().gridRowColWrap)((0, _utils.createRendererSchema)(schema === null || schema === void 0 ? void 0 : schema['x-decorator-props'])))
|
|
152
150
|
}, t('Duplicate')), _react2().default.createElement(_client().SchemaSettings.BlockTitleItem, null), _react2().default.createElement(_client().SchemaSettings.Divider, null), _react2().default.createElement(_client().SchemaSettings.Remove
|
|
153
151
|
// removeParentsIfNoChildren
|
|
154
152
|
, {
|
|
@@ -61,7 +61,8 @@ const _useProps = ({
|
|
|
61
61
|
});
|
|
62
62
|
return _objectSpread(_objectSpread({
|
|
63
63
|
data,
|
|
64
|
-
meta
|
|
64
|
+
meta,
|
|
65
|
+
animation: false
|
|
65
66
|
}, general), advanced);
|
|
66
67
|
};
|
|
67
68
|
const G2PlotLibrary = {
|
|
@@ -73,7 +74,7 @@ const G2PlotLibrary = {
|
|
|
73
74
|
useProps: _useProps,
|
|
74
75
|
reference: {
|
|
75
76
|
title: 'Line Chart',
|
|
76
|
-
link: 'https://g2plot.antv.antgroup.com/api/plots/
|
|
77
|
+
link: 'https://g2plot.antv.antgroup.com/api/plots/line'
|
|
77
78
|
}
|
|
78
79
|
},
|
|
79
80
|
area: {
|
|
@@ -49,15 +49,19 @@ const parseFieldAndAssociations = (ctx, params) => {
|
|
|
49
49
|
name = _selected$field[1];
|
|
50
50
|
}
|
|
51
51
|
let field = underscored ? (0, _database().snakeCase)(name) : name;
|
|
52
|
-
let
|
|
52
|
+
let fieldType = (_fields$get = fields.get(name)) === null || _fields$get === void 0 ? void 0 : _fields$get.type;
|
|
53
53
|
if (target) {
|
|
54
|
-
var _fields$get2;
|
|
54
|
+
var _targetFields$get, _fields$get2;
|
|
55
|
+
const targetField = fields.get(target);
|
|
56
|
+
const targetCollection = ctx.db.getCollection(targetField.target);
|
|
57
|
+
const targetFields = targetCollection.fields;
|
|
58
|
+
fieldType = (_targetFields$get = targetFields.get(name)) === null || _targetFields$get === void 0 ? void 0 : _targetFields$get.type;
|
|
55
59
|
field = `${target}.${field}`;
|
|
56
60
|
name = `${target}.${name}`;
|
|
57
|
-
|
|
61
|
+
const targetType = (_fields$get2 = fields.get(target)) === null || _fields$get2 === void 0 ? void 0 : _fields$get2.type;
|
|
58
62
|
if (!models[target]) {
|
|
59
63
|
models[target] = {
|
|
60
|
-
type
|
|
64
|
+
type: targetType
|
|
61
65
|
};
|
|
62
66
|
}
|
|
63
67
|
} else {
|
|
@@ -66,7 +70,7 @@ const parseFieldAndAssociations = (ctx, params) => {
|
|
|
66
70
|
return _objectSpread(_objectSpread({}, selected), {}, {
|
|
67
71
|
field,
|
|
68
72
|
name,
|
|
69
|
-
type,
|
|
73
|
+
type: fieldType,
|
|
70
74
|
alias: selected.alias || name
|
|
71
75
|
});
|
|
72
76
|
};
|
|
@@ -161,11 +165,7 @@ const parseBuilder = (ctx, builder) => {
|
|
|
161
165
|
fieldMap[alias || field] = dimension;
|
|
162
166
|
});
|
|
163
167
|
orders.forEach(item => {
|
|
164
|
-
const
|
|
165
|
-
let alias = `"${item.alias}"`;
|
|
166
|
-
if (dialect === 'mysql') {
|
|
167
|
-
alias = `\`${item.alias}\``;
|
|
168
|
-
}
|
|
168
|
+
const alias = sequelize.getQueryInterface().quoteIdentifier(item.alias);
|
|
169
169
|
const name = hasAgg ? sequelize.literal(alias) : sequelize.col(item.field);
|
|
170
170
|
order.push([name, item.order || 'ASC']);
|
|
171
171
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/plugin-data-visualization",
|
|
3
|
-
"version": "0.11.1-alpha.
|
|
3
|
+
"version": "0.11.1-alpha.4",
|
|
4
4
|
"displayName": "Data Visualization",
|
|
5
5
|
"displayName.zh-CN": "数据可视化",
|
|
6
6
|
"description": "Provides business intelligence and data visualization features",
|
|
@@ -17,19 +17,19 @@
|
|
|
17
17
|
"@formily/core": "2.2.26",
|
|
18
18
|
"@formily/react": "2.2.26",
|
|
19
19
|
"@formily/shared": "2.2.26",
|
|
20
|
-
"@nocobase/actions": "0.11.1-alpha.
|
|
21
|
-
"@nocobase/cache": "0.11.1-alpha.
|
|
22
|
-
"@nocobase/client": "0.11.1-alpha.
|
|
23
|
-
"@nocobase/database": "0.11.1-alpha.
|
|
24
|
-
"@nocobase/server": "0.11.1-alpha.
|
|
25
|
-
"@nocobase/test": "0.11.1-alpha.
|
|
26
|
-
"@nocobase/utils": "0.11.1-alpha.
|
|
27
|
-
"@testing-library/react": "^
|
|
20
|
+
"@nocobase/actions": "0.11.1-alpha.4",
|
|
21
|
+
"@nocobase/cache": "0.11.1-alpha.4",
|
|
22
|
+
"@nocobase/client": "0.11.1-alpha.4",
|
|
23
|
+
"@nocobase/database": "0.11.1-alpha.4",
|
|
24
|
+
"@nocobase/server": "0.11.1-alpha.4",
|
|
25
|
+
"@nocobase/test": "0.11.1-alpha.4",
|
|
26
|
+
"@nocobase/utils": "0.11.1-alpha.4",
|
|
27
|
+
"@testing-library/react": "^14.0.0",
|
|
28
28
|
"antd": "^5.6.4",
|
|
29
29
|
"lodash": "^4.17.21",
|
|
30
30
|
"react": "^18.2.0",
|
|
31
31
|
"react-i18next": "^11.15.1",
|
|
32
32
|
"vitest": "^0.33.0"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "d9b5bde913013f1057e1aab49587eb0ad3dcb06e"
|
|
35
35
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as client from '@nocobase/client';
|
|
2
|
-
|
|
2
|
+
import { renderHook } from '@testing-library/react';
|
|
3
3
|
import { vi } from 'vitest';
|
|
4
4
|
import formatters from '../block/formatters';
|
|
5
5
|
import transformers from '../block/transformers';
|
|
@@ -13,8 +13,7 @@ import {
|
|
|
13
13
|
useTransformers,
|
|
14
14
|
} from '../hooks';
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
describe.skip('hooks', () => {
|
|
16
|
+
describe('hooks', () => {
|
|
18
17
|
beforeEach(() => {
|
|
19
18
|
vi.spyOn(client, 'useCollectionManager').mockReturnValue({
|
|
20
19
|
getCollectionFields: (name: string) =>
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import { RightSquareOutlined } from '@ant-design/icons';
|
|
2
|
-
import { ArrayItems, Editable,
|
|
2
|
+
import { ArrayItems, Editable, FormCollapse, FormItem, FormLayout, Switch } from '@formily/antd-v5';
|
|
3
3
|
import { Form as FormType, ObjectField, createForm, onFieldChange, onFormInit } from '@formily/core';
|
|
4
4
|
import { FormConsumer, ISchema, Schema } from '@formily/react';
|
|
5
5
|
import {
|
|
6
6
|
AutoComplete,
|
|
7
|
-
|
|
8
|
-
DatePicker,
|
|
9
|
-
Filter,
|
|
10
|
-
Input,
|
|
11
|
-
InputNumber,
|
|
12
|
-
Radio,
|
|
7
|
+
FormProvider,
|
|
13
8
|
SchemaComponent,
|
|
14
|
-
Select,
|
|
15
9
|
gridRowColWrap,
|
|
16
10
|
useCollectionFieldsOptions,
|
|
17
11
|
useCollectionFilterOptions,
|
|
@@ -126,17 +120,14 @@ export const ChartConfigure: React.FC<{
|
|
|
126
120
|
};
|
|
127
121
|
const chartType = useDefaultChartType();
|
|
128
122
|
const form = useMemo(
|
|
129
|
-
() =>
|
|
130
|
-
|
|
123
|
+
() =>
|
|
124
|
+
createForm({
|
|
131
125
|
values: { config: { chartType }, ...(initialValues || field?.decoratorProps), collection },
|
|
132
126
|
effects: (form) => {
|
|
133
127
|
onFieldChange('config.chartType', () => initChart(true));
|
|
134
|
-
onFormInit(() =>
|
|
135
|
-
queryReact(form);
|
|
136
|
-
});
|
|
128
|
+
onFormInit(() => queryReact(form));
|
|
137
129
|
},
|
|
138
|
-
})
|
|
139
|
-
},
|
|
130
|
+
}),
|
|
140
131
|
// visible, collection added here to re-initialize form when visible, collection change
|
|
141
132
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
142
133
|
[field, visible, collection],
|
|
@@ -199,9 +190,8 @@ export const ChartConfigure: React.FC<{
|
|
|
199
190
|
afterSave();
|
|
200
191
|
return;
|
|
201
192
|
}
|
|
202
|
-
insert(createRendererSchema(rendererProps), {
|
|
193
|
+
insert(gridRowColWrap(createRendererSchema(rendererProps)), {
|
|
203
194
|
onSuccess: afterSave,
|
|
204
|
-
wrap: gridRowColWrap,
|
|
205
195
|
});
|
|
206
196
|
}}
|
|
207
197
|
onCancel={() => {
|
|
@@ -224,70 +214,72 @@ export const ChartConfigure: React.FC<{
|
|
|
224
214
|
background: 'rgba(128, 128, 128, 0.08)',
|
|
225
215
|
}}
|
|
226
216
|
>
|
|
227
|
-
<
|
|
228
|
-
<
|
|
229
|
-
<
|
|
230
|
-
<
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
{
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
<
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
{
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
<
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
217
|
+
<FormProvider form={form}>
|
|
218
|
+
<FormLayout layout="vertical">
|
|
219
|
+
<Row gutter={8}>
|
|
220
|
+
<Col span={7}>
|
|
221
|
+
<Card
|
|
222
|
+
style={{
|
|
223
|
+
height: 'calc(100vh - 300px)',
|
|
224
|
+
overflow: 'auto',
|
|
225
|
+
margin: '12px 0 12px 12px',
|
|
226
|
+
}}
|
|
227
|
+
ref={queryRef}
|
|
228
|
+
>
|
|
229
|
+
<Tabs
|
|
230
|
+
tabBarExtraContent={<RunButton />}
|
|
231
|
+
items={[
|
|
232
|
+
{
|
|
233
|
+
label: t('Query'),
|
|
234
|
+
key: 'query',
|
|
235
|
+
children: <ChartConfigure.Query />,
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
label: t('Data'),
|
|
239
|
+
key: 'data',
|
|
240
|
+
children: <ChartConfigure.Data />,
|
|
241
|
+
},
|
|
242
|
+
]}
|
|
243
|
+
/>
|
|
244
|
+
</Card>
|
|
245
|
+
</Col>
|
|
246
|
+
<Col span={6}>
|
|
247
|
+
<Card
|
|
248
|
+
style={{
|
|
249
|
+
height: 'calc(100vh - 300px)',
|
|
250
|
+
overflow: 'auto',
|
|
251
|
+
margin: '12px 3px 12px 3px',
|
|
252
|
+
}}
|
|
253
|
+
ref={configRef}
|
|
254
|
+
>
|
|
255
|
+
<Tabs
|
|
256
|
+
items={[
|
|
257
|
+
{
|
|
258
|
+
label: t('Chart'),
|
|
259
|
+
key: 'chart',
|
|
260
|
+
children: <ChartConfigure.Config />,
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
label: t('Transform'),
|
|
264
|
+
key: 'transform',
|
|
265
|
+
children: <ChartConfigure.Transform />,
|
|
266
|
+
},
|
|
267
|
+
]}
|
|
268
|
+
/>
|
|
269
|
+
</Card>
|
|
270
|
+
</Col>
|
|
271
|
+
<Col span={11}>
|
|
272
|
+
<Card
|
|
273
|
+
style={{
|
|
274
|
+
margin: '12px 12px 12px 0',
|
|
275
|
+
}}
|
|
276
|
+
>
|
|
277
|
+
<ChartConfigure.Renderer />
|
|
278
|
+
</Card>
|
|
279
|
+
</Col>
|
|
280
|
+
</Row>
|
|
281
|
+
</FormLayout>
|
|
282
|
+
</FormProvider>
|
|
291
283
|
</Modal>
|
|
292
284
|
);
|
|
293
285
|
};
|
|
@@ -359,24 +351,7 @@ ChartConfigure.Query = function Query() {
|
|
|
359
351
|
collection: current?.collection,
|
|
360
352
|
useOrderReaction: useOrderReaction(compiledFieldOptions, fields),
|
|
361
353
|
}}
|
|
362
|
-
components={{
|
|
363
|
-
ArrayItems,
|
|
364
|
-
Editable,
|
|
365
|
-
FormCollapse,
|
|
366
|
-
Card,
|
|
367
|
-
Switch,
|
|
368
|
-
Select,
|
|
369
|
-
Input,
|
|
370
|
-
InputNumber,
|
|
371
|
-
FormItem,
|
|
372
|
-
Radio,
|
|
373
|
-
Space,
|
|
374
|
-
Filter,
|
|
375
|
-
DatePicker,
|
|
376
|
-
Text,
|
|
377
|
-
FromSql,
|
|
378
|
-
Cascader,
|
|
379
|
-
}}
|
|
354
|
+
components={{ ArrayItems, Editable, FormCollapse, FormItem, Space, Switch, FromSql }}
|
|
380
355
|
/>
|
|
381
356
|
);
|
|
382
357
|
};
|
|
@@ -411,7 +386,7 @@ ChartConfigure.Config = function Config() {
|
|
|
411
386
|
<SchemaComponent
|
|
412
387
|
schema={getConfigSchema(schema)}
|
|
413
388
|
scope={{ t, chartTypes, useChartFields: getChartFields, getReference }}
|
|
414
|
-
components={{
|
|
389
|
+
components={{ FormItem, ArrayItems, Space, AutoComplete }}
|
|
415
390
|
/>
|
|
416
391
|
);
|
|
417
392
|
}}
|
|
@@ -427,7 +402,7 @@ ChartConfigure.Transform = function Transform() {
|
|
|
427
402
|
return (
|
|
428
403
|
<SchemaComponent
|
|
429
404
|
schema={transformSchema}
|
|
430
|
-
components={{
|
|
405
|
+
components={{ FormItem, ArrayItems, Space }}
|
|
431
406
|
scope={{ useChartFields: getChartFields, useFieldTypeOptions, useTransformers, t }}
|
|
432
407
|
/>
|
|
433
408
|
);
|
|
@@ -219,10 +219,20 @@ export const querySchema: ISchema = {
|
|
|
219
219
|
'x-component': 'Input',
|
|
220
220
|
'x-component-props': {
|
|
221
221
|
placeholder: '{{t("Alias")}}',
|
|
222
|
+
style: {
|
|
223
|
+
minWidth: '100px',
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
required: true,
|
|
230
|
+
'x-component-props': {
|
|
231
|
+
style: {
|
|
232
|
+
overflow: 'auto',
|
|
222
233
|
},
|
|
223
234
|
},
|
|
224
235
|
},
|
|
225
|
-
{ required: true },
|
|
226
236
|
),
|
|
227
237
|
},
|
|
228
238
|
},
|
|
@@ -234,44 +244,56 @@ export const querySchema: ISchema = {
|
|
|
234
244
|
key: 'dimensions',
|
|
235
245
|
},
|
|
236
246
|
properties: {
|
|
237
|
-
dimensions: getArraySchema(
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
247
|
+
dimensions: getArraySchema(
|
|
248
|
+
{
|
|
249
|
+
field: {
|
|
250
|
+
type: 'string',
|
|
251
|
+
'x-decorator': 'FormItem',
|
|
252
|
+
'x-component': 'Cascader',
|
|
253
|
+
'x-component-props': {
|
|
254
|
+
placeholder: '{{t("Field")}}',
|
|
255
|
+
fieldNames: {
|
|
256
|
+
label: 'title',
|
|
257
|
+
value: 'name',
|
|
258
|
+
children: 'children',
|
|
259
|
+
},
|
|
248
260
|
},
|
|
261
|
+
enum: '{{ fieldOptions }}',
|
|
262
|
+
required: true,
|
|
249
263
|
},
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
264
|
+
format: {
|
|
265
|
+
type: 'string',
|
|
266
|
+
'x-decorator': 'FormItem',
|
|
267
|
+
'x-component': 'Select',
|
|
268
|
+
'x-component-props': {
|
|
269
|
+
placeholder: '{{t("Format")}}',
|
|
270
|
+
style: {
|
|
271
|
+
maxWidth: '120px',
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
'x-reactions': '{{ useFormatterOptions }}',
|
|
275
|
+
'x-visible': '{{ $self.dataSource && $self.dataSource.length }}',
|
|
276
|
+
},
|
|
277
|
+
alias: {
|
|
278
|
+
type: 'string',
|
|
279
|
+
'x-decorator': 'FormItem',
|
|
280
|
+
'x-component': 'Input',
|
|
281
|
+
'x-component-props': {
|
|
282
|
+
placeholder: '{{t("Alias")}}',
|
|
283
|
+
style: {
|
|
284
|
+
minWidth: '100px',
|
|
285
|
+
},
|
|
261
286
|
},
|
|
262
287
|
},
|
|
263
|
-
'x-reactions': '{{ useFormatterOptions }}',
|
|
264
|
-
'x-visible': '{{ $self.dataSource && $self.dataSource.length }}',
|
|
265
288
|
},
|
|
266
|
-
|
|
267
|
-
type: 'string',
|
|
268
|
-
'x-decorator': 'FormItem',
|
|
269
|
-
'x-component': 'Input',
|
|
289
|
+
{
|
|
270
290
|
'x-component-props': {
|
|
271
|
-
|
|
291
|
+
style: {
|
|
292
|
+
overflow: 'auto',
|
|
293
|
+
},
|
|
272
294
|
},
|
|
273
295
|
},
|
|
274
|
-
|
|
296
|
+
),
|
|
275
297
|
},
|
|
276
298
|
},
|
|
277
299
|
pane3: {
|
|
@@ -325,12 +347,20 @@ export const querySchema: ISchema = {
|
|
|
325
347
|
'x-component-props': {
|
|
326
348
|
defaultValue: 'ASC',
|
|
327
349
|
optionType: 'button',
|
|
350
|
+
style: {
|
|
351
|
+
width: '128px',
|
|
352
|
+
},
|
|
328
353
|
},
|
|
329
354
|
enum: ['ASC', 'DESC'],
|
|
330
355
|
},
|
|
331
356
|
},
|
|
332
357
|
{
|
|
333
358
|
'x-reactions': '{{ useOrderReaction }}',
|
|
359
|
+
'x-component-props': {
|
|
360
|
+
style: {
|
|
361
|
+
overflow: 'auto',
|
|
362
|
+
},
|
|
363
|
+
},
|
|
334
364
|
},
|
|
335
365
|
),
|
|
336
366
|
},
|
|
@@ -96,11 +96,7 @@ ChartRenderer.Designer = function Designer() {
|
|
|
96
96
|
</SchemaSettings.Item>
|
|
97
97
|
<SchemaSettings.Item
|
|
98
98
|
key="duplicate"
|
|
99
|
-
onClick={() =>
|
|
100
|
-
insertAdjacent('afterEnd', createRendererSchema(schema?.['x-decorator-props']), {
|
|
101
|
-
wrap: gridRowColWrap,
|
|
102
|
-
})
|
|
103
|
-
}
|
|
99
|
+
onClick={() => insertAdjacent('afterEnd', gridRowColWrap(createRendererSchema(schema?.['x-decorator-props'])))}
|
|
104
100
|
>
|
|
105
101
|
{t('Duplicate')}
|
|
106
102
|
</SchemaSettings.Item>
|
|
@@ -42,6 +42,7 @@ const useProps: usePropsFunc = ({ data, fieldProps, general, advanced }) => {
|
|
|
42
42
|
return {
|
|
43
43
|
data,
|
|
44
44
|
meta,
|
|
45
|
+
animation: false,
|
|
45
46
|
...general,
|
|
46
47
|
...advanced,
|
|
47
48
|
};
|
|
@@ -56,7 +57,7 @@ export const G2PlotLibrary: Charts = {
|
|
|
56
57
|
useProps,
|
|
57
58
|
reference: {
|
|
58
59
|
title: 'Line Chart',
|
|
59
|
-
link: 'https://g2plot.antv.antgroup.com/api/plots/
|
|
60
|
+
link: 'https://g2plot.antv.antgroup.com/api/plots/line',
|
|
60
61
|
},
|
|
61
62
|
},
|
|
62
63
|
area: {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Context, Next } from '@nocobase/actions';
|
|
2
2
|
import { Cache } from '@nocobase/cache';
|
|
3
|
-
import { FilterParser, snakeCase } from '@nocobase/database';
|
|
3
|
+
import { Field, FilterParser, snakeCase } from '@nocobase/database';
|
|
4
4
|
import ChartsV2Plugin from '../plugin';
|
|
5
5
|
import { formatter } from './formatter';
|
|
6
6
|
|
|
@@ -65,13 +65,17 @@ export const parseFieldAndAssociations = (ctx: Context, params: QueryParams) =>
|
|
|
65
65
|
[target, name] = selected.field;
|
|
66
66
|
}
|
|
67
67
|
let field = underscored ? snakeCase(name) : name;
|
|
68
|
-
let
|
|
68
|
+
let fieldType = fields.get(name)?.type;
|
|
69
69
|
if (target) {
|
|
70
|
+
const targetField = fields.get(target) as Field;
|
|
71
|
+
const targetCollection = ctx.db.getCollection(targetField.target);
|
|
72
|
+
const targetFields = targetCollection.fields;
|
|
73
|
+
fieldType = targetFields.get(name)?.type;
|
|
70
74
|
field = `${target}.${field}`;
|
|
71
75
|
name = `${target}.${name}`;
|
|
72
|
-
|
|
76
|
+
const targetType = fields.get(target)?.type;
|
|
73
77
|
if (!models[target]) {
|
|
74
|
-
models[target] = { type };
|
|
78
|
+
models[target] = { type: targetType };
|
|
75
79
|
}
|
|
76
80
|
} else {
|
|
77
81
|
field = `${collectionName}.${field}`;
|
|
@@ -80,7 +84,7 @@ export const parseFieldAndAssociations = (ctx: Context, params: QueryParams) =>
|
|
|
80
84
|
...selected,
|
|
81
85
|
field,
|
|
82
86
|
name,
|
|
83
|
-
type,
|
|
87
|
+
type: fieldType,
|
|
84
88
|
alias: selected.alias || name,
|
|
85
89
|
};
|
|
86
90
|
};
|
|
@@ -161,11 +165,7 @@ export const parseBuilder = (ctx: Context, builder: QueryParams) => {
|
|
|
161
165
|
});
|
|
162
166
|
|
|
163
167
|
orders.forEach((item: OrderProps) => {
|
|
164
|
-
const
|
|
165
|
-
let alias = `"${item.alias}"`;
|
|
166
|
-
if (dialect === 'mysql') {
|
|
167
|
-
alias = `\`${item.alias}\``;
|
|
168
|
-
}
|
|
168
|
+
const alias = sequelize.getQueryInterface().quoteIdentifier(item.alias);
|
|
169
169
|
const name = hasAgg ? sequelize.literal(alias) : sequelize.col(item.field as string);
|
|
170
170
|
order.push([name, item.order || 'ASC']);
|
|
171
171
|
});
|
|
@@ -251,18 +251,8 @@ export const cacheWrap = async (
|
|
|
251
251
|
};
|
|
252
252
|
|
|
253
253
|
export const query = async (ctx: Context, next: Next) => {
|
|
254
|
-
const {
|
|
255
|
-
|
|
256
|
-
collection,
|
|
257
|
-
measures,
|
|
258
|
-
dimensions,
|
|
259
|
-
orders,
|
|
260
|
-
filter,
|
|
261
|
-
limit,
|
|
262
|
-
sql,
|
|
263
|
-
cache: cacheConfig,
|
|
264
|
-
refresh,
|
|
265
|
-
} = ctx.action.params.values as QueryParams;
|
|
254
|
+
const { uid, collection, measures, dimensions, orders, filter, limit, sql, cache: cacheConfig, refresh } = ctx.action
|
|
255
|
+
.params.values as QueryParams;
|
|
266
256
|
const roleName = ctx.state.currentRole || 'anonymous';
|
|
267
257
|
const can = ctx.app.acl.can({ role: roleName, resource: collection, action: 'list' });
|
|
268
258
|
if (!can && roleName !== 'root') {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|