@nocobase/plugin-client 1.6.0-alpha.3 → 1.6.0-alpha.31

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 (40) hide show
  1. package/dist/client/ClearCache.d.ts +10 -0
  2. package/dist/client/DesktopRoutesManager.d.ts +10 -0
  3. package/dist/client/MobileRoutesManager.d.ts +10 -0
  4. package/dist/client/RestartApplication.d.ts +10 -0
  5. package/dist/client/index.js +1 -1
  6. package/dist/client/locale/index.d.ts +12 -0
  7. package/dist/client/routesTableSchema.d.ts +1245 -0
  8. package/dist/client/useTableBlockProps.d.ts +26 -0
  9. package/dist/client/utils.d.ts +10 -0
  10. package/dist/collections/desktopRoutes.d.ts +10 -0
  11. package/dist/collections/desktopRoutes.js +434 -0
  12. package/dist/collections/mobileRoutes.d.ts +10 -0
  13. package/dist/collections/mobileRoutes.js +368 -0
  14. package/dist/externalVersion.js +11 -4
  15. package/dist/locale/en-US.js +40 -2
  16. package/dist/locale/es-ES.js +35 -1
  17. package/dist/locale/fr-FR.js +35 -1
  18. package/dist/locale/it-IT.js +870 -0
  19. package/dist/locale/ja-JP.js +35 -1
  20. package/dist/locale/ko-KR.js +35 -1
  21. package/dist/locale/pt-BR.js +35 -1
  22. package/dist/locale/ru-RU.js +27 -1
  23. package/dist/locale/tr-TR.js +27 -1
  24. package/dist/locale/uk-UA.js +35 -1
  25. package/dist/locale/zh-CN.js +56 -7
  26. package/dist/locale/zh-TW.js +36 -1
  27. package/dist/node_modules/cronstrue/package.json +1 -1
  28. package/dist/server/collections/desktopRoutes.d.ts +10 -0
  29. package/dist/server/collections/desktopRoutes.js +44 -0
  30. package/dist/server/collections/extendRoleField.d.ts +14 -0
  31. package/dist/server/collections/extendRoleField.js +44 -0
  32. package/dist/server/migrations/2024122912211-transform-menu-schema-to-routes.d.ts +18 -0
  33. package/dist/server/migrations/2024122912211-transform-menu-schema-to-routes.js +193 -0
  34. package/dist/server/migrations/202502071837-fix-permissions.d.ts +17 -0
  35. package/dist/server/migrations/202502071837-fix-permissions.js +85 -0
  36. package/dist/server/migrations/202503091240-fix-roles-desktop-routes.d.ts +13 -0
  37. package/dist/server/migrations/202503091240-fix-roles-desktop-routes.js +87 -0
  38. package/dist/server/server.d.ts +7 -0
  39. package/dist/server/server.js +178 -5
  40. package/package.json +3 -2
@@ -41,11 +41,13 @@ __export(server_exports, {
41
41
  });
42
42
  module.exports = __toCommonJS(server_exports);
43
43
  var import_server = require("@nocobase/server");
44
+ var import_utils = require("@nocobase/utils");
45
+ var import_lodash = __toESM(require("lodash"));
46
+ var process = __toESM(require("node:process"));
44
47
  var import_path = require("path");
45
48
  var import_antd = require("./antd");
46
49
  var import_cron = require("./cron");
47
50
  var import_cronstrue = require("./cronstrue");
48
- var process = __toESM(require("node:process"));
49
51
  async function getLang(ctx) {
50
52
  const SystemSetting = ctx.db.getRepository("systemSettings");
51
53
  const systemSetting = await SystemSetting.findOne();
@@ -96,17 +98,17 @@ class PluginClientServer extends import_server.Plugin {
96
98
  this.app.acl.allow("app", "getInfo");
97
99
  this.app.acl.registerSnippet({
98
100
  name: "app",
99
- actions: ["app:restart", "app:clearCache"]
101
+ actions: ["app:restart", "app:refresh", "app:clearCache"]
100
102
  });
101
103
  const dialect = this.app.db.sequelize.getDialect();
102
- this.app.resource({
104
+ this.app.resourceManager.define({
103
105
  name: "app",
104
106
  actions: {
105
107
  async getInfo(ctx, next) {
106
108
  var _a, _b;
107
109
  const SystemSetting = ctx.db.getRepository("systemSettings");
108
110
  const systemSetting = await SystemSetting.findOne();
109
- const enabledLanguages = systemSetting.get("enabledLanguages") || [];
111
+ const enabledLanguages = (systemSetting == null ? void 0 : systemSetting.get("enabledLanguages")) || [];
110
112
  const currentUser = ctx.state.currentUser;
111
113
  let lang = (enabledLanguages == null ? void 0 : enabledLanguages[0]) || process.env.APP_LANG || "en-US";
112
114
  if (enabledLanguages.includes(currentUser == null ? void 0 : currentUser.appLang)) {
@@ -124,6 +126,12 @@ class PluginClientServer extends import_server.Plugin {
124
126
  if (process.env["EXPORT_LIMIT"]) {
125
127
  info.exportLimit = parseInt(process.env["EXPORT_LIMIT"]);
126
128
  }
129
+ if (process.env["EXPORT_AUTO_MODE_THRESHOLD"]) {
130
+ info.exportAutoModeThreshold = parseInt(process.env["EXPORT_AUTO_MODE_THRESHOLD"]);
131
+ }
132
+ if (process.env["EXPORT_ATTACHMENTS_AUTO_MODE_THRESHOLD"]) {
133
+ info.exportAttachmentsAutoModeThreshold = parseInt(process.env["EXPORT_ATTACHMENTS_AUTO_MODE_THRESHOLD"]);
134
+ }
127
135
  ctx.body = info;
128
136
  await next();
129
137
  },
@@ -143,10 +151,175 @@ class PluginClientServer extends import_server.Plugin {
143
151
  async restart(ctx, next) {
144
152
  ctx.app.runAsCLI(["restart"], { from: "user" });
145
153
  await next();
154
+ },
155
+ async refresh(ctx, next) {
156
+ ctx.app.runCommand("refresh");
157
+ await next();
146
158
  }
147
159
  }
148
160
  });
149
- this.app.auditManager.registerActions(["app:restart", "app:clearCache"]);
161
+ this.app.auditManager.registerActions(["app:restart", "app:refresh", "app:clearCache"]);
162
+ this.registerActionHandlers();
163
+ this.bindNewMenuToRoles();
164
+ this.setACL();
165
+ this.registerLocalizationSource();
166
+ this.app.db.on("desktopRoutes.afterUpdate", async (instance, { transaction }) => {
167
+ if (instance.changed("enableTabs")) {
168
+ const repository = this.app.db.getRepository("desktopRoutes");
169
+ await repository.update({
170
+ filter: {
171
+ parentId: instance.id
172
+ },
173
+ values: {
174
+ hidden: !instance.enableTabs
175
+ },
176
+ transaction
177
+ });
178
+ }
179
+ });
180
+ }
181
+ setACL() {
182
+ this.app.acl.registerSnippet({
183
+ name: `ui.desktopRoutes`,
184
+ actions: ["desktopRoutes:create", "desktopRoutes:update", "desktopRoutes:move", "desktopRoutes:destroy"]
185
+ });
186
+ this.app.acl.registerSnippet({
187
+ name: `pm.desktopRoutes`,
188
+ actions: ["desktopRoutes:list", "roles.desktopRoutes:*"]
189
+ });
190
+ this.app.acl.allow("desktopRoutes", "listAccessible", "loggedIn");
191
+ }
192
+ /**
193
+ * used to implement: roles with permission (allowNewMenu is true) can directly access the newly created menu
194
+ */
195
+ bindNewMenuToRoles() {
196
+ this.app.db.on("roles.beforeCreate", async (instance) => {
197
+ instance.set(
198
+ "allowNewMenu",
199
+ instance.allowNewMenu === void 0 ? ["admin", "member"].includes(instance.name) : !!instance.allowNewMenu
200
+ );
201
+ });
202
+ this.app.db.on("desktopRoutes.afterCreate", async (instance, { transaction }) => {
203
+ const addNewMenuRoles = await this.app.db.getRepository("roles").find({
204
+ filter: {
205
+ allowNewMenu: true
206
+ },
207
+ transaction
208
+ });
209
+ await this.app.db.getRepository("desktopRoutes.roles", instance.id).add({
210
+ tk: addNewMenuRoles.map((role) => role.name),
211
+ transaction
212
+ });
213
+ });
214
+ const processRoleDesktopRoutes = async (params) => {
215
+ const { models, action, transaction } = params;
216
+ if (!models.length) return;
217
+ const parentIds = models.map((x) => x.desktopRouteId);
218
+ const tabs = await this.app.db.getRepository("desktopRoutes").find({
219
+ where: { parentId: parentIds, hidden: true },
220
+ transaction
221
+ });
222
+ if (!tabs.length) return;
223
+ const repository = this.app.db.getRepository("rolesDesktopRoutes");
224
+ const roleName = models[0].get("roleName");
225
+ const tabIds = tabs.map((x) => x.get("id"));
226
+ const where = { desktopRouteId: tabIds, roleName };
227
+ if (action === "create") {
228
+ const exists = await repository.find({ where });
229
+ const modelsByRouteId = import_lodash.default.keyBy(exists, (x) => x.get("desktopRouteId"));
230
+ const createModels = tabs.map((x) => !modelsByRouteId[x.get("id")] && { desktopRouteId: x.get("id"), roleName }).filter(Boolean);
231
+ for (const values of createModels) {
232
+ await repository.firstOrCreate({
233
+ values,
234
+ filterKeys: ["desktopRouteId", "roleName"],
235
+ transaction
236
+ });
237
+ }
238
+ return;
239
+ }
240
+ if (action === "remove") {
241
+ return await repository.destroy({ filter: where, transaction });
242
+ }
243
+ };
244
+ this.app.db.on("rolesDesktopRoutes.afterBulkCreate", async (instances, options) => {
245
+ await processRoleDesktopRoutes({ models: instances, action: "create", transaction: options.transaction });
246
+ });
247
+ this.app.db.on("rolesDesktopRoutes.afterBulkDestroy", async (options) => {
248
+ const models = await this.app.db.getRepository("rolesDesktopRoutes").find({
249
+ where: options.where
250
+ });
251
+ await processRoleDesktopRoutes({ models, action: "remove", transaction: options.transaction });
252
+ });
253
+ }
254
+ registerActionHandlers() {
255
+ this.app.resourceManager.registerActionHandler("desktopRoutes:listAccessible", async (ctx, next) => {
256
+ const desktopRoutesRepository = ctx.db.getRepository("desktopRoutes");
257
+ const rolesRepository = ctx.db.getRepository("roles");
258
+ if (ctx.state.currentRole === "root") {
259
+ ctx.body = await desktopRoutesRepository.find({
260
+ tree: true,
261
+ ...ctx.query
262
+ });
263
+ return await next();
264
+ }
265
+ const role = await rolesRepository.findOne({
266
+ filterByTk: ctx.state.currentRole,
267
+ appends: ["desktopRoutes"]
268
+ });
269
+ const desktopRoutesId = role.get("desktopRoutes").map(async (item, index, items) => {
270
+ if (item.type === "page" && !items.some((tab) => tab.parentId === item.id)) {
271
+ const children = await desktopRoutesRepository.find({
272
+ filter: {
273
+ parentId: item.id
274
+ }
275
+ });
276
+ return [item.id, ...(children || []).map((child) => child.id)];
277
+ }
278
+ return item.id;
279
+ });
280
+ if (desktopRoutesId) {
281
+ const ids = (await Promise.all(desktopRoutesId)).flat();
282
+ const result = await desktopRoutesRepository.find({
283
+ tree: true,
284
+ ...ctx.query,
285
+ filter: {
286
+ id: ids
287
+ }
288
+ });
289
+ ctx.body = result;
290
+ }
291
+ await next();
292
+ });
293
+ }
294
+ registerLocalizationSource() {
295
+ const localizationPlugin = this.app.pm.get("localization");
296
+ if (!localizationPlugin) {
297
+ return;
298
+ }
299
+ localizationPlugin.sourceManager.registerSource("desktop-routes", {
300
+ title: (0, import_utils.tval)("Desktop routes"),
301
+ sync: async (ctx) => {
302
+ const desktopRoutes = await ctx.db.getRepository("desktopRoutes").find({
303
+ raw: true
304
+ });
305
+ const resources = {};
306
+ desktopRoutes.forEach((route) => {
307
+ if (route.title) {
308
+ resources[route.title] = "";
309
+ }
310
+ });
311
+ return {
312
+ "lm-desktop-routes": resources
313
+ };
314
+ },
315
+ namespace: "lm-desktop-routes",
316
+ collections: [
317
+ {
318
+ collection: "desktopRoutes",
319
+ fields: ["title"]
320
+ }
321
+ ]
322
+ });
150
323
  }
151
324
  }
152
325
  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.3",
7
+ "version": "1.6.0-alpha.31",
8
8
  "main": "./dist/server/index.js",
9
9
  "license": "AGPL-3.0",
10
10
  "devDependencies": {
@@ -16,9 +16,10 @@
16
16
  "peerDependencies": {
17
17
  "@nocobase/client": "1.x",
18
18
  "@nocobase/database": "1.x",
19
+ "@nocobase/plugin-localization": "1.x",
19
20
  "@nocobase/server": "1.x",
20
21
  "@nocobase/test": "1.x",
21
22
  "@nocobase/utils": "1.x"
22
23
  },
23
- "gitHead": "205b4aca5556d5af70679fa401394943a9e51670"
24
+ "gitHead": "2f118f0a0691dd51c437f208b1166258a615b6a8"
24
25
  }