@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.
Files changed (33) hide show
  1. package/dist/client/DesktopRoutesManager.d.ts +10 -0
  2. package/dist/client/MobileRoutesManager.d.ts +10 -0
  3. package/dist/client/index.js +1 -1
  4. package/dist/client/locale/index.d.ts +12 -0
  5. package/dist/client/routesTableSchema.d.ts +1242 -0
  6. package/dist/client/useTableBlockProps.d.ts +23 -0
  7. package/dist/client/utils.d.ts +10 -0
  8. package/dist/collections/desktopRoutes.d.ts +10 -0
  9. package/dist/collections/desktopRoutes.js +420 -0
  10. package/dist/collections/mobileRoutes.d.ts +10 -0
  11. package/dist/collections/mobileRoutes.js +368 -0
  12. package/dist/externalVersion.js +10 -4
  13. package/dist/locale/en-US.js +35 -2
  14. package/dist/locale/es-ES.js +30 -1
  15. package/dist/locale/fr-FR.js +30 -1
  16. package/dist/locale/ja-JP.js +30 -1
  17. package/dist/locale/ko-KR.js +30 -1
  18. package/dist/locale/pt-BR.js +30 -1
  19. package/dist/locale/ru-RU.js +22 -1
  20. package/dist/locale/tr-TR.js +22 -1
  21. package/dist/locale/uk-UA.js +30 -1
  22. package/dist/locale/zh-CN.js +52 -6
  23. package/dist/locale/zh-TW.js +31 -1
  24. package/dist/node_modules/cronstrue/package.json +1 -1
  25. package/dist/server/collections/desktopRoutes.d.ts +10 -0
  26. package/dist/server/collections/desktopRoutes.js +44 -0
  27. package/dist/server/collections/extendRoleField.d.ts +14 -0
  28. package/dist/server/collections/extendRoleField.js +44 -0
  29. package/dist/server/migrations/2024122912211-transform-menu-schema-to-routes.d.ts +14 -0
  30. package/dist/server/migrations/2024122912211-transform-menu-schema-to-routes.js +184 -0
  31. package/dist/server/server.d.ts +6 -0
  32. package/dist/server/server.js +92 -5
  33. 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
+ });
@@ -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;
@@ -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.resource({
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.2",
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": "08bbc34c21727fc0ad0880f397a42bf7741091ee"
23
+ "gitHead": "873cbaec9554e684781b8dc6cfd4386bb5cfa5b0"
24
24
  }