@nocobase/plugin-data-visualization 0.11.1-alpha.5 → 0.12.0-alpha.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/client.d.ts +2 -2
- package/client.js +1 -1
- package/dist/client/chart/antd/antd.d.ts +7 -0
- package/dist/client/chart/antd/index.d.ts +4 -0
- package/dist/client/chart/antd/statistic.d.ts +19 -0
- package/dist/client/chart/antd/table.d.ts +6 -0
- package/dist/client/chart/chart.d.ts +65 -0
- package/dist/client/chart/g2plot/bar.d.ts +16 -0
- package/dist/client/chart/g2plot/dualAxes.d.ts +20 -0
- package/dist/client/chart/g2plot/g2plot.d.ts +19 -0
- package/dist/client/chart/g2plot/index.d.ts +6 -0
- package/dist/client/chart/g2plot/pie.d.ts +17 -0
- package/dist/client/chart/library.d.ts +28 -0
- package/{lib → dist}/client/hooks.d.ts +22 -154
- package/{lib → dist}/client/index.d.ts +3 -1
- package/dist/client/index.js +67448 -0
- package/{lib → dist}/client/renderer/ChartRendererProvider.d.ts +1 -8
- package/{lib → dist}/client/renderer/index.d.ts +0 -2
- package/{lib → dist}/client/utils.d.ts +1 -1
- package/{lib → dist}/index.d.ts +1 -0
- package/dist/index.js +18 -0
- package/dist/locale/en-US.js +26 -0
- package/dist/locale/fr-FR.js +5 -0
- package/dist/locale/ja-JP.js +5 -0
- package/dist/locale/pt-BR.js +26 -0
- package/dist/locale/ru-RU.js +5 -0
- package/dist/locale/tr-TR.js +5 -0
- package/dist/locale/zh-CN.js +74 -0
- package/dist/server/actions/formatter.js +41 -0
- package/{src/server/actions/query.ts → dist/server/actions/query.js} +75 -133
- package/dist/server/index.js +11 -0
- package/dist/server/plugin.js +42 -0
- package/package.json +23 -22
- package/server.d.ts +2 -2
- package/server.js +1 -1
- package/lib/client/Settings.js +0 -81
- package/lib/client/block/ChartBlock.js +0 -74
- package/lib/client/block/ChartBlockDesigner.js +0 -35
- package/lib/client/block/ChartBlockInitializer.js +0 -114
- package/lib/client/block/ChartConfigure.js +0 -499
- package/lib/client/block/formatters.js +0 -58
- package/lib/client/block/index.js +0 -49
- package/lib/client/block/schemas/configure.js +0 -517
- package/lib/client/block/transformers.js +0 -68
- package/lib/client/hooks.js +0 -275
- package/lib/client/index.js +0 -80
- package/lib/client/locale/index.js +0 -37
- package/lib/client/renderer/ChartLibrary.d.ts +0 -72
- package/lib/client/renderer/ChartLibrary.js +0 -146
- package/lib/client/renderer/ChartRenderer.js +0 -181
- package/lib/client/renderer/ChartRendererProvider.js +0 -105
- package/lib/client/renderer/index.js +0 -49
- package/lib/client/renderer/library/AntdLibrary.d.ts +0 -2
- package/lib/client/renderer/library/AntdLibrary.js +0 -123
- package/lib/client/renderer/library/G2PlotLibrary.d.ts +0 -2
- package/lib/client/renderer/library/G2PlotLibrary.js +0 -288
- package/lib/client/renderer/library/index.d.ts +0 -3
- package/lib/client/renderer/library/index.js +0 -15
- package/lib/client/utils.js +0 -137
- package/lib/index.js +0 -13
- package/lib/locale/en-US.js +0 -29
- package/lib/locale/fr-FR.js +0 -8
- package/lib/locale/ja-JP.js +0 -8
- package/lib/locale/pt-BR.js +0 -29
- package/lib/locale/ru-RU.js +0 -8
- package/lib/locale/tr-TR.js +0 -8
- package/lib/locale/zh-CN.js +0 -77
- package/lib/server/actions/formatter.js +0 -44
- package/lib/server/actions/query.js +0 -331
- package/lib/server/index.js +0 -13
- package/lib/server/plugin.js +0 -64
- package/src/client/Settings.tsx +0 -43
- package/src/client/__tests__/chart-configure.test.tsx +0 -14
- package/src/client/__tests__/chart-library.test.ts +0 -78
- package/src/client/__tests__/chart-renderer.test.tsx +0 -30
- package/src/client/__tests__/hooks.test.ts +0 -261
- package/src/client/block/ChartBlock.tsx +0 -24
- package/src/client/block/ChartBlockDesigner.tsx +0 -19
- package/src/client/block/ChartBlockInitializer.tsx +0 -82
- package/src/client/block/ChartConfigure.tsx +0 -446
- package/src/client/block/formatters.ts +0 -70
- package/src/client/block/index.ts +0 -4
- package/src/client/block/schemas/configure.ts +0 -504
- package/src/client/block/transformers.ts +0 -52
- package/src/client/hooks.ts +0 -239
- package/src/client/index.tsx +0 -47
- package/src/client/locale/index.ts +0 -18
- package/src/client/renderer/ChartLibrary.tsx +0 -183
- package/src/client/renderer/ChartRenderer.tsx +0 -129
- package/src/client/renderer/ChartRendererProvider.tsx +0 -123
- package/src/client/renderer/index.ts +0 -4
- package/src/client/renderer/library/AntdLibrary.tsx +0 -94
- package/src/client/renderer/library/G2PlotLibrary.tsx +0 -236
- package/src/client/renderer/library/index.tsx +0 -4
- package/src/client/utils.ts +0 -102
- package/src/index.ts +0 -1
- package/src/locale/en-US.ts +0 -23
- package/src/locale/fr-FR.ts +0 -1
- package/src/locale/ja-JP.ts +0 -1
- package/src/locale/pt-BR.ts +0 -23
- package/src/locale/ru-RU.ts +0 -1
- package/src/locale/tr-TR.ts +0 -1
- package/src/locale/zh-CN.ts +0 -72
- package/src/server/__tests__/api.test.ts +0 -102
- package/src/server/__tests__/formatter.test.ts +0 -49
- package/src/server/__tests__/query.test.ts +0 -220
- package/src/server/actions/formatter.ts +0 -49
- package/src/server/collections/.gitkeep +0 -0
- package/src/server/index.ts +0 -1
- package/src/server/plugin.ts +0 -37
- /package/{lib → dist}/client/Settings.d.ts +0 -0
- /package/{lib → dist}/client/block/ChartBlock.d.ts +0 -0
- /package/{lib → dist}/client/block/ChartBlockDesigner.d.ts +0 -0
- /package/{lib → dist}/client/block/ChartBlockInitializer.d.ts +0 -0
- /package/{lib → dist}/client/block/ChartConfigure.d.ts +0 -0
- /package/{lib → dist}/client/block/formatters.d.ts +0 -0
- /package/{lib → dist}/client/block/index.d.ts +0 -0
- /package/{lib → dist}/client/block/schemas/configure.d.ts +0 -0
- /package/{lib → dist}/client/block/transformers.d.ts +0 -0
- /package/{lib → dist}/client/locale/index.d.ts +0 -0
- /package/{lib → dist}/client/renderer/ChartRenderer.d.ts +0 -0
- /package/{lib → dist}/locale/en-US.d.ts +0 -0
- /package/{lib → dist}/locale/fr-FR.d.ts +0 -0
- /package/{lib → dist}/locale/ja-JP.d.ts +0 -0
- /package/{lib → dist}/locale/pt-BR.d.ts +0 -0
- /package/{lib → dist}/locale/ru-RU.d.ts +0 -0
- /package/{lib → dist}/locale/tr-TR.d.ts +0 -0
- /package/{lib → dist}/locale/zh-CN.d.ts +0 -0
- /package/{lib → dist}/server/actions/formatter.d.ts +0 -0
- /package/{lib → dist}/server/actions/query.d.ts +0 -0
- /package/{lib → dist}/server/index.d.ts +0 -0
- /package/{lib → dist}/server/plugin.d.ts +0 -0
|
@@ -40,14 +40,7 @@ export type ChartRendererProps = {
|
|
|
40
40
|
mode?: 'builder' | 'sql';
|
|
41
41
|
};
|
|
42
42
|
export declare const ChartRendererContext: React.Context<{
|
|
43
|
-
collection: string;
|
|
44
|
-
config?: {
|
|
45
|
-
chartType: string;
|
|
46
|
-
general: any;
|
|
47
|
-
advanced: any;
|
|
48
|
-
};
|
|
49
|
-
transform?: TransformProps[];
|
|
50
43
|
service: any;
|
|
51
44
|
data?: any[];
|
|
52
|
-
}>;
|
|
45
|
+
} & ChartRendererProps>;
|
|
53
46
|
export declare const ChartRendererProvider: React.FC<ChartRendererProps>;
|
|
@@ -93,4 +93,4 @@ export declare const getSelectedFields: (fields: FieldOption[], query: QueryProp
|
|
|
93
93
|
target?: string;
|
|
94
94
|
targetFields?: FieldOption[];
|
|
95
95
|
}[];
|
|
96
|
-
export declare const processData: (
|
|
96
|
+
export declare const processData: (selectedFields: FieldOption[], data: any[], scope: any) => {}[];
|
package/{lib → dist}/index.d.ts
RENAMED
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var server = require('./server');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
Object.defineProperty(exports, 'default', {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function () { return server__namespace.default; }
|
|
12
|
+
});
|
|
13
|
+
Object.keys(server).forEach(function (k) {
|
|
14
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return server[k]; }
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var en_US_default = {
|
|
4
|
+
Edit: "Edit",
|
|
5
|
+
Delete: "Delete",
|
|
6
|
+
Cancel: "Cancel",
|
|
7
|
+
Submit: "Submit",
|
|
8
|
+
Actions: "Actions",
|
|
9
|
+
Title: "Title",
|
|
10
|
+
Enable: "Enable",
|
|
11
|
+
"SAML manager": "SAML manager",
|
|
12
|
+
"SAML Providers": "SAML Providers",
|
|
13
|
+
"Redirect url": "Redirect url",
|
|
14
|
+
"SP entity id": "SP entity id",
|
|
15
|
+
"Add provider": "Add",
|
|
16
|
+
"Edit provider": "Edit",
|
|
17
|
+
"Client id": "Client id",
|
|
18
|
+
"Entity id or issuer": "Entity id or issuer",
|
|
19
|
+
"Login Url": "Login Url",
|
|
20
|
+
"Public cert": "Public cert",
|
|
21
|
+
"Delete provider": "Delete",
|
|
22
|
+
"Are you sure you want to delete it?": "Are you sure you want to delete it?",
|
|
23
|
+
"Sign in button name, which will be displayed on the sign in page": "Sign in button name, which will be displayed on the sign in page"
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
module.exports = en_US_default;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var pt_BR_default = {
|
|
4
|
+
Edit: "Editar",
|
|
5
|
+
Delete: "Delete",
|
|
6
|
+
Cancel: "Cancelar",
|
|
7
|
+
Submit: "Enviar",
|
|
8
|
+
Actions: "A\xE7\xF5es",
|
|
9
|
+
Title: "Titulo",
|
|
10
|
+
Enable: "Ativo",
|
|
11
|
+
"SAML manager": "Gerenciador SAML",
|
|
12
|
+
"SAML Providers": "Provedores SAML",
|
|
13
|
+
"Redirect url": "URL de redirecionamento",
|
|
14
|
+
"SP entity id": "ID de entidade do provedor de servi\xE7o (SP)",
|
|
15
|
+
"Add provider": "Adicionar",
|
|
16
|
+
"Edit provider": "Editar",
|
|
17
|
+
"Client id": "ID do cliente",
|
|
18
|
+
"Entity id or issuer": "ID de entidade ou emissor",
|
|
19
|
+
"Login Url": "URL de login",
|
|
20
|
+
"Public cert": "Certificado p\xFAblico",
|
|
21
|
+
"Delete provider": "Excluir",
|
|
22
|
+
"Are you sure you want to delete it?": "Tem certeza de que deseja exclu\xED-lo?",
|
|
23
|
+
"Sign in button name, which will be displayed on the sign in page": "Nome do bot\xE3o de login, que ser\xE1 exibido na p\xE1gina de login"
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
module.exports = pt_BR_default;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var zh_CN_default = {
|
|
4
|
+
Edit: "\u7F16\u8F91",
|
|
5
|
+
Delete: "\u5220\u9664",
|
|
6
|
+
Cancel: "\u53D6\u6D88",
|
|
7
|
+
Submit: "\u63D0\u4EA4",
|
|
8
|
+
Actions: "\u64CD\u4F5C",
|
|
9
|
+
Title: "\u540D\u79F0",
|
|
10
|
+
Enable: "\u542F\u7528",
|
|
11
|
+
Chart: "\u56FE\u8868",
|
|
12
|
+
ChartV2: "\u56FE\u8868V2",
|
|
13
|
+
Charts: "\u56FE\u8868",
|
|
14
|
+
Configure: "\u914D\u7F6E",
|
|
15
|
+
Duplicate: "\u590D\u5236",
|
|
16
|
+
"Configure chart": "\u914D\u7F6E\u56FE\u8868",
|
|
17
|
+
Transform: "\u6570\u636E\u8F6C\u6362",
|
|
18
|
+
"Chart type": "\u56FE\u8868\u7C7B\u578B",
|
|
19
|
+
"JSON config": "JSON \u914D\u7F6E",
|
|
20
|
+
Query: "\u67E5\u8BE2",
|
|
21
|
+
Data: "\u6570\u636E",
|
|
22
|
+
"Run query": "\u6267\u884C\u67E5\u8BE2",
|
|
23
|
+
Measures: "\u5EA6\u91CF",
|
|
24
|
+
Dimensions: "\u7EF4\u5EA6",
|
|
25
|
+
Filter: "\u8FC7\u6EE4",
|
|
26
|
+
Sort: "\u6392\u5E8F",
|
|
27
|
+
Limit: "\u7ED3\u679C\u6570\u91CF",
|
|
28
|
+
"Enable cache": "\u542F\u7528\u7F13\u5B58",
|
|
29
|
+
"TTL (second)": "\u7F13\u5B58\u65F6\u95F4 (\u79D2)",
|
|
30
|
+
Field: "\u5B57\u6BB5",
|
|
31
|
+
Aggregation: "\u805A\u5408",
|
|
32
|
+
Alias: "\u522B\u540D",
|
|
33
|
+
Format: "\u683C\u5F0F",
|
|
34
|
+
"The first 10 records of the query result:": "\u67E5\u8BE2\u7ED3\u679C\u7684\u524D 10 \u6761\u8BB0\u5F55\uFF1A",
|
|
35
|
+
"Please run query to retrive data.": "\u8BF7\u6267\u884C\u67E5\u8BE2\u6765\u83B7\u53D6\u6570\u636E\u3002",
|
|
36
|
+
Type: "\u7C7B\u578B",
|
|
37
|
+
"Add field": "\u6DFB\u52A0\u5B57\u6BB5",
|
|
38
|
+
"Add chart": "\u6DFB\u52A0\u56FE\u8868",
|
|
39
|
+
xField: "x\u8F74\u5B57\u6BB5",
|
|
40
|
+
yField: "y\u8F74\u5B57\u6BB5",
|
|
41
|
+
seriesField: "\u5206\u7C7B\u5B57\u6BB5",
|
|
42
|
+
angleField: "\u89D2\u5EA6\u5B57\u6BB5",
|
|
43
|
+
colorField: "\u989C\u8272\u5B57\u6BB5",
|
|
44
|
+
"Line Chart": "\u6298\u7EBF\u56FE",
|
|
45
|
+
"Area Chart": "\u9762\u79EF\u56FE",
|
|
46
|
+
"Column Chart": "\u67F1\u72B6\u56FE",
|
|
47
|
+
"Bar Chart": "\u6761\u5F62\u56FE",
|
|
48
|
+
"Pie Chart": "\u997C\u56FE",
|
|
49
|
+
"Dual Axes Chart": "\u53CC\u8F74\u56FE",
|
|
50
|
+
"Scatter Chart": "\u6563\u70B9\u56FE",
|
|
51
|
+
"Gauge Chart": "\u4EEA\u8868\u76D8",
|
|
52
|
+
Statistic: "\u7EDF\u8BA1",
|
|
53
|
+
Currency: "\u8D27\u5E01",
|
|
54
|
+
Percent: "\u767E\u5206\u6BD4",
|
|
55
|
+
Exponential: "\u79D1\u5B66\u8BB0\u6570\u6CD5",
|
|
56
|
+
Abbreviation: "\u7F29\u5199",
|
|
57
|
+
"Please configure and run query": "\u8BF7\u914D\u7F6E\u5E76\u6267\u884C\u6570\u636E\u67E5\u8BE2",
|
|
58
|
+
"Please configure chart": "\u8BF7\u914D\u7F6E\u56FE\u8868",
|
|
59
|
+
"Are you sure to cancel?": "\u786E\u5B9A\u8981\u53D6\u6D88\u5417\uFF1F",
|
|
60
|
+
"You changes are not saved. If you click OK, your changes will be lost.": "\u60A8\u7684\u66F4\u6539\u5C1A\u672A\u4FDD\u5B58\u3002\u5982\u679C\u60A8\u70B9\u51FB\u201C\u786E\u5B9A\u201D\uFF0C\u60A8\u7684\u66F4\u6539\u5C06\u4E22\u5931\u3002",
|
|
61
|
+
"Same properties set in the form above will be overwritten by this JSON config.": "\u4E0A\u9762\u8868\u5355\u4E2D\u8BBE\u7F6E\u7684\u76F8\u540C\u5C5E\u6027\u5C06\u88ABJSON\u914D\u7F6E\u8986\u76D6\u3002",
|
|
62
|
+
"Built-in": "\u5185\u7F6E\u56FE\u8868",
|
|
63
|
+
"Config reference: ": "\u914D\u7F6E\u53C2\u8003: ",
|
|
64
|
+
Table: "\u8868\u683C",
|
|
65
|
+
Sum: "\u6C42\u548C",
|
|
66
|
+
Avg: "\u5E73\u5747\u503C",
|
|
67
|
+
Count: "\u8BA1\u6570",
|
|
68
|
+
Min: "\u6700\u5C0F\u503C",
|
|
69
|
+
Max: "\u6700\u5927\u503C",
|
|
70
|
+
"Please select a chart type.": "\u8BF7\u9009\u62E9\u56FE\u8868\u7C7B\u578B",
|
|
71
|
+
Collection: "\u6570\u636E\u8868"
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
module.exports = zh_CN_default;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const dateFormatFn = (sequelize, dialect, field, format) => {
|
|
4
|
+
switch (dialect) {
|
|
5
|
+
case "sqlite":
|
|
6
|
+
format = format.replace(/YYYY/g, "%Y").replace(/MM/g, "%m").replace(/DD/g, "%d").replace(/hh/g, "%H").replace(/mm/g, "%M").replace(/ss/g, "%S");
|
|
7
|
+
return sequelize.fn("strftime", format, sequelize.col(field));
|
|
8
|
+
case "mysql":
|
|
9
|
+
format = format.replace(/YYYY/g, "%Y").replace(/MM/g, "%m").replace(/DD/g, "%d").replace(/hh/g, "%H").replace(/mm/g, "%i").replace(/ss/g, "%S");
|
|
10
|
+
return sequelize.fn("date_format", sequelize.col(field), format);
|
|
11
|
+
case "postgres":
|
|
12
|
+
format = format.replace(/hh/g, "HH24").replace(/mm/g, "MI").replace(/ss/g, "SS");
|
|
13
|
+
return sequelize.fn("to_char", sequelize.col(field), format);
|
|
14
|
+
default:
|
|
15
|
+
return field;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const formatFn = (sequelize, dialect, field, format) => {
|
|
19
|
+
switch (dialect) {
|
|
20
|
+
case "sqlite":
|
|
21
|
+
case "postgres":
|
|
22
|
+
return sequelize.fn("format", format, sequelize.col(field));
|
|
23
|
+
default:
|
|
24
|
+
return field;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const formatter = (sequelize, type, field, format) => {
|
|
28
|
+
const dialect = sequelize.getDialect();
|
|
29
|
+
switch (type) {
|
|
30
|
+
case "date":
|
|
31
|
+
case "datetime":
|
|
32
|
+
case "time":
|
|
33
|
+
return dateFormatFn(sequelize, dialect, field, format);
|
|
34
|
+
default:
|
|
35
|
+
return formatFn(sequelize, dialect, field, format);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
exports.dateFormatFn = dateFormatFn;
|
|
40
|
+
exports.formatFn = formatFn;
|
|
41
|
+
exports.formatter = formatter;
|
|
@@ -1,62 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
import { Cache } from '@nocobase/cache';
|
|
3
|
-
import { Field, FilterParser, snakeCase } from '@nocobase/database';
|
|
4
|
-
import ChartsV2Plugin from '../plugin';
|
|
5
|
-
import { formatter } from './formatter';
|
|
1
|
+
'use strict';
|
|
6
2
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
type?: string;
|
|
10
|
-
aggregation?: string;
|
|
11
|
-
alias?: string;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
type DimensionProps = {
|
|
15
|
-
field: string | string[];
|
|
16
|
-
type?: string;
|
|
17
|
-
alias?: string;
|
|
18
|
-
format?: string;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
type OrderProps = {
|
|
22
|
-
field: string | string[];
|
|
23
|
-
alias?: string;
|
|
24
|
-
order?: 'asc' | 'desc';
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
type QueryParams = Partial<{
|
|
28
|
-
uid: string;
|
|
29
|
-
collection: string;
|
|
30
|
-
measures: MeasureProps[];
|
|
31
|
-
dimensions: DimensionProps[];
|
|
32
|
-
orders: OrderProps[];
|
|
33
|
-
filter: any;
|
|
34
|
-
limit: number;
|
|
35
|
-
sql: {
|
|
36
|
-
fields?: string;
|
|
37
|
-
clauses?: string;
|
|
38
|
-
};
|
|
39
|
-
cache: {
|
|
40
|
-
enabled: boolean;
|
|
41
|
-
ttl: number;
|
|
42
|
-
};
|
|
43
|
-
// Get the latest data from the database
|
|
44
|
-
refresh: boolean;
|
|
45
|
-
}>;
|
|
3
|
+
var database = require('@nocobase/database');
|
|
4
|
+
var formatter = require('./formatter');
|
|
46
5
|
|
|
47
|
-
|
|
6
|
+
const parseFieldAndAssociations = (ctx, params) => {
|
|
48
7
|
const { collection: collectionName, measures, dimensions, orders, filter } = params;
|
|
49
8
|
const collection = ctx.db.getCollection(collectionName);
|
|
50
9
|
const fields = collection.fields;
|
|
51
10
|
const underscored = ctx.db.options.underscored;
|
|
52
|
-
const models
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const parseField = (selected: { field: string | string[]; alias?: string }) => {
|
|
58
|
-
let target: string;
|
|
59
|
-
let name: string;
|
|
11
|
+
const models = {};
|
|
12
|
+
const parseField = (selected) => {
|
|
13
|
+
var _a, _b, _c;
|
|
14
|
+
let target;
|
|
15
|
+
let name;
|
|
60
16
|
if (!Array.isArray(selected.field)) {
|
|
61
17
|
name = selected.field;
|
|
62
18
|
} else if (selected.field.length === 1) {
|
|
@@ -64,16 +20,16 @@ export const parseFieldAndAssociations = (ctx: Context, params: QueryParams) =>
|
|
|
64
20
|
} else if (selected.field.length > 1) {
|
|
65
21
|
[target, name] = selected.field;
|
|
66
22
|
}
|
|
67
|
-
let field = underscored ? snakeCase(name) : name;
|
|
68
|
-
let fieldType = fields.get(name)
|
|
23
|
+
let field = underscored ? database.snakeCase(name) : name;
|
|
24
|
+
let fieldType = (_a = fields.get(name)) == null ? void 0 : _a.type;
|
|
69
25
|
if (target) {
|
|
70
|
-
const targetField = fields.get(target)
|
|
26
|
+
const targetField = fields.get(target);
|
|
71
27
|
const targetCollection = ctx.db.getCollection(targetField.target);
|
|
72
28
|
const targetFields = targetCollection.fields;
|
|
73
|
-
fieldType = targetFields.get(name)
|
|
29
|
+
fieldType = (_b = targetFields.get(name)) == null ? void 0 : _b.type;
|
|
74
30
|
field = `${target}.${field}`;
|
|
75
31
|
name = `${target}.${name}`;
|
|
76
|
-
const targetType = fields.get(target)
|
|
32
|
+
const targetType = (_c = fields.get(target)) == null ? void 0 : _c.type;
|
|
77
33
|
if (!models[target]) {
|
|
78
34
|
models[target] = { type: targetType };
|
|
79
35
|
}
|
|
@@ -85,40 +41,37 @@ export const parseFieldAndAssociations = (ctx: Context, params: QueryParams) =>
|
|
|
85
41
|
field,
|
|
86
42
|
name,
|
|
87
43
|
type: fieldType,
|
|
88
|
-
alias: selected.alias || name
|
|
44
|
+
alias: selected.alias || name
|
|
89
45
|
};
|
|
90
46
|
};
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
const parsedOrders = orders?.map(parseField) || [];
|
|
47
|
+
const parsedMeasures = (measures == null ? void 0 : measures.map(parseField)) || [];
|
|
48
|
+
const parsedDimensions = (dimensions == null ? void 0 : dimensions.map(parseField)) || [];
|
|
49
|
+
const parsedOrders = (orders == null ? void 0 : orders.map(parseField)) || [];
|
|
95
50
|
const include = Object.entries(models).map(([target, { type }]) => ({
|
|
96
51
|
association: target,
|
|
97
52
|
attributes: [],
|
|
98
|
-
...
|
|
53
|
+
...type === "belongsToMany" ? { through: { attributes: [] } } : {}
|
|
99
54
|
}));
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
collection,
|
|
55
|
+
const filterParser = new database.FilterParser(filter, {
|
|
56
|
+
collection
|
|
103
57
|
});
|
|
104
58
|
const { where, include: filterInclude } = filterParser.toSequelizeParams();
|
|
105
|
-
const parsedFilterInclude = filterInclude
|
|
106
|
-
|
|
59
|
+
const parsedFilterInclude = filterInclude == null ? void 0 : filterInclude.map((item) => {
|
|
60
|
+
var _a;
|
|
61
|
+
if (((_a = fields.get(item.association)) == null ? void 0 : _a.type) === "belongsToMany") {
|
|
107
62
|
item.through = { attributes: [] };
|
|
108
63
|
}
|
|
109
64
|
return item;
|
|
110
65
|
});
|
|
111
|
-
|
|
112
66
|
return {
|
|
113
67
|
where,
|
|
114
68
|
measures: parsedMeasures,
|
|
115
69
|
dimensions: parsedDimensions,
|
|
116
70
|
orders: parsedOrders,
|
|
117
|
-
include: [...include, ...
|
|
71
|
+
include: [...include, ...parsedFilterInclude || []]
|
|
118
72
|
};
|
|
119
73
|
};
|
|
120
|
-
|
|
121
|
-
export const parseBuilder = (ctx: Context, builder: QueryParams) => {
|
|
74
|
+
const parseBuilder = (ctx, builder) => {
|
|
122
75
|
const { sequelize } = ctx.db;
|
|
123
76
|
const { limit } = builder;
|
|
124
77
|
const { measures, dimensions, orders, include, where } = parseFieldAndAssociations(ctx, builder);
|
|
@@ -127,8 +80,7 @@ export const parseBuilder = (ctx: Context, builder: QueryParams) => {
|
|
|
127
80
|
const order = [];
|
|
128
81
|
const fieldMap = {};
|
|
129
82
|
let hasAgg = false;
|
|
130
|
-
|
|
131
|
-
measures.forEach((measure: MeasureProps & { field: string }) => {
|
|
83
|
+
measures.forEach((measure) => {
|
|
132
84
|
const { field, aggregation, alias } = measure;
|
|
133
85
|
const attribute = [];
|
|
134
86
|
const col = sequelize.col(field);
|
|
@@ -144,13 +96,12 @@ export const parseBuilder = (ctx: Context, builder: QueryParams) => {
|
|
|
144
96
|
attributes.push(attribute.length > 1 ? attribute : attribute[0]);
|
|
145
97
|
fieldMap[alias || field] = measure;
|
|
146
98
|
});
|
|
147
|
-
|
|
148
|
-
dimensions.forEach((dimension: DimensionProps & { field: string }) => {
|
|
99
|
+
dimensions.forEach((dimension) => {
|
|
149
100
|
const { field, format, alias, type } = dimension;
|
|
150
101
|
const attribute = [];
|
|
151
102
|
const col = sequelize.col(field);
|
|
152
103
|
if (format) {
|
|
153
|
-
attribute.push(formatter(sequelize, type, field, format));
|
|
104
|
+
attribute.push(formatter.formatter(sequelize, type, field, format));
|
|
154
105
|
} else {
|
|
155
106
|
attribute.push(col);
|
|
156
107
|
}
|
|
@@ -163,13 +114,11 @@ export const parseBuilder = (ctx: Context, builder: QueryParams) => {
|
|
|
163
114
|
}
|
|
164
115
|
fieldMap[alias || field] = dimension;
|
|
165
116
|
});
|
|
166
|
-
|
|
167
|
-
orders.forEach((item: OrderProps) => {
|
|
117
|
+
orders.forEach((item) => {
|
|
168
118
|
const alias = sequelize.getQueryInterface().quoteIdentifier(item.alias);
|
|
169
|
-
const name = hasAgg ? sequelize.literal(alias) : sequelize.col(item.field
|
|
170
|
-
order.push([name, item.order ||
|
|
119
|
+
const name = hasAgg ? sequelize.literal(alias) : sequelize.col(item.field);
|
|
120
|
+
order.push([name, item.order || "ASC"]);
|
|
171
121
|
});
|
|
172
|
-
|
|
173
122
|
return {
|
|
174
123
|
queryParams: {
|
|
175
124
|
where,
|
|
@@ -177,28 +126,26 @@ export const parseBuilder = (ctx: Context, builder: QueryParams) => {
|
|
|
177
126
|
include,
|
|
178
127
|
group,
|
|
179
128
|
order,
|
|
180
|
-
limit: limit >
|
|
181
|
-
raw: true
|
|
129
|
+
limit: limit > 2e3 ? 2e3 : limit,
|
|
130
|
+
raw: true
|
|
182
131
|
},
|
|
183
|
-
fieldMap
|
|
132
|
+
fieldMap
|
|
184
133
|
};
|
|
185
134
|
};
|
|
186
|
-
|
|
187
|
-
export const processData = (ctx: Context, data: any[], fieldMap: { [source: string]: { type?: string } }) => {
|
|
135
|
+
const processData = (ctx, data, fieldMap) => {
|
|
188
136
|
const { sequelize } = ctx.db;
|
|
189
137
|
const dialect = sequelize.getDialect();
|
|
190
138
|
switch (dialect) {
|
|
191
|
-
case
|
|
192
|
-
// https://github.com/sequelize/sequelize/issues/4550
|
|
139
|
+
case "postgres":
|
|
193
140
|
return data.map((record) => {
|
|
194
141
|
const result = {};
|
|
195
142
|
Object.entries(record).forEach(([key, value]) => {
|
|
196
143
|
const { type } = fieldMap[key] || {};
|
|
197
144
|
switch (type) {
|
|
198
|
-
case
|
|
199
|
-
case
|
|
200
|
-
case
|
|
201
|
-
case
|
|
145
|
+
case "bigInt":
|
|
146
|
+
case "integer":
|
|
147
|
+
case "float":
|
|
148
|
+
case "double":
|
|
202
149
|
value = Number(value);
|
|
203
150
|
break;
|
|
204
151
|
}
|
|
@@ -210,37 +157,19 @@ export const processData = (ctx: Context, data: any[], fieldMap: { [source: stri
|
|
|
210
157
|
return data;
|
|
211
158
|
}
|
|
212
159
|
};
|
|
213
|
-
|
|
214
|
-
export const queryData = async (ctx: Context, builder: QueryParams) => {
|
|
160
|
+
const queryData = async (ctx, builder) => {
|
|
215
161
|
const { collection, measures, dimensions, orders, filter, limit, sql } = builder;
|
|
216
162
|
const model = ctx.db.getModel(collection);
|
|
217
163
|
const { queryParams, fieldMap } = parseBuilder(ctx, { collection, measures, dimensions, orders, filter, limit });
|
|
218
164
|
const data = await model.findAll(queryParams);
|
|
219
165
|
return processData(ctx, data, fieldMap);
|
|
220
|
-
// if (!sql) {
|
|
221
|
-
// return await repository.find(parseBuilder(ctx, { collection, measures, dimensions, orders, filter, limit }));
|
|
222
|
-
// }
|
|
223
|
-
|
|
224
|
-
// const statement = `SELECT ${sql.fields} FROM ${collection} ${sql.clauses}`;
|
|
225
|
-
// const [data] = await ctx.db.sequelize.query(statement);
|
|
226
|
-
// return data;
|
|
227
166
|
};
|
|
228
|
-
|
|
229
|
-
export const cacheWrap = async (
|
|
230
|
-
cache: Cache,
|
|
231
|
-
options: {
|
|
232
|
-
func: () => Promise<any>;
|
|
233
|
-
key: string;
|
|
234
|
-
ttl?: number;
|
|
235
|
-
useCache?: boolean;
|
|
236
|
-
refresh?: boolean;
|
|
237
|
-
},
|
|
238
|
-
) => {
|
|
167
|
+
const cacheWrap = async (cache, options) => {
|
|
239
168
|
const { func, key, ttl, useCache, refresh } = options;
|
|
240
169
|
if (useCache && !refresh) {
|
|
241
|
-
const
|
|
242
|
-
if (
|
|
243
|
-
return
|
|
170
|
+
const data2 = await cache.get(key);
|
|
171
|
+
if (data2) {
|
|
172
|
+
return data2;
|
|
244
173
|
}
|
|
245
174
|
}
|
|
246
175
|
const data = await func();
|
|
@@ -249,32 +178,45 @@ export const cacheWrap = async (
|
|
|
249
178
|
}
|
|
250
179
|
return data;
|
|
251
180
|
};
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
181
|
+
const query = async (ctx, next) => {
|
|
182
|
+
const {
|
|
183
|
+
uid,
|
|
184
|
+
collection,
|
|
185
|
+
measures,
|
|
186
|
+
dimensions,
|
|
187
|
+
orders,
|
|
188
|
+
filter,
|
|
189
|
+
limit,
|
|
190
|
+
sql,
|
|
191
|
+
cache: cacheConfig,
|
|
192
|
+
refresh
|
|
193
|
+
} = ctx.action.params.values;
|
|
194
|
+
const roleName = ctx.state.currentRole || "anonymous";
|
|
195
|
+
const can = ctx.app.acl.can({ role: roleName, resource: collection, action: "list" });
|
|
196
|
+
if (!can && roleName !== "root") {
|
|
197
|
+
ctx.throw(403, "No permissions");
|
|
260
198
|
}
|
|
261
|
-
|
|
262
|
-
const plugin = ctx.app.getPlugin('data-visualization') as ChartsV2Plugin;
|
|
199
|
+
const plugin = ctx.app.getPlugin("data-visualization");
|
|
263
200
|
const cache = plugin.cache;
|
|
264
|
-
const useCache = cacheConfig
|
|
265
|
-
|
|
201
|
+
const useCache = (cacheConfig == null ? void 0 : cacheConfig.enabled) && uid;
|
|
266
202
|
try {
|
|
267
203
|
ctx.body = await cacheWrap(cache, {
|
|
268
204
|
func: async () => await queryData(ctx, { collection, measures, dimensions, orders, filter, limit, sql }),
|
|
269
205
|
key: uid,
|
|
270
|
-
ttl: cacheConfig
|
|
206
|
+
ttl: (cacheConfig == null ? void 0 : cacheConfig.ttl) || 30,
|
|
271
207
|
useCache: useCache ? true : false,
|
|
272
|
-
refresh
|
|
208
|
+
refresh
|
|
273
209
|
});
|
|
274
210
|
} catch (err) {
|
|
275
|
-
ctx.app.logger.error(
|
|
211
|
+
ctx.app.logger.error("charts query: ", err);
|
|
276
212
|
ctx.throw(500, err);
|
|
277
213
|
}
|
|
278
|
-
|
|
279
214
|
await next();
|
|
280
215
|
};
|
|
216
|
+
|
|
217
|
+
exports.cacheWrap = cacheWrap;
|
|
218
|
+
exports.parseBuilder = parseBuilder;
|
|
219
|
+
exports.parseFieldAndAssociations = parseFieldAndAssociations;
|
|
220
|
+
exports.processData = processData;
|
|
221
|
+
exports.query = query;
|
|
222
|
+
exports.queryData = queryData;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var cache = require('@nocobase/cache');
|
|
6
|
+
var server = require('@nocobase/server');
|
|
7
|
+
var query = require('./actions/query');
|
|
8
|
+
|
|
9
|
+
class DataVisualizationPlugin extends server.Plugin {
|
|
10
|
+
cache;
|
|
11
|
+
afterAdd() {
|
|
12
|
+
}
|
|
13
|
+
beforeLoad() {
|
|
14
|
+
this.app.resource({
|
|
15
|
+
name: "charts",
|
|
16
|
+
actions: {
|
|
17
|
+
query: query.query
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
this.app.acl.allow("charts", "query", "loggedIn");
|
|
21
|
+
}
|
|
22
|
+
async load() {
|
|
23
|
+
this.cache = cache.createCache({
|
|
24
|
+
ttl: 30,
|
|
25
|
+
// seconds
|
|
26
|
+
max: 1e3,
|
|
27
|
+
store: "memory"
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
async install(options) {
|
|
31
|
+
}
|
|
32
|
+
async afterEnable() {
|
|
33
|
+
}
|
|
34
|
+
async afterDisable() {
|
|
35
|
+
}
|
|
36
|
+
async remove() {
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
var plugin_default = DataVisualizationPlugin;
|
|
40
|
+
|
|
41
|
+
exports.DataVisualizationPlugin = DataVisualizationPlugin;
|
|
42
|
+
exports.default = plugin_default;
|