@nocobase/plugin-client 1.6.0-alpha.2 → 1.6.0-alpha.21
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/DesktopRoutesManager.d.ts +10 -0
- package/dist/client/MobileRoutesManager.d.ts +10 -0
- package/dist/client/index.js +1 -1
- package/dist/client/locale/index.d.ts +12 -0
- package/dist/client/routesTableSchema.d.ts +1242 -0
- package/dist/client/useTableBlockProps.d.ts +23 -0
- package/dist/client/utils.d.ts +10 -0
- package/dist/collections/desktopRoutes.d.ts +10 -0
- package/dist/collections/desktopRoutes.js +420 -0
- package/dist/collections/mobileRoutes.d.ts +10 -0
- package/dist/collections/mobileRoutes.js +368 -0
- package/dist/externalVersion.js +10 -4
- package/dist/locale/en-US.js +35 -2
- package/dist/locale/es-ES.js +30 -1
- package/dist/locale/fr-FR.js +30 -1
- package/dist/locale/ja-JP.js +30 -1
- package/dist/locale/ko-KR.js +30 -1
- package/dist/locale/pt-BR.js +30 -1
- package/dist/locale/ru-RU.js +22 -1
- package/dist/locale/tr-TR.js +22 -1
- package/dist/locale/uk-UA.js +30 -1
- package/dist/locale/zh-CN.js +52 -6
- package/dist/locale/zh-TW.js +31 -1
- package/dist/node_modules/cronstrue/package.json +1 -1
- package/dist/server/collections/desktopRoutes.d.ts +10 -0
- package/dist/server/collections/desktopRoutes.js +44 -0
- package/dist/server/collections/extendRoleField.d.ts +14 -0
- package/dist/server/collections/extendRoleField.js +44 -0
- package/dist/server/migrations/2024122912211-transform-menu-schema-to-routes.d.ts +14 -0
- package/dist/server/migrations/2024122912211-transform-menu-schema-to-routes.js +184 -0
- package/dist/server/server.d.ts +6 -0
- package/dist/server/server.js +92 -5
- package/package.json +2 -2
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var transform_menu_schema_to_routes_exports = {};
|
|
28
|
+
__export(transform_menu_schema_to_routes_exports, {
|
|
29
|
+
default: () => transform_menu_schema_to_routes_default,
|
|
30
|
+
schemaToRoutes: () => schemaToRoutes
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(transform_menu_schema_to_routes_exports);
|
|
33
|
+
var import_server = require("@nocobase/server");
|
|
34
|
+
class transform_menu_schema_to_routes_default extends import_server.Migration {
|
|
35
|
+
appVersion = "<1.6.0";
|
|
36
|
+
async up() {
|
|
37
|
+
const uiSchemas = this.db.getRepository("uiSchemas");
|
|
38
|
+
const desktopRoutes = this.db.getRepository("desktopRoutes");
|
|
39
|
+
const count = await desktopRoutes.count();
|
|
40
|
+
if (count > 0) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const mobileRoutes = this.db.getRepository("mobileRoutes");
|
|
44
|
+
const rolesRepository = this.db.getRepository("roles");
|
|
45
|
+
const menuSchema = await uiSchemas.getJsonSchema("nocobase-admin-menu");
|
|
46
|
+
const routes = await schemaToRoutes(menuSchema, uiSchemas);
|
|
47
|
+
try {
|
|
48
|
+
await this.db.sequelize.transaction(async (transaction) => {
|
|
49
|
+
var _a;
|
|
50
|
+
if (routes.length > 0) {
|
|
51
|
+
await desktopRoutes.createMany({
|
|
52
|
+
records: routes,
|
|
53
|
+
transaction
|
|
54
|
+
});
|
|
55
|
+
const roles = await rolesRepository.find({
|
|
56
|
+
appends: ["desktopRoutes", "menuUiSchemas"],
|
|
57
|
+
transaction
|
|
58
|
+
});
|
|
59
|
+
for (const role of roles) {
|
|
60
|
+
const menuUiSchemas = role.menuUiSchemas || [];
|
|
61
|
+
const desktopRoutes2 = role.desktopRoutes || [];
|
|
62
|
+
const needRemoveIds = getNeedRemoveIds(desktopRoutes2, menuUiSchemas);
|
|
63
|
+
if (needRemoveIds.length === 0) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
await this.db.getRepository("roles.desktopRoutes", role.name).remove({
|
|
67
|
+
tk: needRemoveIds,
|
|
68
|
+
transaction
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (mobileRoutes) {
|
|
73
|
+
const allMobileRoutes = await mobileRoutes.find({
|
|
74
|
+
transaction
|
|
75
|
+
});
|
|
76
|
+
for (const item of allMobileRoutes || []) {
|
|
77
|
+
if (item.type !== "page") {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const mobileRouteSchema = await uiSchemas.getJsonSchema(item.schemaUid);
|
|
81
|
+
const enableTabs = !!((_a = mobileRouteSchema == null ? void 0 : mobileRouteSchema["x-component-props"]) == null ? void 0 : _a.displayTabs);
|
|
82
|
+
await mobileRoutes.update({
|
|
83
|
+
filterByTk: item.id,
|
|
84
|
+
values: {
|
|
85
|
+
enableTabs
|
|
86
|
+
},
|
|
87
|
+
transaction
|
|
88
|
+
});
|
|
89
|
+
await mobileRoutes.update({
|
|
90
|
+
filter: {
|
|
91
|
+
parentId: item.id
|
|
92
|
+
},
|
|
93
|
+
values: {
|
|
94
|
+
hidden: !enableTabs
|
|
95
|
+
},
|
|
96
|
+
transaction
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error("Migration failed:", error);
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async function schemaToRoutes(schema, uiSchemas) {
|
|
108
|
+
const schemaKeys = Object.keys(schema.properties || {});
|
|
109
|
+
if (schemaKeys.length === 0) {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
const result = schemaKeys.map(async (key) => {
|
|
113
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
114
|
+
const item = schema.properties[key];
|
|
115
|
+
if (item["x-component"] === "Menu.SubMenu") {
|
|
116
|
+
return {
|
|
117
|
+
type: "group",
|
|
118
|
+
title: item.title,
|
|
119
|
+
icon: (_a = item["x-component-props"]) == null ? void 0 : _a.icon,
|
|
120
|
+
schemaUid: item["x-uid"],
|
|
121
|
+
hideInMenu: false,
|
|
122
|
+
children: await schemaToRoutes(item, uiSchemas)
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
if (item["x-component"] === "Menu.Item") {
|
|
126
|
+
const menuSchema = await uiSchemas.getProperties(item["x-uid"]);
|
|
127
|
+
const pageSchema = (_b = menuSchema == null ? void 0 : menuSchema.properties) == null ? void 0 : _b.page;
|
|
128
|
+
const enableTabs = (_c = pageSchema == null ? void 0 : pageSchema["x-component-props"]) == null ? void 0 : _c.enablePageTabs;
|
|
129
|
+
const enableHeader = !((_d = pageSchema == null ? void 0 : pageSchema["x-component-props"]) == null ? void 0 : _d.disablePageHeader);
|
|
130
|
+
const displayTitle = !((_e = pageSchema == null ? void 0 : pageSchema["x-component-props"]) == null ? void 0 : _e.hidePageTitle);
|
|
131
|
+
return {
|
|
132
|
+
type: "page",
|
|
133
|
+
title: item.title,
|
|
134
|
+
icon: (_f = item["x-component-props"]) == null ? void 0 : _f.icon,
|
|
135
|
+
schemaUid: pageSchema == null ? void 0 : pageSchema["x-uid"],
|
|
136
|
+
menuSchemaUid: item["x-uid"],
|
|
137
|
+
hideInMenu: false,
|
|
138
|
+
enableTabs,
|
|
139
|
+
enableHeader,
|
|
140
|
+
displayTitle,
|
|
141
|
+
children: (await schemaToRoutes(pageSchema, uiSchemas)).map((item2) => ({ ...item2, hidden: !enableTabs }))
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
if (item["x-component"] === "Menu.URL") {
|
|
145
|
+
return {
|
|
146
|
+
type: "link",
|
|
147
|
+
title: item.title,
|
|
148
|
+
icon: (_g = item["x-component-props"]) == null ? void 0 : _g.icon,
|
|
149
|
+
options: {
|
|
150
|
+
href: (_h = item["x-component-props"]) == null ? void 0 : _h.href,
|
|
151
|
+
params: (_i = item["x-component-props"]) == null ? void 0 : _i.params
|
|
152
|
+
},
|
|
153
|
+
schemaUid: item["x-uid"],
|
|
154
|
+
hideInMenu: false
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
type: "tabs",
|
|
159
|
+
title: item.title || '{{t("Unnamed")}}',
|
|
160
|
+
icon: (_j = item["x-component-props"]) == null ? void 0 : _j.icon,
|
|
161
|
+
schemaUid: item["x-uid"],
|
|
162
|
+
tabSchemaName: key,
|
|
163
|
+
hideInMenu: false
|
|
164
|
+
};
|
|
165
|
+
});
|
|
166
|
+
return Promise.all(result);
|
|
167
|
+
}
|
|
168
|
+
function getNeedRemoveIds(desktopRoutes, menuUiSchemas) {
|
|
169
|
+
const uidList = menuUiSchemas.map((item) => item["x-uid"]);
|
|
170
|
+
return desktopRoutes.filter((item) => {
|
|
171
|
+
if (item.type === "tabs") {
|
|
172
|
+
const page = desktopRoutes.find((route) => (route == null ? void 0 : route.id) === (item == null ? void 0 : item.parentId));
|
|
173
|
+
return !uidList.includes(page == null ? void 0 : page.menuSchemaUid);
|
|
174
|
+
}
|
|
175
|
+
if (item.type === "page") {
|
|
176
|
+
return !uidList.includes(item == null ? void 0 : item.menuSchemaUid);
|
|
177
|
+
}
|
|
178
|
+
return !uidList.includes(item == null ? void 0 : item.schemaUid);
|
|
179
|
+
}).map((item) => item == null ? void 0 : item.id);
|
|
180
|
+
}
|
|
181
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
182
|
+
0 && (module.exports = {
|
|
183
|
+
schemaToRoutes
|
|
184
|
+
});
|
package/dist/server/server.d.ts
CHANGED
|
@@ -11,5 +11,11 @@ export declare class PluginClientServer extends Plugin {
|
|
|
11
11
|
beforeLoad(): Promise<void>;
|
|
12
12
|
install(): Promise<void>;
|
|
13
13
|
load(): Promise<void>;
|
|
14
|
+
setACL(): void;
|
|
15
|
+
/**
|
|
16
|
+
* used to implement: roles with permission (allowNewMenu is true) can directly access the newly created menu
|
|
17
|
+
*/
|
|
18
|
+
bindNewMenuToRoles(): void;
|
|
19
|
+
registerActionHandlers(): void;
|
|
14
20
|
}
|
|
15
21
|
export default PluginClientServer;
|
package/dist/server/server.js
CHANGED
|
@@ -41,11 +41,11 @@ __export(server_exports, {
|
|
|
41
41
|
});
|
|
42
42
|
module.exports = __toCommonJS(server_exports);
|
|
43
43
|
var import_server = require("@nocobase/server");
|
|
44
|
+
var process = __toESM(require("node:process"));
|
|
44
45
|
var import_path = require("path");
|
|
45
46
|
var import_antd = require("./antd");
|
|
46
47
|
var import_cron = require("./cron");
|
|
47
48
|
var import_cronstrue = require("./cronstrue");
|
|
48
|
-
var process = __toESM(require("node:process"));
|
|
49
49
|
async function getLang(ctx) {
|
|
50
50
|
const SystemSetting = ctx.db.getRepository("systemSettings");
|
|
51
51
|
const systemSetting = await SystemSetting.findOne();
|
|
@@ -96,17 +96,17 @@ class PluginClientServer extends import_server.Plugin {
|
|
|
96
96
|
this.app.acl.allow("app", "getInfo");
|
|
97
97
|
this.app.acl.registerSnippet({
|
|
98
98
|
name: "app",
|
|
99
|
-
actions: ["app:restart", "app:clearCache"]
|
|
99
|
+
actions: ["app:restart", "app:refresh", "app:clearCache"]
|
|
100
100
|
});
|
|
101
101
|
const dialect = this.app.db.sequelize.getDialect();
|
|
102
|
-
this.app.
|
|
102
|
+
this.app.resourceManager.define({
|
|
103
103
|
name: "app",
|
|
104
104
|
actions: {
|
|
105
105
|
async getInfo(ctx, next) {
|
|
106
106
|
var _a, _b;
|
|
107
107
|
const SystemSetting = ctx.db.getRepository("systemSettings");
|
|
108
108
|
const systemSetting = await SystemSetting.findOne();
|
|
109
|
-
const enabledLanguages = systemSetting.get("enabledLanguages") || [];
|
|
109
|
+
const enabledLanguages = (systemSetting == null ? void 0 : systemSetting.get("enabledLanguages")) || [];
|
|
110
110
|
const currentUser = ctx.state.currentUser;
|
|
111
111
|
let lang = (enabledLanguages == null ? void 0 : enabledLanguages[0]) || process.env.APP_LANG || "en-US";
|
|
112
112
|
if (enabledLanguages.includes(currentUser == null ? void 0 : currentUser.appLang)) {
|
|
@@ -124,6 +124,12 @@ class PluginClientServer extends import_server.Plugin {
|
|
|
124
124
|
if (process.env["EXPORT_LIMIT"]) {
|
|
125
125
|
info.exportLimit = parseInt(process.env["EXPORT_LIMIT"]);
|
|
126
126
|
}
|
|
127
|
+
if (process.env["EXPORT_AUTO_MODE_THRESHOLD"]) {
|
|
128
|
+
info.exportAutoModeThreshold = parseInt(process.env["EXPORT_AUTO_MODE_THRESHOLD"]);
|
|
129
|
+
}
|
|
130
|
+
if (process.env["EXPORT_ATTACHMENTS_AUTO_MODE_THRESHOLD"]) {
|
|
131
|
+
info.exportAttachmentsAutoModeThreshold = parseInt(process.env["EXPORT_ATTACHMENTS_AUTO_MODE_THRESHOLD"]);
|
|
132
|
+
}
|
|
127
133
|
ctx.body = info;
|
|
128
134
|
await next();
|
|
129
135
|
},
|
|
@@ -143,10 +149,91 @@ class PluginClientServer extends import_server.Plugin {
|
|
|
143
149
|
async restart(ctx, next) {
|
|
144
150
|
ctx.app.runAsCLI(["restart"], { from: "user" });
|
|
145
151
|
await next();
|
|
152
|
+
},
|
|
153
|
+
async refresh(ctx, next) {
|
|
154
|
+
ctx.app.runCommand("refresh");
|
|
155
|
+
await next();
|
|
146
156
|
}
|
|
147
157
|
}
|
|
148
158
|
});
|
|
149
|
-
this.app.auditManager.registerActions(["app:restart", "app:clearCache"]);
|
|
159
|
+
this.app.auditManager.registerActions(["app:restart", "app:refresh", "app:clearCache"]);
|
|
160
|
+
this.registerActionHandlers();
|
|
161
|
+
this.bindNewMenuToRoles();
|
|
162
|
+
this.setACL();
|
|
163
|
+
this.app.db.on("desktopRoutes.afterUpdate", async (instance, { transaction }) => {
|
|
164
|
+
if (instance.changed("enableTabs")) {
|
|
165
|
+
const repository = this.app.db.getRepository("desktopRoutes");
|
|
166
|
+
await repository.update({
|
|
167
|
+
filter: {
|
|
168
|
+
parentId: instance.id
|
|
169
|
+
},
|
|
170
|
+
values: {
|
|
171
|
+
hidden: !instance.enableTabs
|
|
172
|
+
},
|
|
173
|
+
transaction
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
setACL() {
|
|
179
|
+
this.app.acl.registerSnippet({
|
|
180
|
+
name: `ui.desktopRoutes`,
|
|
181
|
+
actions: ["desktopRoutes:create", "desktopRoutes:update", "desktopRoutes:move", "desktopRoutes:destroy"]
|
|
182
|
+
});
|
|
183
|
+
this.app.acl.registerSnippet({
|
|
184
|
+
name: `pm.desktopRoutes`,
|
|
185
|
+
actions: ["desktopRoutes:list", "roles.desktopRoutes:*"]
|
|
186
|
+
});
|
|
187
|
+
this.app.acl.allow("desktopRoutes", "listAccessible", "loggedIn");
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* used to implement: roles with permission (allowNewMenu is true) can directly access the newly created menu
|
|
191
|
+
*/
|
|
192
|
+
bindNewMenuToRoles() {
|
|
193
|
+
this.app.db.on("roles.beforeCreate", async (instance) => {
|
|
194
|
+
instance.set(
|
|
195
|
+
"allowNewMenu",
|
|
196
|
+
instance.allowNewMenu === void 0 ? ["admin", "member"].includes(instance.name) : !!instance.allowNewMenu
|
|
197
|
+
);
|
|
198
|
+
});
|
|
199
|
+
this.app.db.on("desktopRoutes.afterCreate", async (instance, { transaction }) => {
|
|
200
|
+
const addNewMenuRoles = await this.app.db.getRepository("roles").find({
|
|
201
|
+
filter: {
|
|
202
|
+
allowNewMenu: true
|
|
203
|
+
},
|
|
204
|
+
transaction
|
|
205
|
+
});
|
|
206
|
+
await this.app.db.getRepository("desktopRoutes.roles", instance.id).add({
|
|
207
|
+
tk: addNewMenuRoles.map((role) => role.name),
|
|
208
|
+
transaction
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
registerActionHandlers() {
|
|
213
|
+
this.app.resourceManager.registerActionHandler("desktopRoutes:listAccessible", async (ctx, next) => {
|
|
214
|
+
const desktopRoutesRepository = ctx.db.getRepository("desktopRoutes");
|
|
215
|
+
const rolesRepository = ctx.db.getRepository("roles");
|
|
216
|
+
if (ctx.state.currentRole === "root") {
|
|
217
|
+
ctx.body = await desktopRoutesRepository.find({
|
|
218
|
+
tree: true,
|
|
219
|
+
...ctx.query
|
|
220
|
+
});
|
|
221
|
+
return await next();
|
|
222
|
+
}
|
|
223
|
+
const role = await rolesRepository.findOne({
|
|
224
|
+
filterByTk: ctx.state.currentRole,
|
|
225
|
+
appends: ["desktopRoutes"]
|
|
226
|
+
});
|
|
227
|
+
const desktopRoutesId = role.get("desktopRoutes").filter((item) => !item.hidden).map((item) => item.id);
|
|
228
|
+
ctx.body = await desktopRoutesRepository.find({
|
|
229
|
+
tree: true,
|
|
230
|
+
...ctx.query,
|
|
231
|
+
filter: {
|
|
232
|
+
id: desktopRoutesId
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
await next();
|
|
236
|
+
});
|
|
150
237
|
}
|
|
151
238
|
}
|
|
152
239
|
var server_default = PluginClientServer;
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"displayName.zh-CN": "WEB 客户端",
|
|
5
5
|
"description": "Provides a client interface for the NocoBase server",
|
|
6
6
|
"description.zh-CN": "为 NocoBase 服务端提供客户端界面",
|
|
7
|
-
"version": "1.6.0-alpha.
|
|
7
|
+
"version": "1.6.0-alpha.21",
|
|
8
8
|
"main": "./dist/server/index.js",
|
|
9
9
|
"license": "AGPL-3.0",
|
|
10
10
|
"devDependencies": {
|
|
@@ -20,5 +20,5 @@
|
|
|
20
20
|
"@nocobase/test": "1.x",
|
|
21
21
|
"@nocobase/utils": "1.x"
|
|
22
22
|
},
|
|
23
|
-
"gitHead": "
|
|
23
|
+
"gitHead": "873cbaec9554e684781b8dc6cfd4386bb5cfa5b0"
|
|
24
24
|
}
|