@nocobase/app-template-default 1.0.0-beta.73 → 1.0.0-beta.75

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 (38) hide show
  1. package/AGENTS.md +8 -2
  2. package/README.MD +3 -1
  3. package/cli/plugins.ts +2 -1
  4. package/client/components/default-access-editor.tsx +183 -0
  5. package/client/components/permission-editor.tsx +216 -150
  6. package/client/components/role-list.tsx +85 -0
  7. package/client/lib/navigation-transform.ts +29 -1
  8. package/client/locales/system/settings-en-US.ts +74 -2
  9. package/client/locales/system/settings-zh-CN.ts +66 -2
  10. package/client/pages/settings/default-access-form.tsx +499 -0
  11. package/client/pages/settings/default-access-model.ts +154 -0
  12. package/client/pages/settings/default-access.tsx +407 -0
  13. package/client/pages/settings/permission-filters.tsx +43 -37
  14. package/client/pages/settings/permission-management-page.tsx +105 -0
  15. package/client/pages/settings/permissions-model.ts +37 -1
  16. package/client/pages/settings/role-form.tsx +46 -18
  17. package/client/pages/settings/roles.tsx +26 -43
  18. package/client/pages/settings/routes.ts +78 -19
  19. package/client/pages/settings/shared.tsx +3 -0
  20. package/client/pages/settings/users.tsx +1 -1
  21. package/client/plugins.ts +2 -0
  22. package/client/routing/route-navigation.ts +21 -1
  23. package/package.json +25 -23
  24. package/server/plugins.ts +2 -0
  25. package/tests/components/default-access.test.tsx +554 -0
  26. package/tests/components/page-harness.test.tsx +132 -112
  27. package/tests/components/permission-editor.test.tsx +233 -73
  28. package/tests/components/permission-management-tabs.test.tsx +128 -0
  29. package/tests/components/role-list.test.tsx +136 -0
  30. package/tests/components/roles.test.tsx +85 -0
  31. package/tests/components/user-permissions.test.tsx +12 -0
  32. package/tests/logic/authorization-assignment-safety.test.ts +82 -0
  33. package/tests/logic/client-routes.test.ts +8 -0
  34. package/tests/logic/default-access-model.test.ts +167 -0
  35. package/tests/logic/foundation-integration.test.ts +62 -0
  36. package/tests/logic/permission-management-routes.test.ts +64 -0
  37. package/tests/logic/settings-permissions.test.ts +89 -0
  38. package/vitest.config.ts +2 -2
@@ -1,8 +1,36 @@
1
+ import { groupFoundationNavigation } from '@nocobase/app-plugin-foundation/client';
1
2
  import type { RouteNavigationItem } from '../routing/route-navigation.js';
2
3
 
3
4
  /** Application-owned navigation customization, applied after permission filtering. */
4
5
  export function transformNavigation(
5
6
  items: RouteNavigationItem[],
6
7
  ): RouteNavigationItem[] {
7
- return items;
8
+ return groupFoundationNavigation(collapsePermissionNavigation(items));
9
+ }
10
+
11
+ /** One sidebar entry opens the first readable tab; original routes and guards remain unchanged. */
12
+ export function collapsePermissionNavigation(
13
+ items: RouteNavigationItem[],
14
+ ): RouteNavigationItem[] {
15
+ return items.map((item) => {
16
+ if (item.route.name !== 'permissionManagement')
17
+ return {
18
+ ...item,
19
+ children: collapsePermissionNavigation([...item.children]),
20
+ };
21
+ const first = item.children[0];
22
+ if (!first) return item;
23
+ return {
24
+ route: {
25
+ ...first.route,
26
+ name: item.route.name,
27
+ navigation: item.route.navigation,
28
+ },
29
+ children: [],
30
+ activeRouteKeys: item.children.map(
31
+ (child) =>
32
+ `${child.route.packageName}:${child.route.path}:${child.route.id}`,
33
+ ),
34
+ };
35
+ });
8
36
  }
@@ -1,8 +1,78 @@
1
1
  const settings = {
2
+ permissionManagement: 'Permission management',
3
+ defaultAccess: {
4
+ noResourcesShort: 'No configurable objects available',
5
+ scopeInvalid:
6
+ 'Choose a valid data scope or complete its filter conditions.',
7
+
8
+ deleteChanged:
9
+ 'This rule changed or was removed. The list was refreshed; review it before deleting.',
10
+ filterDescription:
11
+ 'Apply conditions to this rule draft, then save the rule to make them effective.',
12
+ fieldLabels: { name: 'Name', id: 'ID' },
13
+ delete: 'Delete',
14
+ title: 'Default data scopes',
15
+ description:
16
+ 'Adds data access for users with operation permission, combined with role-granted scopes and subject to restriction rules.',
17
+ manage: 'Manage default data scopes',
18
+ new: 'New default scope',
19
+ edit: 'Default scope details',
20
+ resource: 'Business object',
21
+ chooseResource: 'Choose a business object',
22
+ action: 'Operation',
23
+ scope: 'Data scope',
24
+ scopes: 'Operations and data scopes',
25
+ none: 'No default scope',
26
+ all: 'All records',
27
+ custom: 'Custom filter',
28
+ records: 'Selected records ({{count}})',
29
+ retained: 'Retain existing configuration',
30
+ search: 'Search business objects or keys',
31
+ empty: 'No default data scopes',
32
+ emptyHint:
33
+ 'Create a rule to configure baseline access for a business object.',
34
+ readOnlyEmpty: 'Ask an administrator to configure baseline data access.',
35
+ noResources:
36
+ 'Every available business object already has a default rule, or no configurable objects are registered.',
37
+ unsupported:
38
+ 'This rule includes configuration absent from the current plugin catalog. It is preserved and shown read-only.',
39
+ changed:
40
+ 'This rule changed or was removed while you were editing. Reload it before saving. Your draft has not been saved.',
41
+ duplicate:
42
+ 'This key or business object already has a default rule. Use a different key or edit the existing rule.',
43
+ invalid:
44
+ 'The configuration is not accepted. Check the business object, operation and data scope.',
45
+ keyRequired: 'Enter a key other than options, subjects or records.',
46
+ resourceRequired: 'Choose a business object.',
47
+ reload: 'Reload rule',
48
+ saved: 'Saved default scope “{{name}}”',
49
+ deleted: 'Deleted default scope “{{name}}”',
50
+ deleteTitle: 'Delete default scope “{{name}}”?',
51
+ deleteHint:
52
+ 'This removes the baseline access supplied by this rule. Existing role grants and other rules remain. This cannot be undone.',
53
+ back: 'Back to default scopes',
54
+ open: 'View / edit',
55
+ },
56
+ scopeHintFor: 'About the data range for {{name}}',
57
+ scopeExplanation:
58
+ 'Each range applies to its corresponding data. The operation must also pass its authorization checks.',
59
+ noAdditionalScopeHint:
60
+ 'This action grants no additional record access here. Default access, sharing and restriction rules still determine actual access.',
61
+ systemToolsHint:
62
+ 'Manage system configuration and tools. Review the capabilities each action includes before granting access.',
63
+ userAccountsHint:
64
+ 'Manage user information, account security and role assignments. Review each permission separately.',
65
+ businessOperationsHint:
66
+ 'Choose the operations this role can perform and the data each operation can use.',
67
+ pageAccessHint:
68
+ 'Controls which pages this role can open. Data and actions on each page require their own permissions.',
69
+ roleAssignment: 'Role assignment',
70
+ accountSecurity: 'Account security',
71
+ userInformation: 'User information',
2
72
  unnamedPage: 'Unnamed page ({{path}})',
3
73
  revokeRoles: 'Revoke roles',
4
74
  keyConflict: 'This role key is already in use.',
5
- userPermissions: 'User management',
75
+ userPermissions: 'Users and accounts',
6
76
  readUsers: 'View users',
7
77
  createUsers: 'Create users',
8
78
  updateUsers: 'Edit users',
@@ -34,6 +104,7 @@ const settings = {
34
104
  username: 'Username',
35
105
  email: 'Email',
36
106
  password: 'Initial password',
107
+ roleType: 'Role type',
37
108
  roleName: 'Role name',
38
109
  key: 'Key',
39
110
  status: 'Status',
@@ -95,10 +166,11 @@ const settings = {
95
166
  noPermissions: 'No permissions to configure',
96
167
  permissionCategories: 'Permission categories',
97
168
  selectAllPermissions: 'All',
169
+ dataRanges: 'Data ranges ({{count}})',
98
170
  selectVisiblePermissions: 'Select visible permissions in {{name}}',
99
171
  permissionSummary: '{{enabled}} of {{total}} enabled',
100
172
  preservedRecordScope: 'Keep existing configuration',
101
- noRecordScope: 'No records (not authorized)',
173
+ noRecordScope: 'No additional record access',
102
174
  permissionFilter: {
103
175
  limit: 'Up to 20 conditions',
104
176
  configure: 'Conditions',
@@ -1,8 +1,70 @@
1
1
  const settings = {
2
+ permissionManagement: '权限管理',
3
+ defaultAccess: {
4
+ noResourcesShort: '暂无可配置的业务对象',
5
+ scopeInvalid: '请重新选择有效的数据范围或完善筛选条件。',
6
+
7
+ deleteChanged: '此规则已被修改或删除,列表已刷新,请重新确认后再删除。',
8
+ filterDescription: '将条件应用到当前规则草稿,保存规则后生效。',
9
+ fieldLabels: { name: '名称', id: '标识' },
10
+ delete: '删除',
11
+ title: '默认数据范围',
12
+ description:
13
+ '为已有操作权限的用户补充数据范围,与角色授权范围合并,最终仍受限制规则约束。',
14
+ manage: '管理默认数据范围',
15
+ new: '新建默认范围',
16
+ edit: '默认范围详情',
17
+ resource: '业务对象',
18
+ chooseResource: '请选择业务对象',
19
+ action: '操作',
20
+ scope: '数据范围',
21
+ scopes: '操作与数据范围',
22
+ none: '不设置默认范围',
23
+ all: '所有记录',
24
+ custom: '自定义筛选',
25
+ records: '指定记录({{count}} 条)',
26
+ retained: '保留现有配置',
27
+ search: '搜索业务对象或标识',
28
+ empty: '暂无默认数据范围',
29
+ emptyHint: '新建规则,为业务对象配置基础数据访问范围。',
30
+ readOnlyEmpty: '请联系管理员配置基础数据访问范围。',
31
+ noResources: '可用业务对象均已配置默认规则,或当前没有可配置的业务对象。',
32
+ unsupported:
33
+ '此规则包含当前插件目录中不存在的配置,已保留原值并以只读方式展示。',
34
+ changed:
35
+ '此规则在编辑期间已被修改或删除,请重新加载后再保存。当前草稿未保存。',
36
+ duplicate: '此标识或业务对象已有默认规则,请更换标识或编辑已有规则。',
37
+ invalid: '配置未通过校验,请检查业务对象、操作和数据范围。',
38
+ keyRequired: '请填写标识,不能使用 options、subjects 或 records。',
39
+ resourceRequired: '请选择业务对象。',
40
+ reload: '重新加载规则',
41
+ saved: '已保存默认范围“{{name}}”',
42
+ deleted: '已删除默认范围“{{name}}”',
43
+ deleteTitle: '删除默认范围“{{name}}”?',
44
+ deleteHint:
45
+ '删除后,此规则提供的基础访问范围将失效;已有角色授权和其他规则保留。此操作无法撤销。',
46
+ back: '返回默认数据范围',
47
+ open: '查看或编辑',
48
+ },
49
+ scopeHintFor: '关于“{{name}}”的数据范围',
50
+ scopeExplanation:
51
+ '每项范围分别约束对应数据,实际操作还需通过相应的权限检查。',
52
+ noAdditionalScopeHint:
53
+ '此操作在这里不额外授予数据访问权限,实际可访问范围仍取决于默认数据范围、共享与限制规则。',
54
+ systemToolsHint: '管理系统配置与工具,授权前请确认每项操作包含的能力。',
55
+ userAccountsHint:
56
+ '管理用户资料、账号安全和角色分配,请逐项确认需要授予的权限。',
57
+ businessOperationsHint:
58
+ '设置此角色可以执行的业务操作,以及每项操作可使用的数据范围。',
59
+ pageAccessHint:
60
+ '控制此角色可以进入哪些页面。页面中的数据和操作仍需单独授权。',
61
+ roleAssignment: '角色分配',
62
+ accountSecurity: '账号安全',
63
+ userInformation: '用户资料',
2
64
  unnamedPage: '未命名页面({{path}})',
3
65
  revokeRoles: '撤销角色',
4
66
  keyConflict: '此角色标识已被使用。',
5
- userPermissions: '用户管理',
67
+ userPermissions: '用户与账号',
6
68
  readUsers: '查看用户',
7
69
  createUsers: '创建用户',
8
70
  updateUsers: '编辑用户',
@@ -34,6 +96,7 @@ const settings = {
34
96
  username: '用户名',
35
97
  email: '邮箱',
36
98
  password: '初始密码',
99
+ roleType: '角色类型',
37
100
  roleName: '角色名称',
38
101
  key: '标识',
39
102
  status: '状态',
@@ -92,9 +155,10 @@ const settings = {
92
155
  noPermissions: '暂无可配置权限',
93
156
  permissionCategories: '权限分类',
94
157
  selectAllPermissions: '全选',
158
+ dataRanges: '数据范围({{count}})',
95
159
  selectVisiblePermissions: '选择“{{name}}”中显示的权限',
96
160
  permissionSummary: '已授权 {{enabled}} / {{total}}',
97
- noRecordScope: '不允许访问数据',
161
+ noRecordScope: '不额外授权数据范围',
98
162
  preservedRecordScope: '保留现有配置',
99
163
  permissionFilter: {
100
164
  limit: '最多支持 20 个条件',