@nocobase/plugin-data-visualization 0.10.1-alpha.1

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 (108) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +88 -0
  3. package/client.d.ts +3 -0
  4. package/client.js +65 -0
  5. package/lib/client/Settings.d.ts +2 -0
  6. package/lib/client/Settings.js +81 -0
  7. package/lib/client/block/ChartBlock.d.ts +2 -0
  8. package/lib/client/block/ChartBlock.js +73 -0
  9. package/lib/client/block/ChartBlockDesigner.d.ts +2 -0
  10. package/lib/client/block/ChartBlockDesigner.js +35 -0
  11. package/lib/client/block/ChartBlockInitializer.d.ts +6 -0
  12. package/lib/client/block/ChartBlockInitializer.js +114 -0
  13. package/lib/client/block/ChartConfigure.d.ts +33 -0
  14. package/lib/client/block/ChartConfigure.js +501 -0
  15. package/lib/client/block/formatters.d.ts +15 -0
  16. package/lib/client/block/formatters.js +58 -0
  17. package/lib/client/block/index.d.ts +4 -0
  18. package/lib/client/block/index.js +49 -0
  19. package/lib/client/block/schemas/configure.d.ts +4 -0
  20. package/lib/client/block/schemas/configure.js +492 -0
  21. package/lib/client/block/transformers.d.ts +6 -0
  22. package/lib/client/block/transformers.js +69 -0
  23. package/lib/client/hooks.d.ts +312 -0
  24. package/lib/client/hooks.js +275 -0
  25. package/lib/client/index.d.ts +5 -0
  26. package/lib/client/index.js +70 -0
  27. package/lib/client/locale/en-US.d.ts +23 -0
  28. package/lib/client/locale/en-US.js +29 -0
  29. package/lib/client/locale/index.d.ts +3 -0
  30. package/lib/client/locale/index.js +39 -0
  31. package/lib/client/locale/ja-JP.d.ts +2 -0
  32. package/lib/client/locale/ja-JP.js +8 -0
  33. package/lib/client/locale/pt-BR.d.ts +23 -0
  34. package/lib/client/locale/pt-BR.js +29 -0
  35. package/lib/client/locale/ru-RU.d.ts +2 -0
  36. package/lib/client/locale/ru-RU.js +8 -0
  37. package/lib/client/locale/tr-TR.d.ts +2 -0
  38. package/lib/client/locale/tr-TR.js +8 -0
  39. package/lib/client/locale/zh-CN.d.ts +70 -0
  40. package/lib/client/locale/zh-CN.js +76 -0
  41. package/lib/client/renderer/ChartLibrary.d.ts +71 -0
  42. package/lib/client/renderer/ChartLibrary.js +140 -0
  43. package/lib/client/renderer/ChartRenderer.d.ts +7 -0
  44. package/lib/client/renderer/ChartRenderer.js +258 -0
  45. package/lib/client/renderer/ChartRendererProvider.d.ts +43 -0
  46. package/lib/client/renderer/ChartRendererProvider.js +38 -0
  47. package/lib/client/renderer/index.d.ts +4 -0
  48. package/lib/client/renderer/index.js +49 -0
  49. package/lib/client/renderer/library/AntdLibrary.d.ts +2 -0
  50. package/lib/client/renderer/library/AntdLibrary.js +123 -0
  51. package/lib/client/renderer/library/G2PlotLibrary.d.ts +2 -0
  52. package/lib/client/renderer/library/G2PlotLibrary.js +288 -0
  53. package/lib/client/renderer/library/index.d.ts +3 -0
  54. package/lib/client/renderer/library/index.js +15 -0
  55. package/lib/client/utils.d.ts +96 -0
  56. package/lib/client/utils.js +137 -0
  57. package/lib/index.d.ts +1 -0
  58. package/lib/index.js +13 -0
  59. package/lib/server/actions/formatter.d.ts +3 -0
  60. package/lib/server/actions/formatter.js +44 -0
  61. package/lib/server/actions/query.d.ts +86 -0
  62. package/lib/server/actions/query.js +326 -0
  63. package/lib/server/index.d.ts +1 -0
  64. package/lib/server/index.js +13 -0
  65. package/lib/server/plugin.d.ts +13 -0
  66. package/lib/server/plugin.js +64 -0
  67. package/package.json +23 -0
  68. package/server.d.ts +3 -0
  69. package/server.js +65 -0
  70. package/src/client/Settings.tsx +43 -0
  71. package/src/client/__tests__/chart-configure.test.tsx +14 -0
  72. package/src/client/__tests__/chart-library.test.ts +78 -0
  73. package/src/client/__tests__/chart-renderer.test.tsx +30 -0
  74. package/src/client/__tests__/hooks.test.ts +261 -0
  75. package/src/client/block/ChartBlock.tsx +22 -0
  76. package/src/client/block/ChartBlockDesigner.tsx +19 -0
  77. package/src/client/block/ChartBlockInitializer.tsx +83 -0
  78. package/src/client/block/ChartConfigure.tsx +450 -0
  79. package/src/client/block/formatters.ts +70 -0
  80. package/src/client/block/index.ts +4 -0
  81. package/src/client/block/schemas/configure.ts +474 -0
  82. package/src/client/block/transformers.ts +52 -0
  83. package/src/client/hooks.ts +239 -0
  84. package/src/client/index.tsx +41 -0
  85. package/src/client/locale/en-US.ts +23 -0
  86. package/src/client/locale/index.ts +19 -0
  87. package/src/client/locale/ja-JP.ts +1 -0
  88. package/src/client/locale/pt-BR.ts +23 -0
  89. package/src/client/locale/ru-RU.ts +1 -0
  90. package/src/client/locale/tr-TR.ts +1 -0
  91. package/src/client/locale/zh-CN.ts +71 -0
  92. package/src/client/renderer/ChartLibrary.tsx +178 -0
  93. package/src/client/renderer/ChartRenderer.tsx +201 -0
  94. package/src/client/renderer/ChartRendererProvider.tsx +58 -0
  95. package/src/client/renderer/index.ts +4 -0
  96. package/src/client/renderer/library/AntdLibrary.tsx +94 -0
  97. package/src/client/renderer/library/G2PlotLibrary.tsx +236 -0
  98. package/src/client/renderer/library/index.tsx +4 -0
  99. package/src/client/utils.ts +102 -0
  100. package/src/index.ts +1 -0
  101. package/src/server/__tests__/api.test.ts +105 -0
  102. package/src/server/__tests__/formatter.test.ts +49 -0
  103. package/src/server/__tests__/query.test.ts +220 -0
  104. package/src/server/actions/formatter.ts +49 -0
  105. package/src/server/actions/query.ts +285 -0
  106. package/src/server/collections/.gitkeep +0 -0
  107. package/src/server/index.ts +1 -0
  108. package/src/server/plugin.ts +37 -0
@@ -0,0 +1,86 @@
1
+ import { Context, Next } from '@nocobase/actions';
2
+ import { Cache } from '@nocobase/cache';
3
+ declare type MeasureProps = {
4
+ field: string | string[];
5
+ type?: string;
6
+ aggregation?: string;
7
+ alias?: string;
8
+ };
9
+ declare type DimensionProps = {
10
+ field: string | string[];
11
+ type?: string;
12
+ alias?: string;
13
+ format?: string;
14
+ };
15
+ declare type OrderProps = {
16
+ field: string | string[];
17
+ alias?: string;
18
+ order?: 'asc' | 'desc';
19
+ };
20
+ declare type QueryParams = Partial<{
21
+ uid: string;
22
+ collection: string;
23
+ measures: MeasureProps[];
24
+ dimensions: DimensionProps[];
25
+ orders: OrderProps[];
26
+ filter: any;
27
+ limit: number;
28
+ sql: {
29
+ fields?: string;
30
+ clauses?: string;
31
+ };
32
+ cache: {
33
+ enabled: boolean;
34
+ ttl: number;
35
+ };
36
+ refresh: boolean;
37
+ }>;
38
+ export declare const parseFieldAndAssociations: (ctx: Context, params: QueryParams) => {
39
+ where: any;
40
+ measures: {
41
+ field: any;
42
+ name: string;
43
+ type: any;
44
+ alias: string;
45
+ }[];
46
+ dimensions: {
47
+ field: any;
48
+ name: string;
49
+ type: any;
50
+ alias: string;
51
+ }[];
52
+ orders: {
53
+ field: any;
54
+ name: string;
55
+ type: any;
56
+ alias: string;
57
+ }[];
58
+ include: any[];
59
+ };
60
+ export declare const parseBuilder: (ctx: Context, builder: QueryParams) => {
61
+ queryParams: {
62
+ where: any;
63
+ attributes: any[];
64
+ include: any[];
65
+ group: any[];
66
+ order: any[];
67
+ limit: number;
68
+ raw: boolean;
69
+ };
70
+ fieldMap: {};
71
+ };
72
+ export declare const processData: (ctx: Context, data: any[], fieldMap: {
73
+ [source: string]: {
74
+ type?: string;
75
+ };
76
+ }) => any[];
77
+ export declare const queryData: (ctx: Context, builder: QueryParams) => Promise<any[]>;
78
+ export declare const cacheWrap: (cache: Cache, options: {
79
+ func: () => Promise<any>;
80
+ key: string;
81
+ ttl?: number;
82
+ useCache?: boolean;
83
+ refresh?: boolean;
84
+ }) => Promise<any>;
85
+ export declare const query: (ctx: Context, next: Next) => Promise<void>;
86
+ export {};
@@ -0,0 +1,326 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.queryData = exports.query = exports.processData = exports.parseFieldAndAssociations = exports.parseBuilder = exports.cacheWrap = void 0;
7
+ function _database() {
8
+ const data = require("@nocobase/database");
9
+ _database = function _database() {
10
+ return data;
11
+ };
12
+ return data;
13
+ }
14
+ var _formatter = require("./formatter");
15
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
16
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
17
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
18
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
19
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
20
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
21
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
22
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
23
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
24
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
25
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
26
+ function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
27
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
28
+ const parseFieldAndAssociations = (ctx, params) => {
29
+ const collectionName = params.collection,
30
+ measures = params.measures,
31
+ dimensions = params.dimensions,
32
+ orders = params.orders,
33
+ filter = params.filter;
34
+ const collection = ctx.db.getCollection(collectionName);
35
+ const fields = collection.fields;
36
+ const underscored = ctx.db.options.underscored;
37
+ const models = {};
38
+ const parseField = selected => {
39
+ var _fields$get;
40
+ let target;
41
+ let name;
42
+ if (!Array.isArray(selected.field)) {
43
+ name = selected.field;
44
+ } else if (selected.field.length === 1) {
45
+ name = selected.field[0];
46
+ } else if (selected.field.length > 1) {
47
+ var _selected$field = _slicedToArray(selected.field, 2);
48
+ target = _selected$field[0];
49
+ name = _selected$field[1];
50
+ }
51
+ let field = underscored ? (0, _database().snakeCase)(name) : name;
52
+ let type = (_fields$get = fields.get(name)) === null || _fields$get === void 0 ? void 0 : _fields$get.type;
53
+ if (target) {
54
+ var _fields$get2;
55
+ field = `${target}.${field}`;
56
+ name = `${target}.${name}`;
57
+ type = (_fields$get2 = fields.get(target)) === null || _fields$get2 === void 0 ? void 0 : _fields$get2.type;
58
+ if (!models[target]) {
59
+ models[target] = {
60
+ type
61
+ };
62
+ }
63
+ } else {
64
+ field = `${collectionName}.${field}`;
65
+ }
66
+ return _objectSpread(_objectSpread({}, selected), {}, {
67
+ field,
68
+ name,
69
+ type,
70
+ alias: selected.alias || name
71
+ });
72
+ };
73
+ const parsedMeasures = (measures === null || measures === void 0 ? void 0 : measures.map(parseField)) || [];
74
+ const parsedDimensions = (dimensions === null || dimensions === void 0 ? void 0 : dimensions.map(parseField)) || [];
75
+ const parsedOrders = (orders === null || orders === void 0 ? void 0 : orders.map(parseField)) || [];
76
+ const include = Object.entries(models).map(([target, {
77
+ type
78
+ }]) => _objectSpread({
79
+ association: target,
80
+ attributes: []
81
+ }, type === 'belongsToMany' ? {
82
+ through: {
83
+ attributes: []
84
+ }
85
+ } : {}));
86
+ const filterParser = new (_database().FilterParser)(filter, {
87
+ collection
88
+ });
89
+ const _filterParser$toSeque = filterParser.toSequelizeParams(),
90
+ where = _filterParser$toSeque.where,
91
+ filterInclude = _filterParser$toSeque.include;
92
+ const parsedFilterInclude = filterInclude === null || filterInclude === void 0 ? void 0 : filterInclude.map(item => {
93
+ var _fields$get3;
94
+ if (((_fields$get3 = fields.get(item.association)) === null || _fields$get3 === void 0 ? void 0 : _fields$get3.type) === 'belongsToMany') {
95
+ item.through = {
96
+ attributes: []
97
+ };
98
+ }
99
+ return item;
100
+ });
101
+ return {
102
+ where,
103
+ measures: parsedMeasures,
104
+ dimensions: parsedDimensions,
105
+ orders: parsedOrders,
106
+ include: [...include, ...(parsedFilterInclude || [])]
107
+ };
108
+ };
109
+ exports.parseFieldAndAssociations = parseFieldAndAssociations;
110
+ const parseBuilder = (ctx, builder) => {
111
+ const sequelize = ctx.db.sequelize;
112
+ const limit = builder.limit;
113
+ const _parseFieldAndAssocia = parseFieldAndAssociations(ctx, builder),
114
+ measures = _parseFieldAndAssocia.measures,
115
+ dimensions = _parseFieldAndAssocia.dimensions,
116
+ orders = _parseFieldAndAssocia.orders,
117
+ include = _parseFieldAndAssocia.include,
118
+ where = _parseFieldAndAssocia.where;
119
+ const attributes = [];
120
+ const group = [];
121
+ const order = [];
122
+ const fieldMap = {};
123
+ let hasAgg = false;
124
+ measures.forEach(measure => {
125
+ const field = measure.field,
126
+ aggregation = measure.aggregation,
127
+ alias = measure.alias;
128
+ const attribute = [];
129
+ const col = sequelize.col(field);
130
+ if (aggregation) {
131
+ hasAgg = true;
132
+ attribute.push(sequelize.fn(aggregation, col));
133
+ } else {
134
+ attribute.push(col);
135
+ }
136
+ if (alias) {
137
+ attribute.push(alias);
138
+ }
139
+ attributes.push(attribute.length > 1 ? attribute : attribute[0]);
140
+ fieldMap[alias || field] = measure;
141
+ });
142
+ dimensions.forEach(dimension => {
143
+ const field = dimension.field,
144
+ format = dimension.format,
145
+ alias = dimension.alias,
146
+ type = dimension.type;
147
+ const attribute = [];
148
+ const col = sequelize.col(field);
149
+ if (format) {
150
+ attribute.push((0, _formatter.formatter)(sequelize, type, field, format));
151
+ } else {
152
+ attribute.push(col);
153
+ }
154
+ if (alias) {
155
+ attribute.push(alias);
156
+ }
157
+ attributes.push(attribute.length > 1 ? attribute : attribute[0]);
158
+ if (hasAgg) {
159
+ group.push(attribute[0]);
160
+ }
161
+ fieldMap[alias || field] = dimension;
162
+ });
163
+ orders.forEach(item => {
164
+ const name = hasAgg ? sequelize.literal(`"${item.alias}"`) : sequelize.col(item.field);
165
+ order.push([name, item.order || 'ASC']);
166
+ });
167
+ return {
168
+ queryParams: {
169
+ where,
170
+ attributes,
171
+ include,
172
+ group,
173
+ order,
174
+ limit: limit > 2000 ? 2000 : limit,
175
+ raw: true
176
+ },
177
+ fieldMap
178
+ };
179
+ };
180
+ exports.parseBuilder = parseBuilder;
181
+ const processData = (ctx, data, fieldMap) => {
182
+ const sequelize = ctx.db.sequelize;
183
+ const dialect = sequelize.getDialect();
184
+ switch (dialect) {
185
+ case 'postgres':
186
+ // https://github.com/sequelize/sequelize/issues/4550
187
+ return data.map(record => {
188
+ const result = {};
189
+ Object.entries(record).forEach(([key, value]) => {
190
+ const _ref = fieldMap[key] || {},
191
+ type = _ref.type;
192
+ switch (type) {
193
+ case 'bigInt':
194
+ case 'integer':
195
+ case 'float':
196
+ case 'double':
197
+ value = Number(value);
198
+ break;
199
+ }
200
+ result[key] = value;
201
+ });
202
+ return result;
203
+ });
204
+ default:
205
+ return data;
206
+ }
207
+ };
208
+ exports.processData = processData;
209
+ const queryData = /*#__PURE__*/function () {
210
+ var _ref2 = _asyncToGenerator(function* (ctx, builder) {
211
+ const collection = builder.collection,
212
+ measures = builder.measures,
213
+ dimensions = builder.dimensions,
214
+ orders = builder.orders,
215
+ filter = builder.filter,
216
+ limit = builder.limit,
217
+ sql = builder.sql;
218
+ const model = ctx.db.getModel(collection);
219
+ const _parseBuilder = parseBuilder(ctx, {
220
+ collection,
221
+ measures,
222
+ dimensions,
223
+ orders,
224
+ filter,
225
+ limit
226
+ }),
227
+ queryParams = _parseBuilder.queryParams,
228
+ fieldMap = _parseBuilder.fieldMap;
229
+ const data = yield model.findAll(queryParams);
230
+ return processData(ctx, data, fieldMap);
231
+ // if (!sql) {
232
+ // return await repository.find(parseBuilder(ctx, { collection, measures, dimensions, orders, filter, limit }));
233
+ // }
234
+ // const statement = `SELECT ${sql.fields} FROM ${collection} ${sql.clauses}`;
235
+ // const [data] = await ctx.db.sequelize.query(statement);
236
+ // return data;
237
+ });
238
+ return function queryData(_x2, _x3) {
239
+ return _ref2.apply(this, arguments);
240
+ };
241
+ }();
242
+ exports.queryData = queryData;
243
+ const cacheWrap = /*#__PURE__*/function () {
244
+ var _ref3 = _asyncToGenerator(function* (cache, options) {
245
+ const func = options.func,
246
+ key = options.key,
247
+ ttl = options.ttl,
248
+ useCache = options.useCache,
249
+ refresh = options.refresh;
250
+ if (useCache && !refresh) {
251
+ const data = yield cache.get(key);
252
+ if (data) {
253
+ return data;
254
+ }
255
+ }
256
+ const data = yield func();
257
+ if (useCache) {
258
+ yield cache.set(key, data, ttl);
259
+ }
260
+ return data;
261
+ });
262
+ return function cacheWrap(_x4, _x5) {
263
+ return _ref3.apply(this, arguments);
264
+ };
265
+ }();
266
+ exports.cacheWrap = cacheWrap;
267
+ const query = /*#__PURE__*/function () {
268
+ var _ref4 = _asyncToGenerator(function* (ctx, next) {
269
+ const _ctx$action$params$va = ctx.action.params.values,
270
+ uid = _ctx$action$params$va.uid,
271
+ collection = _ctx$action$params$va.collection,
272
+ measures = _ctx$action$params$va.measures,
273
+ dimensions = _ctx$action$params$va.dimensions,
274
+ orders = _ctx$action$params$va.orders,
275
+ filter = _ctx$action$params$va.filter,
276
+ limit = _ctx$action$params$va.limit,
277
+ sql = _ctx$action$params$va.sql,
278
+ cacheConfig = _ctx$action$params$va.cache,
279
+ refresh = _ctx$action$params$va.refresh;
280
+ const roleName = ctx.state.currentRole || 'anonymous';
281
+ const can = ctx.app.acl.can({
282
+ role: roleName,
283
+ resource: collection,
284
+ action: 'list'
285
+ });
286
+ if (!can && roleName !== 'root') {
287
+ ctx.throw(403, 'No permissions');
288
+ }
289
+ const plugin = ctx.app.getPlugin('data-visualization');
290
+ const cache = plugin.cache;
291
+ const useCache = (cacheConfig === null || cacheConfig === void 0 ? void 0 : cacheConfig.enabled) && uid;
292
+ try {
293
+ ctx.body = yield cacheWrap(cache, {
294
+ func: function () {
295
+ var _func = _asyncToGenerator(function* () {
296
+ return yield queryData(ctx, {
297
+ collection,
298
+ measures,
299
+ dimensions,
300
+ orders,
301
+ filter,
302
+ limit,
303
+ sql
304
+ });
305
+ });
306
+ function func() {
307
+ return _func.apply(this, arguments);
308
+ }
309
+ return func;
310
+ }(),
311
+ key: uid,
312
+ ttl: (cacheConfig === null || cacheConfig === void 0 ? void 0 : cacheConfig.ttl) || 30,
313
+ useCache: useCache ? true : false,
314
+ refresh
315
+ });
316
+ } catch (err) {
317
+ ctx.app.logger.error('charts query: ', err);
318
+ ctx.throw(500, err);
319
+ }
320
+ yield next();
321
+ });
322
+ return function query(_x6, _x7) {
323
+ return _ref4.apply(this, arguments);
324
+ };
325
+ }();
326
+ exports.query = query;
@@ -0,0 +1 @@
1
+ export { default } from './plugin';
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "default", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _plugin.default;
10
+ }
11
+ });
12
+ var _plugin = _interopRequireDefault(require("./plugin"));
13
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -0,0 +1,13 @@
1
+ import { Cache } from '@nocobase/cache';
2
+ import { InstallOptions, Plugin } from '@nocobase/server';
3
+ export declare class DataVisualizationPlugin extends Plugin {
4
+ cache: Cache;
5
+ afterAdd(): void;
6
+ beforeLoad(): void;
7
+ load(): Promise<void>;
8
+ install(options?: InstallOptions): Promise<void>;
9
+ afterEnable(): Promise<void>;
10
+ afterDisable(): Promise<void>;
11
+ remove(): Promise<void>;
12
+ }
13
+ export default DataVisualizationPlugin;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.DataVisualizationPlugin = void 0;
7
+ function _cache() {
8
+ const data = require("@nocobase/cache");
9
+ _cache = function _cache() {
10
+ return data;
11
+ };
12
+ return data;
13
+ }
14
+ function _server() {
15
+ const data = require("@nocobase/server");
16
+ _server = function _server() {
17
+ return data;
18
+ };
19
+ return data;
20
+ }
21
+ var _query = require("./actions/query");
22
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
23
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
24
+ class DataVisualizationPlugin extends _server().Plugin {
25
+ constructor(...args) {
26
+ super(...args);
27
+ this.cache = void 0;
28
+ }
29
+ afterAdd() {}
30
+ beforeLoad() {
31
+ this.app.resource({
32
+ name: 'charts',
33
+ actions: {
34
+ query: _query.query
35
+ }
36
+ });
37
+ this.app.acl.allow('charts', 'query', 'loggedIn');
38
+ }
39
+ load() {
40
+ var _this = this;
41
+ return _asyncToGenerator(function* () {
42
+ _this.cache = (0, _cache().createCache)({
43
+ ttl: 30,
44
+ max: 1000,
45
+ store: 'memory'
46
+ });
47
+ })();
48
+ }
49
+ install(options) {
50
+ return _asyncToGenerator(function* () {})();
51
+ }
52
+ afterEnable() {
53
+ return _asyncToGenerator(function* () {})();
54
+ }
55
+ afterDisable() {
56
+ return _asyncToGenerator(function* () {})();
57
+ }
58
+ remove() {
59
+ return _asyncToGenerator(function* () {})();
60
+ }
61
+ }
62
+ exports.DataVisualizationPlugin = DataVisualizationPlugin;
63
+ var _default = DataVisualizationPlugin;
64
+ exports.default = _default;
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@nocobase/plugin-data-visualization",
3
+ "version": "0.10.1-alpha.1",
4
+ "main": "lib/server/index.js",
5
+ "devDependencies": {
6
+ "@nocobase/actions": "0.10.1-alpha.1",
7
+ "@nocobase/cache": "0.10.1-alpha.1",
8
+ "@nocobase/server": "0.10.1-alpha.1",
9
+ "@nocobase/test": "0.10.1-alpha.1",
10
+ "@testing-library/react": "^14.0.0",
11
+ "lodash": "^4.17.21"
12
+ },
13
+ "dependencies": {
14
+ "@ant-design/plots": "^1.2.5",
15
+ "dayjs": "^1.11.7",
16
+ "react-error-boundary": "^4.0.4"
17
+ },
18
+ "displayName": "Data Visualization",
19
+ "displayName.zh-CN": "数据可视化",
20
+ "description": "Provides business intelligence and data visualization features",
21
+ "description.zh-CN": "提供BI面板和数据可视化功能",
22
+ "gitHead": "8f415f5e0ee2e72d681f9ab16af5911b52c374a9"
23
+ }
package/server.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ // @ts-nocheck
2
+ export * from './lib/server';
3
+ export { default } from './lib/server';
package/server.js ADDED
@@ -0,0 +1,65 @@
1
+ 'use strict';
2
+
3
+ function _getRequireWildcardCache(nodeInterop) {
4
+ if (typeof WeakMap !== 'function') return null;
5
+ var cacheBabelInterop = new WeakMap();
6
+ var cacheNodeInterop = new WeakMap();
7
+ return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) {
8
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
9
+ })(nodeInterop);
10
+ }
11
+
12
+ function _interopRequireWildcard(obj, nodeInterop) {
13
+ if (!nodeInterop && obj && obj.__esModule) {
14
+ return obj;
15
+ }
16
+ if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) {
17
+ return { default: obj };
18
+ }
19
+ var cache = _getRequireWildcardCache(nodeInterop);
20
+ if (cache && cache.has(obj)) {
21
+ return cache.get(obj);
22
+ }
23
+ var newObj = {};
24
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
25
+ for (var key in obj) {
26
+ if (key !== 'default' && Object.prototype.hasOwnProperty.call(obj, key)) {
27
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
28
+ if (desc && (desc.get || desc.set)) {
29
+ Object.defineProperty(newObj, key, desc);
30
+ } else {
31
+ newObj[key] = obj[key];
32
+ }
33
+ }
34
+ }
35
+ newObj.default = obj;
36
+ if (cache) {
37
+ cache.set(obj, newObj);
38
+ }
39
+ return newObj;
40
+ }
41
+
42
+ var _index = _interopRequireWildcard(require('./lib/server'));
43
+
44
+ Object.defineProperty(exports, '__esModule', {
45
+ value: true,
46
+ });
47
+ var _exportNames = {};
48
+ Object.defineProperty(exports, 'default', {
49
+ enumerable: true,
50
+ get: function get() {
51
+ return _index.default;
52
+ },
53
+ });
54
+
55
+ Object.keys(_index).forEach(function (key) {
56
+ if (key === 'default' || key === '__esModule') return;
57
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
58
+ if (key in exports && exports[key] === _index[key]) return;
59
+ Object.defineProperty(exports, key, {
60
+ enumerable: true,
61
+ get: function get() {
62
+ return _index[key];
63
+ },
64
+ });
65
+ });
@@ -0,0 +1,43 @@
1
+ import { CheckOutlined } from '@ant-design/icons';
2
+ import { css } from '@emotion/css';
3
+ import { Form, FormItem } from '@formily/antd';
4
+ import { Button, Card } from 'antd';
5
+ import cls from 'classnames';
6
+ import React, { useContext } from 'react';
7
+ import { useChartsTranslation } from './locale';
8
+ import { ChartLibraryContext, useToggleChartLibrary } from './renderer';
9
+
10
+ export const Settings = () => {
11
+ const { t } = useChartsTranslation();
12
+ const libraries = useContext(ChartLibraryContext);
13
+ const { toggle } = useToggleChartLibrary();
14
+ const list = Object.entries(libraries).map(([library, { enabled }]) => {
15
+ return (
16
+ <Button
17
+ key={library}
18
+ icon={enabled ? <CheckOutlined /> : ''}
19
+ className={cls(
20
+ css`
21
+ margin: 8px 8px 8px 0;
22
+ `,
23
+ enabled
24
+ ? css`
25
+ color: #40a9ff;
26
+ border-color: #40a9ff;
27
+ `
28
+ : '',
29
+ )}
30
+ onClick={() => toggle(library)}
31
+ >
32
+ {library}
33
+ </Button>
34
+ );
35
+ });
36
+ return (
37
+ <Card>
38
+ <Form layout="vertical">
39
+ <FormItem label={t('Enabled Chart Library')}>{list}</FormItem>
40
+ </Form>
41
+ </Card>
42
+ );
43
+ };
@@ -0,0 +1,14 @@
1
+ import { vi } from 'vitest';
2
+
3
+ describe('ChartConfigure', () => {
4
+ afterEach(() => {
5
+ vi.restoreAllMocks();
6
+ });
7
+
8
+ it('should render correctly', () => {
9
+ // vi.spyOn(client, 'useDesignable').mockReturnValue({} as any);
10
+ // render(<ChartConfigure insert={(schema, options) => {}} />);
11
+ // const modal = document.querySelector('.ant-modal-content') as HTMLInputElement;
12
+ // expect(modal).toBeInTheDocument();
13
+ });
14
+ });