@nocobase/portal-template-default 1.0.9 → 1.0.10
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/.env.example +5 -0
- package/.github/workflows/publish.yml +106 -0
- package/.gitignore +33 -0
- package/AGENTS.md +19 -0
- package/README.MD +61 -180
- package/package.json +3 -5
- package/scripts/build-html.mjs +12 -0
- package/src/App.css +2 -0
- package/src/App.tsx +35 -186
- package/src/app/development.tsx +154 -0
- package/src/app/extension.ts +5 -0
- package/src/app/extensions.tsx +18 -4
- package/src/app/routes.tsx +65 -0
- package/src/components/access-control/acl-bootstrap.tsx +11 -3
- package/src/components/access-control/acl-gate.tsx +7 -6
- package/src/components/access-control/can-access.tsx +17 -0
- package/src/components/access-control/navigate-to-accessible-resource.tsx +8 -3
- package/src/components/app-shell/sidebar.tsx +21 -5
- package/src/components/auth/auto-redirect-provider.tsx +2 -1
- package/src/extensions/nocobase-acl/README.md +74 -0
- package/{registry → src/extensions}/nocobase-acl/components/acl-boundary.tsx +22 -25
- package/{registry → src/extensions}/nocobase-acl/components/role-switcher.tsx +26 -23
- package/src/extensions/nocobase-acl/demo/acl-preview-provider.tsx +81 -0
- package/{registry → src/extensions}/nocobase-acl/demo/boundary-api.tsx +58 -0
- package/{registry → src/extensions}/nocobase-acl/demo/index.tsx +243 -105
- package/{registry → src/extensions}/nocobase-acl/demo/prompt-generator.tsx +3 -1
- package/src/extensions/nocobase-acl/extension.tsx +73 -0
- package/{registry → src/extensions}/nocobase-ai/README.md +21 -5
- package/{registry → src/extensions}/nocobase-ai/components/chat/chat-composer.tsx +3 -1
- package/{registry → src/extensions}/nocobase-ai/components/chat/chat-messages.tsx +38 -3
- package/{registry → src/extensions}/nocobase-ai/components/chat/tool-call-card.tsx +1 -9
- package/{registry → src/extensions}/nocobase-ai/components/index.ts +5 -0
- package/src/extensions/nocobase-ai/components/surfaces/chat-dialog.tsx +17 -0
- package/src/extensions/nocobase-ai/components/surfaces/chat-side-panel.tsx +35 -0
- package/src/extensions/nocobase-ai/components/surfaces/chat-surface.tsx +108 -0
- package/{registry → src/extensions}/nocobase-ai/components/triggers/ai-chat-floating-trigger.tsx +2 -2
- package/{registry → src/extensions}/nocobase-ai/demo/configuration-gate.tsx +4 -1
- package/{registry → src/extensions}/nocobase-ai/demo/container-showcase.tsx +2 -2
- package/{registry → src/extensions}/nocobase-ai/demo/floating.tsx +45 -15
- package/{registry → src/extensions}/nocobase-ai/demo/index.tsx +116 -74
- package/{registry → src/extensions}/nocobase-ai/demo/prompt-generator.tsx +3 -3
- package/{registry → src/extensions}/nocobase-ai/demo/tool-cards.tsx +2 -3
- package/src/extensions/nocobase-ai/extension.tsx +160 -0
- package/{registry → src/extensions}/nocobase-ai/global-ai-chat.tsx +12 -28
- package/{registry → src/extensions}/nocobase-ai/providers/ai-provider.tsx +14 -1
- package/{registry → src/extensions}/nocobase-ai/providers/chat-context.tsx +1 -0
- package/{registry → src/extensions}/nocobase-ai/providers/chat-provider.tsx +29 -8
- package/{registry → src/extensions}/nocobase-ai/providers/use-chat-attachments.ts +6 -1
- package/{registry → src/extensions}/nocobase-ai/providers/use-chat-work-context.ts +4 -1
- package/{registry → src/extensions}/nocobase-route-surfaces/README.md +2 -1
- package/{registry → src/extensions}/nocobase-route-surfaces/demo/index.tsx +33 -7
- package/{registry → src/extensions}/nocobase-route-surfaces/demo/scenarios.ts +20 -14
- package/{registry → src/extensions}/nocobase-route-surfaces/extension.tsx +55 -52
- package/src/{pages/users → extensions/nocobase-users-example}/create.tsx +4 -4
- package/src/{pages/users → extensions/nocobase-users-example}/edit.tsx +5 -9
- package/src/extensions/nocobase-users-example/extension.tsx +109 -0
- package/src/{pages/users → extensions/nocobase-users-example}/form-context.ts +11 -9
- package/src/extensions/nocobase-users-example/layout.tsx +16 -0
- package/src/{pages/users → extensions/nocobase-users-example}/list.tsx +1 -1
- package/src/extensions/nocobase-users-example/locales/en-US.ts +77 -0
- package/src/extensions/nocobase-users-example/locales/index.ts +8 -0
- package/src/extensions/nocobase-users-example/locales/zh-CN.ts +73 -0
- package/src/extensions/nocobase-users-example/optional-ai.ts +67 -0
- package/src/{pages/users → extensions/nocobase-users-example}/role-detail.tsx +4 -15
- package/src/{pages/users → extensions/nocobase-users-example}/routes.ts +1 -4
- package/src/extensions/nocobase-users-example/show.tsx +266 -0
- package/src/lib/nocobase/acl/context.ts +32 -0
- package/src/lib/nocobase/acl/evaluator.ts +186 -0
- package/src/lib/nocobase/acl/hooks.ts +40 -0
- package/src/lib/nocobase/acl/index.ts +4 -1
- package/src/lib/nocobase/acl/menu.ts +6 -6
- package/src/lib/nocobase/acl/record-permissions.ts +37 -7
- package/src/lib/nocobase/acl/store-provider.tsx +14 -0
- package/src/lib/nocobase/acl/store.ts +92 -86
- package/src/lib/nocobase/acl/types.ts +52 -32
- package/src/lib/nocobase/auth-session.ts +128 -0
- package/src/lib/nocobase/client.ts +48 -50
- package/src/locales/en-US.ts +0 -78
- package/src/locales/index.ts +2 -7
- package/src/locales/zh-CN.ts +0 -74
- package/src/providers/access-control.ts +43 -8
- package/src/providers/auth-callback.ts +1 -0
- package/src/providers/auth.ts +24 -26
- package/src/providers/constants.ts +0 -4
- package/src/providers/data.ts +14 -26
- package/src/providers/runtime-config.ts +40 -0
- package/src/vite-env.d.ts +9 -0
- package/tests/auth-session-regression.mjs +101 -0
- package/tsconfig.json +2 -1
- package/vite.config.ts +9 -1
- package/dist/assets/CoordinateSystem-C8P-Cleg.js +0 -1
- package/dist/assets/LegendVisualProvider-Bdgkckq-.js +0 -1
- package/dist/assets/LineDraw-C0m1GONT.js +0 -1
- package/dist/assets/SymbolDraw-CCospe5G.js +0 -1
- package/dist/assets/VisualMapping-Cbv1v7Cd.js +0 -1
- package/dist/assets/ai-employee-shortcut-B253WWow.js +0 -1
- package/dist/assets/calendar-B3dXXyIv.js +0 -1
- package/dist/assets/chat-inline-xpQ9iq4p.js +0 -1
- package/dist/assets/chat-side-panel-layout-BVWsp5rr.js +0 -1
- package/dist/assets/components-ChhJaNRc.js +0 -20
- package/dist/assets/configuration-gate-Dwdq_lxf.js +0 -1
- package/dist/assets/createClipPathFromCoordSys-uEftn1Mq.js +0 -1
- package/dist/assets/createSeriesDataSimply-CI7l7Ufv.js +0 -1
- package/dist/assets/customGraphicKeyframeAnimation-DE3jSfMd.js +0 -3
- package/dist/assets/echarts-preview-C-cNUtJF.js +0 -1
- package/dist/assets/echarts-runtime-CEgJbv68.js +0 -58
- package/dist/assets/echarts-runtime-advanced-Buhm2BHz.js +0 -1
- package/dist/assets/echarts-runtime-common-DLAdBAIa.js +0 -1
- package/dist/assets/echarts-runtime-components-ypnyLkYx.js +0 -1
- package/dist/assets/echarts-runtime-hierarchy-ClStquCF.js +0 -1
- package/dist/assets/floating-BarTmn-b.js +0 -13
- package/dist/assets/index-BJIcYTdc.js +0 -53
- package/dist/assets/index-C6xNKxpg.js +0 -656
- package/dist/assets/index-D4JQi1TM.js +0 -54
- package/dist/assets/index-YA7-AUO8.css +0 -1
- package/dist/assets/index-g8zWVpP9.js +0 -23
- package/dist/assets/labelHelper-C137W5gU.js +0 -1
- package/dist/assets/nocobase-ai-chat-VTMaZFQB.svg +0 -50
- package/dist/assets/page-context-Cxx11gzg.js +0 -73
- package/dist/assets/prompt-card-BsYMW_rq.js +0 -1
- package/dist/assets/sectorHelper-Fqgz3uEk.js +0 -1
- package/dist/assets/shortcut-xtghDP63.js +0 -47
- package/dist/assets/static.browser-CfQQzERe.js +0 -30
- package/dist/assets/switch-DrxImI8F.js +0 -1
- package/dist/assets/tool-cards-BGfsY8JF.js +0 -41
- package/dist/favicon.ico +0 -0
- package/dist/index.html +0 -40
- package/dist/index.raw.html +0 -46
- package/dist/logo-dark.png +0 -0
- package/dist/logo-mark-dark.png +0 -0
- package/dist/logo-mark.png +0 -0
- package/dist/logo.png +0 -0
- package/registry/nocobase-acl/README.md +0 -19
- package/registry/nocobase-acl/extension.tsx +0 -71
- package/registry/nocobase-acl/tests/acl-regression.mjs +0 -314
- package/registry/nocobase-ai/components/surfaces/chat-dialog.tsx +0 -31
- package/registry/nocobase-ai/components/surfaces/chat-side-panel.tsx +0 -74
- package/registry/nocobase-ai/extension.tsx +0 -158
- package/registry/nocobase-ai/tests/business-report-regression.mjs +0 -70
- package/registry/nocobase-ai/tests/form-filler-regression.mjs +0 -129
- package/registry/nocobase-ai/tests/frontend-tool-regression.mjs +0 -128
- package/registry/nocobase-ai/tests/page-context-regression.mjs +0 -48
- package/registry/nocobase-ai/tests/stream-regression.mjs +0 -207
- package/registry/nocobase-auth-cas/README.md +0 -6
- package/registry/nocobase-auth-cas/cas-sign-in-button.tsx +0 -41
- package/registry/nocobase-auth-cas/demo.tsx +0 -20
- package/registry/nocobase-auth-cas/extension.tsx +0 -46
- package/registry/nocobase-auth-cas/index.ts +0 -1
- package/registry/nocobase-auth-cas/use-cas-sign-in.ts +0 -29
- package/registry/nocobase-auth-dingtalk/README.md +0 -7
- package/registry/nocobase-auth-dingtalk/auto-login-provider.tsx +0 -154
- package/registry/nocobase-auth-dingtalk/demo.tsx +0 -23
- package/registry/nocobase-auth-dingtalk/dingtalk-sign-in-button.tsx +0 -45
- package/registry/nocobase-auth-dingtalk/extension.tsx +0 -55
- package/registry/nocobase-auth-dingtalk/index.ts +0 -4
- package/registry/nocobase-auth-dingtalk/use-dingtalk-sign-in.ts +0 -64
- package/registry/nocobase-auth-ldap/README.md +0 -6
- package/registry/nocobase-auth-ldap/demo.tsx +0 -21
- package/registry/nocobase-auth-ldap/extension.tsx +0 -46
- package/registry/nocobase-auth-ldap/index.ts +0 -1
- package/registry/nocobase-auth-ldap/ldap-sign-in-form.tsx +0 -69
- package/registry/nocobase-auth-ldap/use-ldap-sign-in.ts +0 -5
- package/registry/nocobase-auth-oidc/README.md +0 -11
- package/registry/nocobase-auth-oidc/auto-redirect-provider.tsx +0 -13
- package/registry/nocobase-auth-oidc/demo.tsx +0 -20
- package/registry/nocobase-auth-oidc/extension.tsx +0 -51
- package/registry/nocobase-auth-oidc/index.ts +0 -1
- package/registry/nocobase-auth-oidc/oidc-sign-in-button.tsx +0 -44
- package/registry/nocobase-auth-oidc/use-oidc-sign-in.ts +0 -58
- package/registry/nocobase-auth-saml/README.md +0 -6
- package/registry/nocobase-auth-saml/auto-redirect-provider.tsx +0 -13
- package/registry/nocobase-auth-saml/demo.tsx +0 -20
- package/registry/nocobase-auth-saml/extension.tsx +0 -51
- package/registry/nocobase-auth-saml/index.ts +0 -1
- package/registry/nocobase-auth-saml/saml-sign-in-button.tsx +0 -43
- package/registry/nocobase-auth-saml/use-saml-sign-in.ts +0 -51
- package/registry/nocobase-auth-sms/README.md +0 -7
- package/registry/nocobase-auth-sms/demo.tsx +0 -25
- package/registry/nocobase-auth-sms/extension.tsx +0 -46
- package/registry/nocobase-auth-sms/index.ts +0 -1
- package/registry/nocobase-auth-sms/sms-sign-in-form.tsx +0 -107
- package/registry/nocobase-auth-sms/use-sms-sign-in.ts +0 -88
- package/registry/nocobase-auth-wecom/README.md +0 -6
- package/registry/nocobase-auth-wecom/auto-login-provider.tsx +0 -21
- package/registry/nocobase-auth-wecom/demo.tsx +0 -23
- package/registry/nocobase-auth-wecom/extension.tsx +0 -49
- package/registry/nocobase-auth-wecom/index.ts +0 -1
- package/registry/nocobase-auth-wecom/use-wecom-sign-in.ts +0 -62
- package/registry/nocobase-auth-wecom/wecom-sign-in-button.tsx +0 -70
- package/registry/nocobase-i18n/README.md +0 -44
- package/registry/nocobase-i18n/components/index.ts +0 -1
- package/registry/nocobase-i18n/components/language-switcher.tsx +0 -138
- package/registry/nocobase-i18n/demo/index.tsx +0 -209
- package/registry/nocobase-i18n/demo/prompt-generator.tsx +0 -132
- package/registry/nocobase-i18n/extension.tsx +0 -45
- package/registry/nocobase-i18n/index.ts +0 -7
- package/registry/nocobase-i18n/locales/en-US.ts +0 -39
- package/registry/nocobase-i18n/locales/index.ts +0 -8
- package/registry/nocobase-i18n/locales/zh-CN.ts +0 -35
- package/registry/nocobase-i18n/provider.tsx +0 -44
- package/registry/nocobase-i18n/server-resources.ts +0 -166
- package/registry/nocobase-i18n/tests/i18n-regression.mjs +0 -51
- package/registry.config.json +0 -302
- package/scripts/registry.mjs +0 -164
- package/src/components/access-control/resource-access-guard.tsx +0 -21
- package/src/components/access-control/use-acl-runtime.ts +0 -28
- package/src/lib/nocobase/acl/action.ts +0 -147
- package/src/pages/users/layout.tsx +0 -15
- package/src/pages/users/show.tsx +0 -278
- /package/{registry → src/extensions}/nocobase-acl/components/index.ts +0 -0
- /package/{registry → src/extensions}/nocobase-acl/components/role-options.ts +0 -0
- /package/{registry → src/extensions}/nocobase-acl/demo/components.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-acl/demo/lazy-route.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-acl/demo/role-switcher-prompt-generator.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-acl/demo/scenario-section.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-acl/index.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/adapters/react-hook-form.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/assets/nocobase-ai-chat.svg +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/ai-root-provider.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/ai-employee-avatar.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-attachment.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-compact.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-empty-state.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-header.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-history-dialog.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-message.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/chat-window.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/conversation-list.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/markdown-message.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/model-select-options.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/reasoning-panel.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/sub-agent-conversation.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/user-prompt-editor.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/chat/work-context-chip.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/page-elements/ai-form.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/page-elements/page-element-provider.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/surfaces/chat-inline.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/surfaces/chat-page.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/surfaces/chat-side-panel-layout.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/surfaces/chat-surface-actions.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/builtin-tool-renderers.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/business-report-dialog.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/business-report-renderer.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/business-report-utils.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/chart-renderer.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-preview.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime-advanced.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime-common.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime-components.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime-hierarchy.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/echarts-runtime.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/sub-agent-renderer.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/suggestions-renderer.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/tool-renderer-provider.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/tool-renderer-utils.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/tools/workflow-renderer.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/components/triggers/ai-employee-shortcut.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/demo/interaction-showcase.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/demo/page-context-prompt-generator.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/demo/page-context.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/demo/page-element-showcase.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/demo/prompt-card.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/demo/shortcut.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/index.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/avatars.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/chat-controller.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/chat-message-utils.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/chat-reducer.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/chat-task-utils.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/chat-transport.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/form-registry.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/frontend-tool-registry.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/index.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/model.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/page-context.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/stream-coalescer.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/stream-event-utils.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/stream-parser.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/sub-agent-stream.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/types.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/ui-message-stream.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/use-automatic-tool-approval.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/use-chat-message-actions.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/use-chat-runtime.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/use-conversation-catalog.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/providers/use-conversation-history.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/services/index.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/services/nocobase-ai-service.ts +0 -0
- /package/{registry → src/extensions}/nocobase-ai/services/types.ts +0 -0
- /package/{registry → src/extensions}/nocobase-route-surfaces/demo/lazy-route.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-route-surfaces/demo/prompt-generator.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-route-surfaces/index.ts +0 -0
- /package/{registry → src/extensions}/nocobase-route-surfaces/route-dialog.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-route-surfaces/route-drawer.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-route-surfaces/route-page.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-route-surfaces/route-surface-context.ts +0 -0
- /package/{registry → src/extensions}/nocobase-route-surfaces/use-refine-unsaved-changes.tsx +0 -0
- /package/{registry → src/extensions}/nocobase-route-surfaces/use-route-surface-close.ts +0 -0
- /package/{registry → src/extensions}/nocobase-route-surfaces/use-route-surface-state.ts +0 -0
- /package/src/{pages/users → extensions/nocobase-users-example}/form-fields.tsx +0 -0
- /package/src/{pages/users → extensions/nocobase-users-example}/index.ts +0 -0
- /package/src/{pages/users → extensions/nocobase-users-example}/role-badges.tsx +0 -0
- /package/src/{pages/users → extensions/nocobase-users-example}/role-utils.ts +0 -0
- /package/src/{pages/users → extensions/nocobase-users-example}/types.ts +0 -0
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import type { BaseKey, IResourceItem } from "@refinedev/core";
|
|
2
2
|
|
|
3
|
-
export type RoleMode =
|
|
4
|
-
| "default"
|
|
5
|
-
| "allow-use-union"
|
|
6
|
-
| "only-use-union";
|
|
3
|
+
export type RoleMode = "default" | "allow-use-union" | "only-use-union";
|
|
7
4
|
|
|
8
5
|
export type Role = {
|
|
9
6
|
name: string;
|
|
10
7
|
title?: string;
|
|
11
8
|
};
|
|
12
9
|
|
|
10
|
+
export type RoleConstraint = {
|
|
11
|
+
anyOf?: string[];
|
|
12
|
+
allOf?: string[];
|
|
13
|
+
noneOf?: string[];
|
|
14
|
+
};
|
|
15
|
+
|
|
13
16
|
export type AclActionParams = Record<string, unknown> & {
|
|
14
17
|
fields?: string[];
|
|
15
18
|
whitelist?: string[];
|
|
16
19
|
appends?: string[];
|
|
17
20
|
};
|
|
18
21
|
|
|
19
|
-
export type
|
|
22
|
+
export type AclResourcePermissions = {
|
|
20
23
|
snippets?: string[];
|
|
21
|
-
role?: string;
|
|
22
|
-
roleMode?: RoleMode;
|
|
23
24
|
resources?: string[];
|
|
24
25
|
actions?: Record<string, AclActionParams>;
|
|
25
26
|
actionAlias?: Record<string, string>;
|
|
@@ -34,26 +35,44 @@ export type AclRoleData = {
|
|
|
34
35
|
uiButtonSchemasBlacklist?: string[];
|
|
35
36
|
};
|
|
36
37
|
|
|
37
|
-
export type
|
|
38
|
-
|
|
38
|
+
export type AclPermissionSet = AclResourcePermissions & {
|
|
39
|
+
currentRole?: string;
|
|
40
|
+
roles: string[];
|
|
41
|
+
roleMode?: RoleMode;
|
|
42
|
+
dataSources?: Record<string, Partial<AclResourcePermissions>>;
|
|
39
43
|
};
|
|
40
44
|
|
|
41
45
|
export type AclResponse = {
|
|
42
|
-
data?:
|
|
43
|
-
|
|
46
|
+
data?: AclResourcePermissions & {
|
|
47
|
+
role?: string;
|
|
48
|
+
roles?: string[];
|
|
49
|
+
roleMode?: RoleMode;
|
|
50
|
+
};
|
|
51
|
+
meta?: {
|
|
52
|
+
dataSources?: Record<string, Partial<AclResourcePermissions>>;
|
|
53
|
+
};
|
|
44
54
|
};
|
|
45
55
|
|
|
46
|
-
export type
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
export type AclState =
|
|
57
|
+
| {
|
|
58
|
+
status: "idle" | "loading";
|
|
59
|
+
permissions?: undefined;
|
|
60
|
+
error?: undefined;
|
|
61
|
+
}
|
|
62
|
+
| {
|
|
63
|
+
status: "ready";
|
|
64
|
+
permissions: AclPermissionSet;
|
|
65
|
+
error?: undefined;
|
|
66
|
+
}
|
|
67
|
+
| {
|
|
68
|
+
status: "error";
|
|
69
|
+
permissions?: undefined;
|
|
70
|
+
error: Error;
|
|
71
|
+
};
|
|
54
72
|
|
|
55
|
-
|
|
56
|
-
|
|
73
|
+
type ResourceAclRule = {
|
|
74
|
+
roles?: RoleConstraint;
|
|
75
|
+
} & (
|
|
57
76
|
| {
|
|
58
77
|
type: "authenticated";
|
|
59
78
|
}
|
|
@@ -70,19 +89,20 @@ export type ResourceAcl =
|
|
|
70
89
|
| {
|
|
71
90
|
type: "route";
|
|
72
91
|
routeId: string | number;
|
|
73
|
-
}
|
|
92
|
+
}
|
|
93
|
+
);
|
|
74
94
|
|
|
75
|
-
export type
|
|
95
|
+
export type ResourceAcl = false | ResourceAclRule;
|
|
96
|
+
|
|
97
|
+
export type AclAccessRequest = {
|
|
98
|
+
roles?: RoleConstraint;
|
|
76
99
|
resource?: string;
|
|
77
|
-
action
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
resource?: IResourceItem;
|
|
84
|
-
[key: string]: unknown;
|
|
85
|
-
};
|
|
100
|
+
action?: string;
|
|
101
|
+
id?: BaseKey;
|
|
102
|
+
field?: string;
|
|
103
|
+
dataSourceKey?: string;
|
|
104
|
+
meta?: Record<string, unknown>;
|
|
105
|
+
resourceItem?: IResourceItem;
|
|
86
106
|
};
|
|
87
107
|
|
|
88
108
|
export type AclIdentity = {
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { getNocoBaseAppName } from "@/providers/runtime-config";
|
|
2
|
+
|
|
3
|
+
export type AuthStorageType = "localStorage" | "sessionStorage" | "memory";
|
|
4
|
+
export type AuthSessionField = "token" | "auth" | "role" | "locale";
|
|
5
|
+
|
|
6
|
+
type AuthSessionRuntime = Window & {
|
|
7
|
+
__nocobase_api_client_storage_prefix__?: string;
|
|
8
|
+
__nocobase_api_client_storage_type__?: string;
|
|
9
|
+
__nocobase_api_client_share_token__?: boolean | string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type StorageLike = Pick<Storage, "getItem" | "setItem" | "removeItem">;
|
|
13
|
+
|
|
14
|
+
type AuthSessionOptions = {
|
|
15
|
+
appName?: string;
|
|
16
|
+
storagePrefix?: string;
|
|
17
|
+
storageType?: AuthStorageType;
|
|
18
|
+
shareToken?: boolean;
|
|
19
|
+
storage?: StorageLike;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const DEFAULT_STORAGE_PREFIX = "NOCOBASE_";
|
|
23
|
+
const DEFAULT_STORAGE_TYPE: AuthStorageType = "localStorage";
|
|
24
|
+
const memoryStorage = new Map<string, string>();
|
|
25
|
+
|
|
26
|
+
const memoryStorageAdapter: StorageLike = {
|
|
27
|
+
getItem: (key) => memoryStorage.get(key) ?? null,
|
|
28
|
+
setItem: (key, value) => memoryStorage.set(key, value),
|
|
29
|
+
removeItem: (key) => memoryStorage.delete(key),
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const normalizeStorageType = (value?: string): AuthStorageType => {
|
|
33
|
+
if (value === "sessionStorage" || value === "memory") return value;
|
|
34
|
+
return DEFAULT_STORAGE_TYPE;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const parseBoolean = (value: boolean | string | undefined) =>
|
|
38
|
+
value === true || (typeof value === "string" && /^true$/i.test(value));
|
|
39
|
+
|
|
40
|
+
const getRuntimeWindow = () =>
|
|
41
|
+
typeof window === "undefined" ? undefined : (window as AuthSessionRuntime);
|
|
42
|
+
|
|
43
|
+
const getStorage = (type: AuthStorageType): StorageLike => {
|
|
44
|
+
if (typeof window === "undefined" || type === "memory") {
|
|
45
|
+
return memoryStorageAdapter;
|
|
46
|
+
}
|
|
47
|
+
return type === "sessionStorage" ? window.sessionStorage : window.localStorage;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const getCookie = (name: string) => {
|
|
51
|
+
if (typeof document === "undefined") return undefined;
|
|
52
|
+
const prefix = `${name}=`;
|
|
53
|
+
const value = document.cookie
|
|
54
|
+
.split(";")
|
|
55
|
+
.map((item) => item.trim())
|
|
56
|
+
.find((item) => item.startsWith(prefix))
|
|
57
|
+
?.slice(prefix.length);
|
|
58
|
+
if (value === undefined) return undefined;
|
|
59
|
+
try {
|
|
60
|
+
return decodeURIComponent(value);
|
|
61
|
+
} catch {
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export class AuthSession {
|
|
67
|
+
readonly appName: string;
|
|
68
|
+
readonly storagePrefix: string;
|
|
69
|
+
readonly storageType: AuthStorageType;
|
|
70
|
+
readonly shareToken: boolean;
|
|
71
|
+
private readonly storage: StorageLike;
|
|
72
|
+
|
|
73
|
+
constructor(options: AuthSessionOptions = {}) {
|
|
74
|
+
const runtime = getRuntimeWindow();
|
|
75
|
+
this.appName = options.appName ?? getNocoBaseAppName();
|
|
76
|
+
this.storagePrefix =
|
|
77
|
+
options.storagePrefix ||
|
|
78
|
+
runtime?.__nocobase_api_client_storage_prefix__ ||
|
|
79
|
+
import.meta.env.API_CLIENT_STORAGE_PREFIX ||
|
|
80
|
+
DEFAULT_STORAGE_PREFIX;
|
|
81
|
+
this.storageType =
|
|
82
|
+
options.storageType ??
|
|
83
|
+
normalizeStorageType(
|
|
84
|
+
runtime?.__nocobase_api_client_storage_type__ ??
|
|
85
|
+
import.meta.env.API_CLIENT_STORAGE_TYPE
|
|
86
|
+
);
|
|
87
|
+
this.shareToken =
|
|
88
|
+
options.shareToken ??
|
|
89
|
+
parseBoolean(
|
|
90
|
+
runtime?.__nocobase_api_client_share_token__ ??
|
|
91
|
+
import.meta.env.API_CLIENT_SHARE_TOKEN
|
|
92
|
+
);
|
|
93
|
+
this.storage = options.storage ?? getStorage(this.storageType);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
getStorageKey(field: AuthSessionField) {
|
|
97
|
+
const isSharedSubAppToken =
|
|
98
|
+
field === "token" && this.appName !== "main" && this.shareToken;
|
|
99
|
+
const appPrefix =
|
|
100
|
+
this.appName === "main" || isSharedSubAppToken
|
|
101
|
+
? this.storagePrefix
|
|
102
|
+
: `${this.storagePrefix}${this.appName.toUpperCase()}_`;
|
|
103
|
+
return `${appPrefix}${field}`.toUpperCase();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
get(field: AuthSessionField) {
|
|
107
|
+
return this.storage.getItem(this.getStorageKey(field)) || undefined;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
set(field: AuthSessionField, value?: string | null) {
|
|
111
|
+
const key = this.getStorageKey(field);
|
|
112
|
+
if (value) this.storage.setItem(key, value);
|
|
113
|
+
else this.storage.removeItem(key);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
clearAuthentication() {
|
|
117
|
+
this.set("token", null);
|
|
118
|
+
this.set("auth", null);
|
|
119
|
+
this.set("role", null);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
getCookie(type: "role" | "csrfToken") {
|
|
123
|
+
const prefix = type === "role" ? "nb_role" : "nb_csrf_token";
|
|
124
|
+
return getCookie(`${prefix}_${this.appName}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export const authSession = new AuthSession();
|
|
@@ -2,11 +2,8 @@ import {
|
|
|
2
2
|
API_ORIGIN,
|
|
3
3
|
API_URL,
|
|
4
4
|
NOCOBASE_AUTHENTICATOR,
|
|
5
|
-
NOCOBASE_AUTHENTICATOR_KEY,
|
|
6
|
-
NOCOBASE_LOCALE_KEY,
|
|
7
|
-
NOCOBASE_ROLE_KEY,
|
|
8
|
-
NOCOBASE_TOKEN_KEY,
|
|
9
5
|
} from "@/providers/constants";
|
|
6
|
+
import { authSession } from "./auth-session";
|
|
10
7
|
import { getNocoBaseErrorMessage, NocoBaseHttpError } from "./error";
|
|
11
8
|
|
|
12
9
|
type QueryValue =
|
|
@@ -26,7 +23,6 @@ export type NocoBaseRequestOptions = {
|
|
|
26
23
|
authenticator?: string | null;
|
|
27
24
|
role?: string;
|
|
28
25
|
includeRole?: boolean;
|
|
29
|
-
includeAuthenticator?: boolean;
|
|
30
26
|
withAclMeta?: boolean;
|
|
31
27
|
headers?: Record<string, string>;
|
|
32
28
|
accept?: "json" | "stream";
|
|
@@ -36,6 +32,8 @@ export type NocoBaseRequestOptions = {
|
|
|
36
32
|
const getBrowserLocale = () =>
|
|
37
33
|
typeof navigator === "undefined" ? undefined : navigator.language;
|
|
38
34
|
|
|
35
|
+
const SAFE_METHODS = new Set(["GET", "HEAD", "OPTIONS"]);
|
|
36
|
+
|
|
39
37
|
const getClientTimezone = () => {
|
|
40
38
|
const offsetMinutes = -new Date().getTimezoneOffset();
|
|
41
39
|
const sign = offsetMinutes >= 0 ? "+" : "-";
|
|
@@ -73,6 +71,10 @@ export class NocoBaseClient {
|
|
|
73
71
|
return this.apiUrl;
|
|
74
72
|
}
|
|
75
73
|
|
|
74
|
+
getAppName() {
|
|
75
|
+
return authSession.appName;
|
|
76
|
+
}
|
|
77
|
+
|
|
76
78
|
resolveUrl(value: string) {
|
|
77
79
|
if (!value || /^[a-z][a-z\d+.-]*:/i.test(value)) return value;
|
|
78
80
|
const base =
|
|
@@ -87,18 +89,11 @@ export class NocoBaseClient {
|
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
getToken() {
|
|
90
|
-
return (
|
|
91
|
-
(typeof localStorage === "undefined"
|
|
92
|
-
? undefined
|
|
93
|
-
: localStorage.getItem(NOCOBASE_TOKEN_KEY) ?? undefined) ??
|
|
94
|
-
import.meta.env.NOCOBASE_API_TOKEN
|
|
95
|
-
);
|
|
92
|
+
return authSession.get("token") ?? import.meta.env.NOCOBASE_API_TOKEN;
|
|
96
93
|
}
|
|
97
94
|
|
|
98
95
|
getStoredAuthenticator() {
|
|
99
|
-
return
|
|
100
|
-
? undefined
|
|
101
|
-
: localStorage.getItem(NOCOBASE_AUTHENTICATOR_KEY) ?? undefined;
|
|
96
|
+
return authSession.get("auth");
|
|
102
97
|
}
|
|
103
98
|
|
|
104
99
|
getAuthenticator() {
|
|
@@ -106,36 +101,23 @@ export class NocoBaseClient {
|
|
|
106
101
|
}
|
|
107
102
|
|
|
108
103
|
setAuthenticator(authenticator?: string | null) {
|
|
109
|
-
|
|
110
|
-
if (authenticator) {
|
|
111
|
-
localStorage.setItem(NOCOBASE_AUTHENTICATOR_KEY, authenticator);
|
|
112
|
-
} else {
|
|
113
|
-
localStorage.removeItem(NOCOBASE_AUTHENTICATOR_KEY);
|
|
114
|
-
}
|
|
104
|
+
authSession.set("auth", authenticator);
|
|
115
105
|
}
|
|
116
106
|
|
|
117
107
|
setToken(token?: string | null) {
|
|
118
|
-
|
|
119
|
-
if (token) localStorage.setItem(NOCOBASE_TOKEN_KEY, token);
|
|
120
|
-
else localStorage.removeItem(NOCOBASE_TOKEN_KEY);
|
|
108
|
+
authSession.set("token", token);
|
|
121
109
|
}
|
|
122
110
|
|
|
123
111
|
getRole() {
|
|
124
|
-
return
|
|
125
|
-
? undefined
|
|
126
|
-
: localStorage.getItem(NOCOBASE_ROLE_KEY) ?? undefined;
|
|
112
|
+
return authSession.get("role") ?? authSession.getCookie("role");
|
|
127
113
|
}
|
|
128
114
|
|
|
129
115
|
setRole(role?: string | null) {
|
|
130
|
-
|
|
131
|
-
if (role) localStorage.setItem(NOCOBASE_ROLE_KEY, role);
|
|
132
|
-
else localStorage.removeItem(NOCOBASE_ROLE_KEY);
|
|
116
|
+
authSession.set("role", role);
|
|
133
117
|
}
|
|
134
118
|
|
|
135
119
|
getStoredLocale() {
|
|
136
|
-
return
|
|
137
|
-
? undefined
|
|
138
|
-
: localStorage.getItem(NOCOBASE_LOCALE_KEY) ?? undefined;
|
|
120
|
+
return authSession.get("locale");
|
|
139
121
|
}
|
|
140
122
|
|
|
141
123
|
getLocale() {
|
|
@@ -143,9 +125,11 @@ export class NocoBaseClient {
|
|
|
143
125
|
}
|
|
144
126
|
|
|
145
127
|
setLocale(locale?: string | null) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
128
|
+
authSession.set("locale", locale);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
clearAuthentication() {
|
|
132
|
+
authSession.clearAuthentication();
|
|
149
133
|
}
|
|
150
134
|
|
|
151
135
|
setRuntimeLocale(locale?: string | null) {
|
|
@@ -173,38 +157,35 @@ export class NocoBaseClient {
|
|
|
173
157
|
}
|
|
174
158
|
|
|
175
159
|
getHeaders({
|
|
160
|
+
method = "GET",
|
|
176
161
|
token = this.getToken(),
|
|
177
162
|
authenticator,
|
|
178
163
|
role = this.getRole(),
|
|
179
164
|
includeRole = true,
|
|
180
|
-
includeAuthenticator = false,
|
|
181
165
|
withAclMeta = true,
|
|
182
166
|
headers,
|
|
183
167
|
accept = "json",
|
|
184
168
|
body,
|
|
185
169
|
}: Pick<
|
|
186
170
|
NocoBaseRequestOptions,
|
|
171
|
+
| "method"
|
|
187
172
|
| "token"
|
|
188
173
|
| "authenticator"
|
|
189
174
|
| "role"
|
|
190
175
|
| "includeRole"
|
|
191
|
-
| "includeAuthenticator"
|
|
192
176
|
| "withAclMeta"
|
|
193
177
|
| "headers"
|
|
194
178
|
| "accept"
|
|
195
179
|
| "body"
|
|
196
|
-
> = {}) {
|
|
180
|
+
> = {}): Record<string, string> {
|
|
197
181
|
const resolvedAuthenticator =
|
|
198
182
|
authenticator === null
|
|
199
183
|
? undefined
|
|
200
|
-
: authenticator ??
|
|
201
|
-
(includeAuthenticator
|
|
202
|
-
? this.getAuthenticator()
|
|
203
|
-
: this.getStoredAuthenticator());
|
|
184
|
+
: authenticator ?? this.getStoredAuthenticator();
|
|
204
185
|
const locale = this.getLocale();
|
|
205
186
|
const formData =
|
|
206
187
|
typeof FormData !== "undefined" && body instanceof FormData;
|
|
207
|
-
|
|
188
|
+
const requestHeaders: Record<string, string> = {
|
|
208
189
|
Accept: accept === "stream" ? "text/event-stream" : "application/json",
|
|
209
190
|
...(body !== undefined && !formData
|
|
210
191
|
? { "Content-Type": "application/json" }
|
|
@@ -222,6 +203,17 @@ export class NocoBaseClient {
|
|
|
222
203
|
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
223
204
|
...headers,
|
|
224
205
|
};
|
|
206
|
+
const csrfToken = authSession.getCookie("csrfToken");
|
|
207
|
+
if (
|
|
208
|
+
!SAFE_METHODS.has(method) &&
|
|
209
|
+
csrfToken &&
|
|
210
|
+
!Object.keys(requestHeaders).some(
|
|
211
|
+
(key) => key.toLowerCase() === "x-csrf-token"
|
|
212
|
+
)
|
|
213
|
+
) {
|
|
214
|
+
requestHeaders["X-CSRF-Token"] = csrfToken;
|
|
215
|
+
}
|
|
216
|
+
return requestHeaders;
|
|
225
217
|
}
|
|
226
218
|
|
|
227
219
|
async request<T>(
|
|
@@ -230,9 +222,11 @@ export class NocoBaseClient {
|
|
|
230
222
|
): Promise<T> {
|
|
231
223
|
const method =
|
|
232
224
|
options.method ?? (options.body === undefined ? "GET" : "POST");
|
|
225
|
+
const headers = this.getHeaders({ ...options, method, body: options.body });
|
|
233
226
|
const response = await fetch(this.buildUrl(endpoint, options.query), {
|
|
234
227
|
method,
|
|
235
|
-
headers
|
|
228
|
+
headers,
|
|
229
|
+
credentials: "include",
|
|
236
230
|
body:
|
|
237
231
|
options.body === undefined
|
|
238
232
|
? undefined
|
|
@@ -270,13 +264,17 @@ export class NocoBaseClient {
|
|
|
270
264
|
endpoint: string,
|
|
271
265
|
options: Omit<NocoBaseRequestOptions, "accept" | "unwrap"> = {}
|
|
272
266
|
) {
|
|
267
|
+
const method = options.method ?? "POST";
|
|
268
|
+
const headers = this.getHeaders({
|
|
269
|
+
...options,
|
|
270
|
+
method,
|
|
271
|
+
accept: "stream",
|
|
272
|
+
body: options.body,
|
|
273
|
+
});
|
|
273
274
|
const response = await fetch(this.buildUrl(endpoint, options.query), {
|
|
274
|
-
method
|
|
275
|
-
headers
|
|
276
|
-
|
|
277
|
-
accept: "stream",
|
|
278
|
-
body: options.body,
|
|
279
|
-
}),
|
|
275
|
+
method,
|
|
276
|
+
headers,
|
|
277
|
+
credentials: "include",
|
|
280
278
|
body:
|
|
281
279
|
options.body === undefined ? undefined : JSON.stringify(options.body),
|
|
282
280
|
signal: options.signal,
|
package/src/locales/en-US.ts
CHANGED
|
@@ -85,81 +85,3 @@ export const starter = {
|
|
|
85
85
|
Anonymous: "Anonymous",
|
|
86
86
|
"Full permissions": "Full permissions",
|
|
87
87
|
} as const;
|
|
88
|
-
|
|
89
|
-
export const app = {
|
|
90
|
-
"resources.users": "Users",
|
|
91
|
-
"resources.user": "User",
|
|
92
|
-
"resources.users.description":
|
|
93
|
-
"Manage the people who can sign in and work in this NocoBase application.",
|
|
94
|
-
"users.fields.id": "ID",
|
|
95
|
-
"users.fields.nickname": "Nickname",
|
|
96
|
-
"users.fields.username": "Username",
|
|
97
|
-
"users.fields.email": "Email",
|
|
98
|
-
"users.fields.phone": "Phone",
|
|
99
|
-
"users.fields.password": "Password",
|
|
100
|
-
"users.fields.roles": "Roles",
|
|
101
|
-
"users.fields.createdAt": "Created at",
|
|
102
|
-
"users.fields.updatedAt": "Updated at",
|
|
103
|
-
"users.fields.actions": "Actions",
|
|
104
|
-
"users.filters.roles.placeholder": "Select roles...",
|
|
105
|
-
"users.filters.roles.noResults": "No roles found.",
|
|
106
|
-
"users.actions.view": "View user",
|
|
107
|
-
"users.actions.edit": "Edit user",
|
|
108
|
-
"users.actions.delete": "Delete user",
|
|
109
|
-
"users.drawer.create.title": "Create user",
|
|
110
|
-
"users.drawer.create.description":
|
|
111
|
-
"Add a user who can sign in to this NocoBase application.",
|
|
112
|
-
"users.drawer.edit.title": "Edit user",
|
|
113
|
-
"users.drawer.edit.description":
|
|
114
|
-
"Update this user's identity and contact information.",
|
|
115
|
-
"users.drawer.show.description":
|
|
116
|
-
"Review this user's identity, contact information, and roles.",
|
|
117
|
-
"users.form.create.submit": "Create user",
|
|
118
|
-
"users.form.create.submitting": "Creating...",
|
|
119
|
-
"users.form.edit.submit": "Save changes",
|
|
120
|
-
"users.form.edit.submitting": "Saving...",
|
|
121
|
-
"users.form.cancel": "Cancel",
|
|
122
|
-
"users.form.nickname.placeholder": "Enter a display name",
|
|
123
|
-
"users.form.username.placeholder": "Enter a unique username",
|
|
124
|
-
"users.form.email.placeholder": "Enter an email address",
|
|
125
|
-
"users.form.phone.placeholder": "Enter a phone number",
|
|
126
|
-
"users.form.password.placeholder": "Set an initial password",
|
|
127
|
-
"users.form.password.aiNotice":
|
|
128
|
-
"Passwords are never included in AI page context or Form filler.",
|
|
129
|
-
"users.validation.username": "Username is required",
|
|
130
|
-
"users.validation.email": "Email is required",
|
|
131
|
-
"users.validation.emailFormat": "Enter a valid email address",
|
|
132
|
-
"users.validation.phone": "Phone is required",
|
|
133
|
-
"users.validation.password": "Password is required",
|
|
134
|
-
"users.detail.identity": "Identity",
|
|
135
|
-
"users.detail.contact": "Contact",
|
|
136
|
-
"users.detail.access": "Access",
|
|
137
|
-
"users.detail.timestamps": "Timestamps",
|
|
138
|
-
"users.detail.noRoles": "No assigned roles",
|
|
139
|
-
"users.detail.unnamed": "Unnamed user",
|
|
140
|
-
"users.detail.loadError.title": "Unable to load user",
|
|
141
|
-
"users.detail.loadError.description":
|
|
142
|
-
"The user may no longer exist, or you may not have permission to view it.",
|
|
143
|
-
"users.ai.table": "Users table",
|
|
144
|
-
"users.ai.detail": "User details",
|
|
145
|
-
"users.ai.createForm": "Create user form",
|
|
146
|
-
"users.ai.editForm": "Edit user form",
|
|
147
|
-
"common.yes": "Yes",
|
|
148
|
-
"common.no": "No",
|
|
149
|
-
"roles.drawer.description": "Review the role associated with this user.",
|
|
150
|
-
"roles.fields.name": "Name",
|
|
151
|
-
"roles.fields.title": "Title",
|
|
152
|
-
"roles.fields.description": "Description",
|
|
153
|
-
"roles.fields.default": "Default role",
|
|
154
|
-
"roles.fields.hidden": "Hidden",
|
|
155
|
-
"roles.fields.allowConfigure": "Can configure",
|
|
156
|
-
"roles.fields.createdAt": "Created at",
|
|
157
|
-
"roles.fields.updatedAt": "Updated at",
|
|
158
|
-
"roles.detail.identity": "Role identity",
|
|
159
|
-
"roles.detail.settings": "Settings",
|
|
160
|
-
"roles.detail.actions": "Allowed actions",
|
|
161
|
-
"roles.detail.timestamps": "Timestamps",
|
|
162
|
-
"roles.detail.unavailable":
|
|
163
|
-
"Additional role details are unavailable. Showing the relation data included with the user.",
|
|
164
|
-
"roles.ai.detail": "Role details",
|
|
165
|
-
} as const;
|
package/src/locales/index.ts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { registerTranslationResources } from "@/lib/i18n";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { starter as enUSStarter } from "./en-US";
|
|
3
|
+
import { starter as zhCNStarter } from "./zh-CN";
|
|
4
4
|
|
|
5
5
|
registerTranslationResources("starter", {
|
|
6
6
|
"en-US": enUSStarter,
|
|
7
7
|
"zh-CN": zhCNStarter,
|
|
8
8
|
});
|
|
9
|
-
|
|
10
|
-
registerTranslationResources("app", {
|
|
11
|
-
"en-US": enUSApp,
|
|
12
|
-
"zh-CN": zhCNApp,
|
|
13
|
-
});
|
package/src/locales/zh-CN.ts
CHANGED
|
@@ -82,77 +82,3 @@ export const starter = {
|
|
|
82
82
|
Anonymous: "匿名用户",
|
|
83
83
|
"Full permissions": "全部权限",
|
|
84
84
|
} as const;
|
|
85
|
-
|
|
86
|
-
export const app = {
|
|
87
|
-
"resources.users": "用户",
|
|
88
|
-
"resources.user": "用户",
|
|
89
|
-
"resources.users.description": "管理可以登录并使用此 NocoBase 应用的用户。",
|
|
90
|
-
"users.fields.id": "ID",
|
|
91
|
-
"users.fields.nickname": "昵称",
|
|
92
|
-
"users.fields.username": "用户名",
|
|
93
|
-
"users.fields.email": "邮箱",
|
|
94
|
-
"users.fields.phone": "手机号",
|
|
95
|
-
"users.fields.password": "密码",
|
|
96
|
-
"users.fields.roles": "角色",
|
|
97
|
-
"users.fields.createdAt": "创建时间",
|
|
98
|
-
"users.fields.updatedAt": "更新时间",
|
|
99
|
-
"users.fields.actions": "操作",
|
|
100
|
-
"users.filters.roles.placeholder": "选择角色…",
|
|
101
|
-
"users.filters.roles.noResults": "未找到角色。",
|
|
102
|
-
"users.actions.view": "查看用户",
|
|
103
|
-
"users.actions.edit": "编辑用户",
|
|
104
|
-
"users.actions.delete": "删除用户",
|
|
105
|
-
"users.drawer.create.title": "新建用户",
|
|
106
|
-
"users.drawer.create.description": "添加可以登录此 NocoBase 应用的用户。",
|
|
107
|
-
"users.drawer.edit.title": "编辑用户",
|
|
108
|
-
"users.drawer.edit.description": "更新用户的身份和联系方式。",
|
|
109
|
-
"users.drawer.show.description": "查看用户的身份、联系方式和关联角色。",
|
|
110
|
-
"users.form.create.submit": "创建用户",
|
|
111
|
-
"users.form.create.submitting": "正在创建...",
|
|
112
|
-
"users.form.edit.submit": "保存修改",
|
|
113
|
-
"users.form.edit.submitting": "正在保存...",
|
|
114
|
-
"users.form.cancel": "取消",
|
|
115
|
-
"users.form.nickname.placeholder": "输入显示名称",
|
|
116
|
-
"users.form.username.placeholder": "输入唯一用户名",
|
|
117
|
-
"users.form.email.placeholder": "输入邮箱地址",
|
|
118
|
-
"users.form.phone.placeholder": "输入手机号",
|
|
119
|
-
"users.form.password.placeholder": "设置初始密码",
|
|
120
|
-
"users.form.password.aiNotice":
|
|
121
|
-
"密码不会包含在 AI 页面上下文中,Form filler 也无法填写密码。",
|
|
122
|
-
"users.validation.username": "请输入用户名",
|
|
123
|
-
"users.validation.email": "请输入邮箱",
|
|
124
|
-
"users.validation.emailFormat": "请输入有效的邮箱地址",
|
|
125
|
-
"users.validation.phone": "请输入手机号",
|
|
126
|
-
"users.validation.password": "请输入密码",
|
|
127
|
-
"users.detail.identity": "身份信息",
|
|
128
|
-
"users.detail.contact": "联系方式",
|
|
129
|
-
"users.detail.access": "访问权限",
|
|
130
|
-
"users.detail.timestamps": "时间信息",
|
|
131
|
-
"users.detail.noRoles": "尚未分配角色",
|
|
132
|
-
"users.detail.unnamed": "未命名用户",
|
|
133
|
-
"users.detail.loadError.title": "无法加载用户",
|
|
134
|
-
"users.detail.loadError.description":
|
|
135
|
-
"该用户可能已不存在,或者你没有权限查看此用户。",
|
|
136
|
-
"users.ai.table": "用户表格",
|
|
137
|
-
"users.ai.detail": "用户详情",
|
|
138
|
-
"users.ai.createForm": "新建用户表单",
|
|
139
|
-
"users.ai.editForm": "编辑用户表单",
|
|
140
|
-
"common.yes": "是",
|
|
141
|
-
"common.no": "否",
|
|
142
|
-
"roles.drawer.description": "查看与当前用户关联的角色信息。",
|
|
143
|
-
"roles.fields.name": "名称",
|
|
144
|
-
"roles.fields.title": "标题",
|
|
145
|
-
"roles.fields.description": "描述",
|
|
146
|
-
"roles.fields.default": "默认角色",
|
|
147
|
-
"roles.fields.hidden": "隐藏",
|
|
148
|
-
"roles.fields.allowConfigure": "允许配置",
|
|
149
|
-
"roles.fields.createdAt": "创建时间",
|
|
150
|
-
"roles.fields.updatedAt": "更新时间",
|
|
151
|
-
"roles.detail.identity": "角色标识",
|
|
152
|
-
"roles.detail.settings": "角色设置",
|
|
153
|
-
"roles.detail.actions": "允许的操作",
|
|
154
|
-
"roles.detail.timestamps": "时间信息",
|
|
155
|
-
"roles.detail.unavailable":
|
|
156
|
-
"无法加载更多角色详情,当前展示用户关联数据中已有的信息。",
|
|
157
|
-
"roles.ai.detail": "角色详情",
|
|
158
|
-
} as const;
|