@nocobase/plugin-charts 0.9.1-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.
Files changed (139) hide show
  1. package/client.d.ts +4 -0
  2. package/client.js +30 -0
  3. package/lib/client/ChartBlockEngine.d.ts +27 -0
  4. package/lib/client/ChartBlockEngine.js +201 -0
  5. package/lib/client/ChartBlockEngineDesigner.d.ts +3 -0
  6. package/lib/client/ChartBlockEngineDesigner.js +348 -0
  7. package/lib/client/ChartBlockInitializer.d.ts +3 -0
  8. package/lib/client/ChartBlockInitializer.js +324 -0
  9. package/lib/client/ChartQueryBlockInitializer.d.ts +9 -0
  10. package/lib/client/ChartQueryBlockInitializer.js +230 -0
  11. package/lib/client/ChartQueryMetadataProvider.d.ts +10 -0
  12. package/lib/client/ChartQueryMetadataProvider.js +118 -0
  13. package/lib/client/DataSetPreviewTable.d.ts +5 -0
  14. package/lib/client/DataSetPreviewTable.js +127 -0
  15. package/lib/client/Icons.d.ts +1 -0
  16. package/lib/client/Icons.js +226 -0
  17. package/lib/client/chartRenderComponents/index.d.ts +2 -0
  18. package/lib/client/chartRenderComponents/index.js +26 -0
  19. package/lib/client/hooks/index.d.ts +4 -0
  20. package/lib/client/hooks/index.js +52 -0
  21. package/lib/client/index.d.ts +4 -0
  22. package/lib/client/index.js +161 -0
  23. package/lib/client/locale/en-US.d.ts +23 -0
  24. package/lib/client/locale/en-US.js +29 -0
  25. package/lib/client/locale/index.d.ts +3 -0
  26. package/lib/client/locale/index.js +46 -0
  27. package/lib/client/locale/ja-JP.d.ts +2 -0
  28. package/lib/client/locale/ja-JP.js +8 -0
  29. package/lib/client/locale/ru-RU.d.ts +2 -0
  30. package/lib/client/locale/ru-RU.js +8 -0
  31. package/lib/client/locale/tr-TR.d.ts +2 -0
  32. package/lib/client/locale/tr-TR.js +8 -0
  33. package/lib/client/locale/zh-CN.d.ts +61 -0
  34. package/lib/client/locale/zh-CN.js +67 -0
  35. package/lib/client/select/CustomSelect.d.ts +11 -0
  36. package/lib/client/select/CustomSelect.js +193 -0
  37. package/lib/client/select/ReadPretty.d.ts +2 -0
  38. package/lib/client/select/ReadPretty.js +102 -0
  39. package/lib/client/select/index.d.ts +2 -0
  40. package/lib/client/select/index.js +31 -0
  41. package/lib/client/select/shared.d.ts +7 -0
  42. package/lib/client/select/shared.js +86 -0
  43. package/lib/client/settings/AddNewQuery.d.ts +2 -0
  44. package/lib/client/settings/AddNewQuery.js +321 -0
  45. package/lib/client/settings/ConfigureFields.d.ts +1 -0
  46. package/lib/client/settings/ConfigureFields.js +51 -0
  47. package/lib/client/settings/QueriesTable.d.ts +1 -0
  48. package/lib/client/settings/QueriesTable.js +108 -0
  49. package/lib/client/settings/queryTypes.d.ts +5 -0
  50. package/lib/client/settings/queryTypes.js +85 -0
  51. package/lib/client/settings/schemas/chartsQueries.d.ts +8 -0
  52. package/lib/client/settings/schemas/chartsQueries.js +378 -0
  53. package/lib/client/templates/AreaTemplate.d.ts +65 -0
  54. package/lib/client/templates/AreaTemplate.js +86 -0
  55. package/lib/client/templates/BarTemplate.d.ts +80 -0
  56. package/lib/client/templates/BarTemplate.js +103 -0
  57. package/lib/client/templates/ColumnTemplate.d.ts +80 -0
  58. package/lib/client/templates/ColumnTemplate.js +103 -0
  59. package/lib/client/templates/FunnelTemplate.d.ts +66 -0
  60. package/lib/client/templates/FunnelTemplate.js +87 -0
  61. package/lib/client/templates/LineTemplate.d.ts +67 -0
  62. package/lib/client/templates/LineTemplate.js +92 -0
  63. package/lib/client/templates/PieTemplate.d.ts +71 -0
  64. package/lib/client/templates/PieTemplate.js +92 -0
  65. package/lib/client/templates/RadarTemplate.d.ts +71 -0
  66. package/lib/client/templates/RadarTemplate.js +93 -0
  67. package/lib/client/templates/ScatterTemplate.d.ts +91 -0
  68. package/lib/client/templates/ScatterTemplate.js +112 -0
  69. package/lib/client/templates/TableTemplate.d.ts +28 -0
  70. package/lib/client/templates/TableTemplate.js +54 -0
  71. package/lib/client/templates/index.d.ts +1 -0
  72. package/lib/client/templates/index.js +33 -0
  73. package/lib/client/utils.d.ts +3 -0
  74. package/lib/client/utils.js +66 -0
  75. package/lib/index.d.ts +1 -0
  76. package/lib/index.js +15 -0
  77. package/lib/server/actions/chartsQueries.d.ts +3 -0
  78. package/lib/server/actions/chartsQueries.js +104 -0
  79. package/lib/server/actions/index.d.ts +1 -0
  80. package/lib/server/actions/index.js +1 -0
  81. package/lib/server/collections/chartsQueries.d.ts +2 -0
  82. package/lib/server/collections/chartsQueries.js +36 -0
  83. package/lib/server/index.d.ts +1 -0
  84. package/lib/server/index.js +15 -0
  85. package/lib/server/plugin.d.ts +14 -0
  86. package/lib/server/plugin.js +142 -0
  87. package/lib/server/query.d.ts +12 -0
  88. package/lib/server/query.js +91 -0
  89. package/lib/server/shared/index.d.ts +2 -0
  90. package/lib/server/shared/index.js +8 -0
  91. package/package.json +14 -0
  92. package/server.d.ts +4 -0
  93. package/server.js +30 -0
  94. package/src/client/ChartBlockEngine.tsx +120 -0
  95. package/src/client/ChartBlockEngineDesigner.tsx +238 -0
  96. package/src/client/ChartBlockInitializer.tsx +216 -0
  97. package/src/client/ChartQueryBlockInitializer.tsx +136 -0
  98. package/src/client/ChartQueryMetadataProvider.tsx +62 -0
  99. package/src/client/DataSetPreviewTable.tsx +73 -0
  100. package/src/client/Icons.tsx +99 -0
  101. package/src/client/chartRenderComponents/index.ts +7 -0
  102. package/src/client/hooks/index.ts +19 -0
  103. package/src/client/index.tsx +101 -0
  104. package/src/client/locale/en-US.ts +23 -0
  105. package/src/client/locale/index.ts +18 -0
  106. package/src/client/locale/ja-JP.ts +1 -0
  107. package/src/client/locale/ru-RU.ts +1 -0
  108. package/src/client/locale/tr-TR.ts +1 -0
  109. package/src/client/locale/zh-CN.ts +63 -0
  110. package/src/client/select/CustomSelect.tsx +127 -0
  111. package/src/client/select/ReadPretty.tsx +36 -0
  112. package/src/client/select/index.md +38 -0
  113. package/src/client/select/index.ts +2 -0
  114. package/src/client/select/shared.ts +36 -0
  115. package/src/client/settings/AddNewQuery.tsx +161 -0
  116. package/src/client/settings/ConfigureFields.tsx +18 -0
  117. package/src/client/settings/QueriesTable.tsx +26 -0
  118. package/src/client/settings/queryTypes.ts +64 -0
  119. package/src/client/settings/schemas/chartsQueries.ts +319 -0
  120. package/src/client/templates/AreaTemplate.tsx +64 -0
  121. package/src/client/templates/BarTemplate.tsx +80 -0
  122. package/src/client/templates/ColumnTemplate.tsx +81 -0
  123. package/src/client/templates/FunnelTemplate.tsx +65 -0
  124. package/src/client/templates/LineTemplate.tsx +72 -0
  125. package/src/client/templates/PieTemplate.tsx +68 -0
  126. package/src/client/templates/RadarTemplate.tsx +71 -0
  127. package/src/client/templates/ScatterTemplate.tsx +90 -0
  128. package/src/client/templates/TableTemplate.tsx +48 -0
  129. package/src/client/templates/index.ts +21 -0
  130. package/src/client/utils.ts +39 -0
  131. package/src/index.ts +1 -0
  132. package/src/server/actions/chartsQueries.ts +44 -0
  133. package/src/server/actions/index.ts +0 -0
  134. package/src/server/collections/.gitkeep +0 -0
  135. package/src/server/collections/chartsQueries.ts +24 -0
  136. package/src/server/index.ts +1 -0
  137. package/src/server/plugin.ts +61 -0
  138. package/src/server/query.ts +39 -0
  139. package/src/server/shared/index.ts +2 -0
@@ -0,0 +1,68 @@
1
+ import JSON5 from 'json5';
2
+
3
+ const chartConfig = {
4
+ appendPadding: 10,
5
+ angleField: '{{metric}}',
6
+ colorField: '{{dimension}}',
7
+ radius: 0.9,
8
+ label: {
9
+ type: 'inner',
10
+ offset: '-30%',
11
+ content: '{{({percent}) => `${(percent * 100).toFixed(0)}%`}}',
12
+ style: {
13
+ fontSize: 14,
14
+ textAlign: 'center',
15
+ },
16
+ },
17
+ interactions: [{ type: 'element-active' }],
18
+ };
19
+
20
+ export const pieTemplate = {
21
+ description: '1 「Time」 or 「Order Noun」 field, 1 「Value」 field',
22
+ title: 'Pie',
23
+ type: 'Pie',
24
+ iconId: 'icon-pie',
25
+ group: 2,
26
+ renderComponent: 'G2Plot',
27
+ defaultChartOptions: chartConfig,
28
+ configurableProperties: {
29
+ type: 'void',
30
+ properties: {
31
+ dimension: {
32
+ required: true,
33
+ type: 'string',
34
+ title: '{{t("Sector label / Dimensional",{ns:"charts"})}}',
35
+ 'x-decorator': 'FormItem',
36
+ 'x-component': 'Select',
37
+ enum: '{{dataSource}}',
38
+ },
39
+ metric: {
40
+ required: true,
41
+ type: 'string',
42
+ title: '{{t("Sector Angle / Metric",{ns:"charts"})}}',
43
+ 'x-decorator': 'FormItem',
44
+ 'x-component': 'Select',
45
+ enum: '{{dataSource}}',
46
+ },
47
+ jsonConfig: {
48
+ type: 'void',
49
+ 'x-component': 'div',
50
+ properties: {
51
+ template: {
52
+ required: true,
53
+ title: '{{t("JSON config",{ns:"charts"})}}',
54
+ type: 'string',
55
+ default: JSON5.stringify(chartConfig, null, 2),
56
+ 'x-decorator': 'FormItem',
57
+ 'x-component': 'Input.TextArea',
58
+ 'x-component-props': {
59
+ autoSize: { minRows: 8, maxRows: 16 },
60
+ },
61
+ description: '{{jsonConfigDesc("Pie | G2Plot","https://g2plot.antv.antgroup.com/api/plots/pie")}}',
62
+ 'x-validator': { json5: true },
63
+ },
64
+ },
65
+ },
66
+ },
67
+ },
68
+ };
@@ -0,0 +1,71 @@
1
+ import JSON5 from 'json5';
2
+
3
+ const chartConfig = {
4
+ xField: '{{dimension}}',
5
+ yField: '{{metric}}',
6
+ appendPadding: [0, 10, 0, 10],
7
+ xAxis: {
8
+ tickLine: null,
9
+ },
10
+ yAxis: {
11
+ label: false,
12
+ grid: {
13
+ alternateColor: 'rgba(0, 0, 0, 0.04)',
14
+ },
15
+ },
16
+ // 开启辅助点
17
+ point: {
18
+ size: 2,
19
+ },
20
+ area: {},
21
+ };
22
+
23
+ export const radarTemplate = {
24
+ description: '1~ 2 「Unordered Noun」 fields, 1 「Numeric」 field',
25
+ type: 'Radar',
26
+ title: 'Radar',
27
+ iconId: 'icon-radar',
28
+ group: 1,
29
+ renderComponent: 'G2Plot',
30
+ defaultChartOptions: chartConfig,
31
+ configurableProperties: {
32
+ type: 'void',
33
+ properties: {
34
+ dimension: {
35
+ required: true,
36
+ type: 'string',
37
+ title: '{{t("Branch Tags/Dimensions",{ns:"charts"})}}',
38
+ 'x-decorator': 'FormItem',
39
+ 'x-component': 'Select',
40
+ enum: '{{dataSource}}',
41
+ },
42
+ metric: {
43
+ required: true,
44
+ type: 'string',
45
+ title: '{{t("Branch Length/Metrics",{ns:"charts"})}}',
46
+ 'x-decorator': 'FormItem',
47
+ 'x-component': 'Select',
48
+ enum: '{{dataSource}}',
49
+ },
50
+ jsonConfig: {
51
+ type: 'void',
52
+ 'x-component': 'div',
53
+ properties: {
54
+ template: {
55
+ required: true,
56
+ title: '{{t("JSON config",{ns:"charts"})}}',
57
+ type: 'string',
58
+ default: JSON5.stringify(chartConfig, null, 2),
59
+ 'x-decorator': 'FormItem',
60
+ 'x-component': 'Input.TextArea',
61
+ 'x-component-props': {
62
+ autoSize: { minRows: 8, maxRows: 16 },
63
+ },
64
+ description: '{{jsonConfigDesc("Radar | G2Plot","https://g2plot.antv.antgroup.com/api/plots/radar")}}',
65
+ 'x-validator': { json5: true },
66
+ },
67
+ },
68
+ },
69
+ },
70
+ },
71
+ };
@@ -0,0 +1,90 @@
1
+ import JSON5 from 'json5';
2
+
3
+ const chartConfig = {
4
+ appendPadding: 10,
5
+ xField: '{{metric}}',
6
+ yField: '{{dimension}}',
7
+ colorField: '{{category}}',
8
+ shape: 'circle',
9
+ size: 4,
10
+ yAxis: {
11
+ nice: true,
12
+ line: {
13
+ style: {
14
+ stroke: '#aaa',
15
+ },
16
+ },
17
+ },
18
+ xAxis: {
19
+ min: -100,
20
+ grid: {
21
+ line: {
22
+ style: {
23
+ stroke: '#eee',
24
+ },
25
+ },
26
+ },
27
+ line: {
28
+ style: {
29
+ stroke: '#aaa',
30
+ },
31
+ },
32
+ },
33
+ };
34
+
35
+ export const scatterTemplate = {
36
+ description: '1 「Numeric」 field, 0~ 1 「Unordered Noun」 field',
37
+ type: 'Scatter',
38
+ title: 'Scatter',
39
+ iconId: 'icon-scatter',
40
+ group: 2,
41
+ renderComponent: 'G2Plot',
42
+ defaultChartOptions: chartConfig,
43
+ configurableProperties: {
44
+ type: 'void',
45
+ properties: {
46
+ dimension: {
47
+ required: true,
48
+ type: 'string',
49
+ title: '{{t("Category axis / Dimension",{ns:"charts"})}}',
50
+ 'x-decorator': 'FormItem',
51
+ 'x-component': 'Select',
52
+ enum: '{{dataSource}}',
53
+ },
54
+ metric: {
55
+ required: true,
56
+ type: 'string',
57
+ title: '{{t("Value axis / Metrics",{ns:"charts"})}}',
58
+ 'x-decorator': 'FormItem',
59
+ 'x-component': 'Select',
60
+ enum: '{{dataSource}}',
61
+ },
62
+ category: {
63
+ type: 'string',
64
+ title: '{{t("Color legend / Dimensional",{ns:"charts"})}}',
65
+ 'x-decorator': 'FormItem',
66
+ 'x-component': 'Select',
67
+ enum: '{{dataSource}}',
68
+ },
69
+ jsonConfig: {
70
+ type: 'void',
71
+ 'x-component': 'div',
72
+ properties: {
73
+ template: {
74
+ required: true,
75
+ title: '{{t("JSON config",{ns:"charts"})}}',
76
+ type: 'string',
77
+ default: JSON5.stringify(chartConfig, null, 2),
78
+ 'x-decorator': 'FormItem',
79
+ 'x-component': 'Input.TextArea',
80
+ 'x-component-props': {
81
+ autoSize: { minRows: 8, maxRows: 16 },
82
+ },
83
+ description: '{{jsonConfigDesc("Scatter | G2Plot","https://g2plot.antv.antgroup.com/api/plots/scatter")}}',
84
+ 'x-validator': { json5: true },
85
+ },
86
+ },
87
+ },
88
+ },
89
+ },
90
+ };
@@ -0,0 +1,48 @@
1
+ import JSON5 from 'json5';
2
+
3
+ const validateJSON = {
4
+ validator: `{{(value, rule)=> {
5
+ if (!value) {
6
+ return '';
7
+ }
8
+ try {
9
+ const val = JSON5.parse(value);
10
+ if(!isNaN(val)) {
11
+ return false;
12
+ }
13
+ return true;
14
+ } catch(error) {
15
+ console.error(error);
16
+ return false;
17
+ }
18
+ }}}`,
19
+ message: '{{t("Invalid JSON format",{ ns: "charts" })}}',
20
+ };
21
+
22
+ const chartConfig = {
23
+ appendPadding: 10,
24
+ angleField: '{{metric}}',
25
+ colorField: '{{dimension}}',
26
+ radius: 0.9,
27
+ label: {
28
+ type: 'inner',
29
+ offset: '-30%',
30
+ content: '{{({percent}) => `${(percent * 100).toFixed(0)}%`}}',
31
+ style: {
32
+ fontSize: 14,
33
+ textAlign: 'center',
34
+ },
35
+ },
36
+ interactions: [{ type: 'element-active' }],
37
+ };
38
+ export const tableTemplate = {
39
+ title: '表格展示',
40
+ type: 'DataSetPreviewTable',
41
+ group: 2,
42
+ renderComponent: 'DataSetPreviewTable',
43
+ defaultChartOptions: chartConfig,
44
+ configurableProperties: {
45
+ type: 'void',
46
+ properties: {},
47
+ },
48
+ };
@@ -0,0 +1,21 @@
1
+ import { pieTemplate } from './PieTemplate';
2
+ import { barTemplate } from './BarTemplate';
3
+ import { columnTemplate } from './ColumnTemplate';
4
+ import { lineTemplate } from './LineTemplate';
5
+ import { areaTemplate } from './AreaTemplate';
6
+ import { tableTemplate } from './TableTemplate';
7
+ import { scatterTemplate } from './ScatterTemplate';
8
+ import { radarTemplate } from './RadarTemplate';
9
+ import { funnelTemplate } from './FunnelTemplate';
10
+
11
+ export const templates = new Map();
12
+
13
+ templates.set('Pie', pieTemplate);
14
+ templates.set('Line', lineTemplate);
15
+ templates.set('Area', areaTemplate);
16
+ templates.set('Bar', barTemplate);
17
+ templates.set('Column', columnTemplate);
18
+ templates.set('Scatter', scatterTemplate);
19
+ templates.set('Radar', radarTemplate);
20
+ templates.set('Funnel', funnelTemplate);
21
+ // templates.set('DataSetPreviewTable', tableTemplate);
@@ -0,0 +1,39 @@
1
+ import JSON5 from 'json5';
2
+ import { uid } from '@formily/shared';
3
+
4
+ const validateArray = (value) => {
5
+ try {
6
+ value = JSON5.parse(value);
7
+ } catch (e) {
8
+ return 'Please input validate dataset';
9
+ }
10
+ if (Array.isArray(value)) {
11
+ if (
12
+ value.every((item) => {
13
+ return typeof item === 'object' && Object.keys(item).length > 1;
14
+ })
15
+ )
16
+ return true;
17
+ }
18
+ return 'Please input validate dataset';
19
+ };
20
+
21
+ const parseDataSetString = (str) => {
22
+ const dataSetDataArray = JSON5.parse(str);
23
+ if (Array.isArray(dataSetDataArray)) {
24
+ if (
25
+ dataSetDataArray.every((item) => {
26
+ return typeof item === 'object' && Object.keys(item).length > 1;
27
+ })
28
+ )
29
+ dataSetDataArray.map((item) => {
30
+ if (!item?.id) {
31
+ item.id = uid();
32
+ }
33
+ return item;
34
+ });
35
+ }
36
+ return dataSetDataArray;
37
+ };
38
+
39
+ export { validateArray, parseDataSetString };
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { default } from './server';
@@ -0,0 +1,44 @@
1
+ import JSON5 from 'json5';
2
+ import { query } from '../query';
3
+
4
+ export const getData = async (ctx, next) => {
5
+ const { filterByTk } = ctx.action.params;
6
+ const r = ctx.db.getRepository('chartsQueries');
7
+ const instance = await r.findOne({ filterByTk });
8
+ const result = await query[instance.type](instance.options, { db: ctx.db, skipError: true });
9
+ if (typeof result === 'string') {
10
+ ctx.body = JSON5.parse(result);
11
+ } else {
12
+ ctx.body = result;
13
+ }
14
+ return next();
15
+ };
16
+
17
+ export const validate = async (ctx, next) => {
18
+ const { values } = ctx.action.params;
19
+ ctx.body = {
20
+ errorMessage: '',
21
+ };
22
+ try {
23
+ await query.sql(values, { db: ctx.db, validateSQL: true });
24
+ } catch (error) {
25
+ ctx.body = {
26
+ errorMessage: error.message,
27
+ };
28
+ }
29
+ return next();
30
+ };
31
+
32
+ export const listMetadata = async (ctx, next) => {
33
+ const r = ctx.db.getRepository('chartsQueries');
34
+ const items = await r.find({ sort: '-id' });
35
+ ctx.body = items.map((item) => {
36
+ return {
37
+ id: item.id,
38
+ title: item.title,
39
+ type: item.type,
40
+ fields: item.fields,
41
+ };
42
+ });
43
+ return next();
44
+ };
File without changes
File without changes
@@ -0,0 +1,24 @@
1
+ import { defineCollection } from '@nocobase/database';
2
+
3
+ export default defineCollection({
4
+ name: 'chartsQueries',
5
+ fields: [
6
+ {
7
+ name: 'title',
8
+ type: 'string',
9
+ },
10
+ {
11
+ name: 'type',
12
+ type: 'string',
13
+ },
14
+ {
15
+ name: 'options',
16
+ type: 'json',
17
+ },
18
+ {
19
+ name: 'fields',
20
+ type: 'json',
21
+ defaultValue: [],
22
+ },
23
+ ],
24
+ });
@@ -0,0 +1 @@
1
+ export { default } from './plugin';
@@ -0,0 +1,61 @@
1
+ import { InstallOptions, Plugin } from '@nocobase/server';
2
+ import JSON5 from 'json5';
3
+ import { resolve } from 'path';
4
+ import { getData, listMetadata, validate } from './actions/chartsQueries';
5
+ import { query } from './query';
6
+
7
+ export class ChartsPlugin extends Plugin {
8
+ syncFields = async (instance, { transaction }) => {
9
+ const _data = await query[instance.type](instance.options, { db: this.db, transaction, validateSQL: true });
10
+ let data;
11
+ if (typeof _data === 'string') {
12
+ data = JSON5.parse(_data);
13
+ } else {
14
+ data = _data;
15
+ }
16
+ const d = Array.isArray(data) ? data?.[0] : data;
17
+ const fields = Object.keys(d || {}).map((f) => {
18
+ return {
19
+ name: f,
20
+ };
21
+ });
22
+ instance.set('fields', fields);
23
+ };
24
+
25
+ afterAdd() {}
26
+
27
+ beforeLoad() {
28
+ this.app.db.on('chartsQueries.beforeCreate', this.syncFields);
29
+ this.app.db.on('chartsQueries.beforeUpdate', this.syncFields);
30
+ }
31
+
32
+ async load() {
33
+ await this.db.import({
34
+ directory: resolve(__dirname, 'collections'),
35
+ });
36
+
37
+ this.app.resourcer.registerActionHandlers({
38
+ 'chartsQueries:getData': getData,
39
+ 'chartsQueries:listMetadata': listMetadata,
40
+ 'chartsQueries:validate': validate,
41
+ });
42
+
43
+ this.app.acl.registerSnippet({
44
+ name: 'pm.charts.queries',
45
+ actions: ['chartsQueries:*'],
46
+ });
47
+
48
+ this.app.acl.allow('chartsQueries', 'getData', 'loggedIn');
49
+ this.app.acl.allow('chartsQueries', 'listMetadata', 'loggedIn');
50
+ }
51
+
52
+ async install(options?: InstallOptions) {}
53
+
54
+ async afterEnable() {}
55
+
56
+ async afterDisable() {}
57
+
58
+ async remove() {}
59
+ }
60
+
61
+ export default ChartsPlugin;
@@ -0,0 +1,39 @@
1
+ import { Database } from '@nocobase/database';
2
+
3
+ export const query = {
4
+ api: async (options) => {
5
+ return [];
6
+ },
7
+ json: async (options) => {
8
+ return options.data || [];
9
+ },
10
+ sql: async (
11
+ options,
12
+ {
13
+ db,
14
+ transaction,
15
+ skipError,
16
+ validateSQL,
17
+ }: { db: Database; transaction?: any; skipError?: boolean; validateSQL?: boolean },
18
+ ) => {
19
+ try {
20
+ // 分号截取,只取第一段
21
+ const sql: string = options.sql.trim().split(';').shift();
22
+ if (!sql) {
23
+ throw new Error('SQL is empty');
24
+ }
25
+ if (!/^select/i.test(sql) && !/^with([\s\S]+)select([\s\S]+)/i.test(sql)) {
26
+ throw new Error('Only select query allowed');
27
+ }
28
+ const [data] = await db.sequelize.query(sql, { transaction });
29
+ return data;
30
+ } catch (error) {
31
+ if (skipError) {
32
+ return [];
33
+ }
34
+ throw error;
35
+ }
36
+ },
37
+ };
38
+
39
+ export default query;
@@ -0,0 +1,2 @@
1
+ const choicesTypeInterfaceArray = ['radioGroup', 'select'];
2
+ export { choicesTypeInterfaceArray };