@nocobase/plugin-data-visualization 1.0.0-alpha.9 → 1.0.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.
- package/dist/client/hooks/filter.d.ts +1 -0
- package/dist/client/hooks/useVariableOptions.d.ts +15 -0
- package/dist/client/index.js +23 -23
- package/dist/externalVersion.js +7 -6
- package/dist/node_modules/koa-compose/package.json +1 -1
- package/dist/server/actions/formatter.d.ts +4 -3
- package/dist/server/actions/formatter.js +28 -3
- package/dist/server/actions/query.d.ts +1 -1
- package/dist/server/actions/query.js +6 -47
- package/package.json +2 -2
package/dist/externalVersion.js
CHANGED
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
module.exports = {
|
|
11
|
-
"@nocobase/client": "1.0.
|
|
11
|
+
"@nocobase/client": "1.0.1-alpha.2",
|
|
12
12
|
"dayjs": "1.11.10",
|
|
13
13
|
"@formily/react": "2.3.0",
|
|
14
14
|
"@formily/shared": "2.3.0",
|
|
15
15
|
"lodash": "4.17.21",
|
|
16
|
-
"@nocobase/cache": "1.0.
|
|
17
|
-
"@nocobase/server": "1.0.
|
|
16
|
+
"@nocobase/cache": "1.0.1-alpha.2",
|
|
17
|
+
"@nocobase/server": "1.0.1-alpha.2",
|
|
18
18
|
"react": "18.2.0",
|
|
19
19
|
"@ant-design/icons": "5.2.6",
|
|
20
20
|
"ahooks": "3.7.8",
|
|
@@ -22,8 +22,9 @@ module.exports = {
|
|
|
22
22
|
"antd": "5.12.8",
|
|
23
23
|
"@formily/antd-v5": "1.1.9",
|
|
24
24
|
"@formily/core": "2.3.0",
|
|
25
|
-
"@nocobase/utils": "1.0.
|
|
25
|
+
"@nocobase/utils": "1.0.1-alpha.2",
|
|
26
26
|
"react-i18next": "11.18.6",
|
|
27
|
-
"
|
|
28
|
-
"@nocobase/
|
|
27
|
+
"sequelize": "6.35.2",
|
|
28
|
+
"@nocobase/actions": "1.0.1-alpha.2",
|
|
29
|
+
"@nocobase/database": "1.0.1-alpha.2"
|
|
29
30
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"koa-compose","description":"compose Koa middleware","repository":"koajs/compose","version":"4.1.0","keywords":["koa","middleware","compose"],"files":["index.js"],"dependencies":{},"devDependencies":{"codecov":"^3.0.0","jest":"^21.0.0","matcha":"^0.7.0","standard":"^10.0.3"},"scripts":{"bench":"matcha bench/bench.js","lint":"standard --fix .","test":"jest --forceExit --coverage"},"jest":{"testEnvironment":"node"},"license":"MIT","_lastModified":"2024-
|
|
1
|
+
{"name":"koa-compose","description":"compose Koa middleware","repository":"koajs/compose","version":"4.1.0","keywords":["koa","middleware","compose"],"files":["index.js"],"dependencies":{},"devDependencies":{"codecov":"^3.0.0","jest":"^21.0.0","matcha":"^0.7.0","standard":"^10.0.3"},"scripts":{"bench":"matcha bench/bench.js","lint":"standard --fix .","test":"jest --forceExit --coverage"},"jest":{"testEnvironment":"node"},"license":"MIT","_lastModified":"2024-06-11T12:22:49.907Z"}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
export declare const
|
|
11
|
-
export declare const
|
|
9
|
+
import { Sequelize } from 'sequelize';
|
|
10
|
+
export declare const dateFormatFn: (sequelize: Sequelize, dialect: string, field: string, format: string, timezone?: string) => import("sequelize/types/utils").Col | import("sequelize/types/utils").Fn;
|
|
11
|
+
export declare const formatFn: (sequelize: Sequelize, dialect: string, field: string, format: string) => string | import("sequelize/types/utils").Fn;
|
|
12
|
+
export declare const formatter: (sequelize: Sequelize, type: string, field: string, format: string, timezone?: string) => string | import("sequelize/types/utils").Col | import("sequelize/types/utils").Fn;
|
|
@@ -31,17 +31,42 @@ __export(formatter_exports, {
|
|
|
31
31
|
formatter: () => formatter
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(formatter_exports);
|
|
34
|
-
const
|
|
34
|
+
const getOffsetMinutesFromTimezone = (timezone) => {
|
|
35
|
+
const sign = timezone.charAt(0);
|
|
36
|
+
timezone = timezone.slice(1);
|
|
37
|
+
const [hours, minutes] = timezone.split(":");
|
|
38
|
+
const hoursNum = Number(hours);
|
|
39
|
+
const minutesNum = Number(minutes);
|
|
40
|
+
const offset = hoursNum * 60 + minutesNum;
|
|
41
|
+
return `${sign}${offset} minutes`;
|
|
42
|
+
};
|
|
43
|
+
const dateFormatFn = (sequelize, dialect, field, format, timezone) => {
|
|
35
44
|
switch (dialect) {
|
|
36
45
|
case "sqlite":
|
|
37
46
|
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");
|
|
47
|
+
if (timezone) {
|
|
48
|
+
return sequelize.fn("strftime", format, sequelize.col(field), getOffsetMinutesFromTimezone(timezone));
|
|
49
|
+
}
|
|
38
50
|
return sequelize.fn("strftime", format, sequelize.col(field));
|
|
39
51
|
case "mysql":
|
|
40
52
|
case "mariadb":
|
|
41
53
|
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");
|
|
54
|
+
if (timezone) {
|
|
55
|
+
return sequelize.fn(
|
|
56
|
+
"date_format",
|
|
57
|
+
sequelize.fn("convert_tz", sequelize.col(field), process.env.DB_TIMEZONE || "+00:00", timezone),
|
|
58
|
+
format
|
|
59
|
+
);
|
|
60
|
+
}
|
|
42
61
|
return sequelize.fn("date_format", sequelize.col(field), format);
|
|
43
62
|
case "postgres":
|
|
44
63
|
format = format.replace(/hh/g, "HH24").replace(/mm/g, "MI").replace(/ss/g, "SS");
|
|
64
|
+
if (timezone) {
|
|
65
|
+
const fieldWithTZ = sequelize.literal(
|
|
66
|
+
`(${sequelize.getQueryInterface().quoteIdentifiers(field)} AT TIME ZONE CURRENT_SETTING('TIMEZONE') AT TIME ZONE '${timezone}')`
|
|
67
|
+
);
|
|
68
|
+
return sequelize.fn("to_char", fieldWithTZ, format);
|
|
69
|
+
}
|
|
45
70
|
return sequelize.fn("to_char", sequelize.col(field), format);
|
|
46
71
|
default:
|
|
47
72
|
return sequelize.col(field);
|
|
@@ -57,13 +82,13 @@ const formatFn = (sequelize, dialect, field, format) => {
|
|
|
57
82
|
return field;
|
|
58
83
|
}
|
|
59
84
|
};
|
|
60
|
-
const formatter = (sequelize, type, field, format) => {
|
|
85
|
+
const formatter = (sequelize, type, field, format, timezone) => {
|
|
61
86
|
const dialect = sequelize.getDialect();
|
|
62
87
|
switch (type) {
|
|
63
88
|
case "date":
|
|
64
89
|
case "datetime":
|
|
65
90
|
case "time":
|
|
66
|
-
return dateFormatFn(sequelize, dialect, field, format);
|
|
91
|
+
return dateFormatFn(sequelize, dialect, field, format, timezone);
|
|
67
92
|
default:
|
|
68
93
|
return formatFn(sequelize, dialect, field, format);
|
|
69
94
|
}
|
|
@@ -11,7 +11,7 @@ export declare const postProcess: (ctx: Context, next: Next) => Promise<void>;
|
|
|
11
11
|
export declare const queryData: (ctx: Context, next: Next) => Promise<void>;
|
|
12
12
|
export declare const parseBuilder: (ctx: Context, next: Next) => Promise<void>;
|
|
13
13
|
export declare const parseFieldAndAssociations: (ctx: Context, next: Next) => Promise<void>;
|
|
14
|
-
export declare const parseVariables: (ctx: Context, next: Next) => Promise<
|
|
14
|
+
export declare const parseVariables: (ctx: Context, next: Next) => Promise<void>;
|
|
15
15
|
export declare const cacheMiddleware: (ctx: Context, next: Next) => Promise<void>;
|
|
16
16
|
export declare const checkPermission: (ctx: Context, next: Next) => Promise<any>;
|
|
17
17
|
export declare const query: (ctx: Context, next: Next) => Promise<void>;
|
|
@@ -49,7 +49,7 @@ module.exports = __toCommonJS(query_exports);
|
|
|
49
49
|
var import_database = require("@nocobase/database");
|
|
50
50
|
var import_formatter = require("./formatter");
|
|
51
51
|
var import_koa_compose = __toESM(require("koa-compose"));
|
|
52
|
-
var
|
|
52
|
+
var import_server = require("@nocobase/server");
|
|
53
53
|
const getDB = (ctx, dataSource) => {
|
|
54
54
|
const ds = ctx.app.dataSourceManager.dataSources.get(dataSource);
|
|
55
55
|
return ds == null ? void 0 : ds.collectionManager.db;
|
|
@@ -116,7 +116,7 @@ const parseBuilder = async (ctx, next) => {
|
|
|
116
116
|
const attribute = [];
|
|
117
117
|
const col = sequelize.col(field);
|
|
118
118
|
if (format) {
|
|
119
|
-
attribute.push((0, import_formatter.formatter)(sequelize, type, field, format));
|
|
119
|
+
attribute.push((0, import_formatter.formatter)(sequelize, type, field, format, ctx.timezone));
|
|
120
120
|
} else {
|
|
121
121
|
attribute.push(col);
|
|
122
122
|
}
|
|
@@ -230,52 +230,11 @@ const parseFieldAndAssociations = async (ctx, next) => {
|
|
|
230
230
|
};
|
|
231
231
|
const parseVariables = async (ctx, next) => {
|
|
232
232
|
const { filter } = ctx.action.params.values;
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
if (typeof str === "number")
|
|
238
|
-
return true;
|
|
239
|
-
if (typeof str != "string")
|
|
240
|
-
return false;
|
|
241
|
-
return !isNaN(str) && !isNaN(parseFloat(str));
|
|
242
|
-
};
|
|
243
|
-
const getUser = () => {
|
|
244
|
-
return async ({ fields }) => {
|
|
245
|
-
var _a, _b;
|
|
246
|
-
const userFields = fields.filter((f) => f && ctx.db.getFieldByPath("users." + f));
|
|
247
|
-
(_a = ctx.logger) == null ? void 0 : _a.info("parse filter variables", { userFields, method: "parseVariables" });
|
|
248
|
-
if (!ctx.state.currentUser) {
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
if (!userFields.length) {
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
const user = await ctx.db.getRepository("users").findOne({
|
|
255
|
-
filterByTk: ctx.state.currentUser.id,
|
|
256
|
-
fields: userFields
|
|
257
|
-
});
|
|
258
|
-
(_b = ctx.logger) == null ? void 0 : _b.info("parse filter variables", {
|
|
259
|
-
$user: user == null ? void 0 : user.toJSON(),
|
|
260
|
-
method: "parseVariables"
|
|
261
|
-
});
|
|
262
|
-
return user;
|
|
263
|
-
};
|
|
264
|
-
};
|
|
265
|
-
ctx.action.params.values.filter = await (0, import_utils.parseFilter)(filter, {
|
|
266
|
-
timezone: ctx.get("x-timezone"),
|
|
267
|
-
now: (/* @__PURE__ */ new Date()).toISOString(),
|
|
268
|
-
getField: (path) => {
|
|
269
|
-
const fieldPath = path.split(".").filter((p) => !p.startsWith("$") && !isNumeric(p)).join(".");
|
|
270
|
-
const { resourceName } = ctx.action;
|
|
271
|
-
return ctx.db.getFieldByPath(`${resourceName}.${fieldPath}`);
|
|
272
|
-
},
|
|
273
|
-
vars: {
|
|
274
|
-
$nDate: (0, import_utils.getDateVars)(),
|
|
275
|
-
$user: getUser()
|
|
276
|
-
}
|
|
233
|
+
ctx.action.params.filter = filter;
|
|
234
|
+
await import_server.middlewares.parseVariables(ctx, async () => {
|
|
235
|
+
ctx.action.params.values.filter = ctx.action.params.filter;
|
|
236
|
+
await next();
|
|
277
237
|
});
|
|
278
|
-
await next();
|
|
279
238
|
};
|
|
280
239
|
const cacheMiddleware = async (ctx, next) => {
|
|
281
240
|
const { uid, cache: cacheConfig, refresh } = ctx.action.params.values;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/plugin-data-visualization",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1-alpha.2",
|
|
4
4
|
"displayName": "Data visualization",
|
|
5
5
|
"displayName.zh-CN": "数据可视化",
|
|
6
6
|
"description": "Provides data visualization feature, including chart block and chart filter block, support line charts, area charts, bar charts and more than a dozen kinds of charts, you can also extend more chart types.",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@nocobase/test": "1.x",
|
|
34
34
|
"@nocobase/utils": "1.x"
|
|
35
35
|
},
|
|
36
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "fc5a8e3c812516f787cb22d3d198f058f45b1963",
|
|
37
37
|
"keywords": [
|
|
38
38
|
"Blocks"
|
|
39
39
|
]
|