From 2cb1203aa44e9b0eba301aeaa04558698dcb155c Mon Sep 17 00:00:00 2001 From: jack zhang <1098626505@qq.com> Date: Fri, 7 Jul 2023 14:35:22 +0800 Subject: [PATCH] refactor(client)!: application, router and plugin (#2068) BREAKING CHANGE: * refactor: update umi version 3.x to version 4.x * refactor: update react-router-dom version to 6.x * refactor(react-router-dom): change Layout Component `props.children` to `` * refactor(react-router-dom): change props and correct * refactor(react-router-dom): replace `` to `` * refactor(react-router-dom): replace `useHistory` to `useNavigate` * refactor(react-router-dom): replace `useRouteMatch` to `useParams` * refactor(react-router-dom & dumi): fix & umi document bug * refactor(react-router-dom): `useRoutes` Optimize `` code * refactor(react-router-dom): update `Route` types and docs * refactor(react-router-dom): optimize RouteSwitch code * refactor(react-router-dom): `useLocation` no generics type * refactor(react-router-dom): add `less v3.9.0` to `resolutions` to solve the error of `gulp-less` * refactor(react-router-dom): fix `` `props.routes` as an array is not handled * chore: upgrade `dumi` and refactor docs * fix: completed code review, add `targets` to solve browser compatibility & removed `chainWebpack` * refactor(dumi): upgraded dumi under `packages/core/client` * refactor(dumi): delete `packages/core/dumi-theme-nocobase` * refactor(dumi): degrade `react` & replace `dumi-theme-antd` to `dumi-theme-nocobase` * refactor(dumi): solve conflicts between multiple dumi applications * fix: login page error in react 17 * refactor(dumi): remove less resolutions * refactor(dumi): umi add `msfu: true` config * fix: merge bug * fix: self code review * fix: code reivew and test bug * refactor: upgrade react to 18 * refactor: degrade react types to 17 * chore: fix ci error * fix: support routerBase & fix workflow page params * fix(doc): menu externel link * fix: build error * fix: delete * fix: vitest error * fix: react-router new code replace * fix: vitest markdown error * fix: title is none when refresh * fix: merge error * fix: sidebar width is wrong * fix: useProps error * fix: side-menu-width * fix: menu selectId is wrong & useProps is string * fix: menu selected first default & side menu hide when change * fix: test error & v0.10 change log * fix: new compnent doc modify * fix: set umi `fastRefresh=false` * refactor: application v2 * fix: improve code * fix: bug * fix: page = 0 error * fix: workflow navigate error * feat: plugin manager * fix: afterAdd * feat: complete basic functional refactor * fix: performance Application * feat: support client and server build * refactor: nocobase build-in plugin and providers * fix: server can't start * refactor: all plugins package `Prodiver` change to `Plugin` * feat: nested router and change mobile client * feat: delete application-v1 and router-switch * feat: improve routes * fix: change mobile not nested * feat: delete RouteSwitchContext and change buildin Provider to Plugin * feat: delete RouteSwitchContext plugins * fix: refactor SchemaComponentOptions * feat: improve SchemaComponentOptions * fix: add useAdminSchemaUid * fix: merge master error * fix: vitest error * fix: bug * feat: bugs * fix: improve code * fix: restore code * feat: vitest * fix: bugs * fix: bugs * docs: update doc * feat: improve code * feat: add docs and imporve code * fix: bugs * feat: add tests * fix: remove deps * fix: muti app router error * fix: router error * fix: workflow error * fix: cli error * feat: change NoCobase -> Nocobase * fix: code review * fix: type error * fix: cli error and plugin demo * feat: update doc theme * fix: build error * fix: mobile router * fix: code rewview * fix: bug * fix: test bug * fix: bug * refactor: add the "client" directory to all plugins * refactor: modify samples client and plugin template * fix: merge error * fix: add files in package.json * refactor: add README to files in package.json * fix: adjust plugins depencies * refactor: completing plugins' devDependencies and dependencies * fix: bug * refactor: remove @emotion/css * refactor: jsonwebtoken deps * refactor: remove sequelize * refactor: dayjs and moment deps * fix: bugs * fix: bug * fix: cycle detect * fix: merge bug * feat: new plugin bug * fix: lang bug * fix: dynamic import bug * refactor: plugins and example add father config * feat: improve code * fix: add AppSpin and AppError components * Revert "refactor: plugins and example add father config" This reverts commit 483315bca5524e4b8cbbb20cbad77986f081089d. # Conflicts: # packages/plugins/auth/package.json # packages/plugins/multi-app-manager/package.json # packages/samples/command/package.json # packages/samples/custom-collection-template/package.json # packages/samples/ratelimit/package.json # packages/samples/shop-actions/package.json # packages/samples/shop-events/package.json # packages/samples/shop-modeling/package.json * feat: update doc --------- Co-authored-by: chenos --- .eslintignore | 1 + .eslintrc | 2 + .prettierignore | 1 + docs/config.ts | 3 +- docs/en-US/api/client/application.md | 1 - docs/en-US/api/client/route-switch.md | 74 ---- docs/en-US/api/client/router.md | 180 ++++++++ docs/en-US/development/client/index.md | 1 - docs/en-US/development/client/ui-router.md | 82 ++-- docs/en-US/welcome/release/v11-changelog.md | 100 +++++ docs/tr-TR/api/client/application.md | 3 +- docs/tr-TR/api/client/route-switch.md | 74 ---- docs/tr-TR/api/client/router.md | 180 ++++++++ docs/tr-TR/development/client/index.md | 1 - docs/tr-TR/development/client/ui-router.md | 82 ++-- docs/tr-TR/welcome/release/v11-changelog.md | 100 +++++ docs/zh-CN/api/client/application.md | 3 +- docs/zh-CN/api/client/route-switch.md | 74 ---- docs/zh-CN/api/client/router.md | 183 +++++++++ docs/zh-CN/development/client/index.md | 1 - docs/zh-CN/development/client/ui-router.md | 82 ++-- docs/zh-CN/welcome/release/v11-changelog.md | 120 ++++++ package.json | 3 +- packages/app/client/.umirc.ts | 3 +- packages/app/client/public/set-router.js | 2 - packages/app/client/src/pages/index.tsx | 4 +- packages/app/client/src/plugins/acl.ts | 2 + packages/app/client/src/plugins/client.ts | 1 + .../client/src/plugins/collection-manager.ts | 1 + .../app/client/src/plugins/error-handler.ts | 1 + .../app/client/src/plugins/system-settings.ts | 1 + .../client/src/plugins/ui-routes-storage.ts | 1 + .../client/src/plugins/ui-schema-storage.ts | 1 + packages/core/build/src/build.ts | 17 +- packages/core/build/src/getUserConfig.ts | 4 +- packages/core/build/src/utils/index.ts | 8 +- .../core/cli/templates/plugin/client.d.ts | 6 +- packages/core/cli/templates/plugin/client.js | 66 +-- .../cli/templates/plugin/package.json.tpl | 11 + .../core/cli/templates/plugin/server.d.ts | 6 +- packages/core/cli/templates/plugin/server.js | 66 +-- .../cli/templates/plugin/src/client/index.tsx | 8 - .../templates/plugin/src/client/index.tsx.tpl | 21 + packages/core/client/docs/develop.md | 2 +- packages/core/client/docs/intro.md | 204 ++-------- packages/core/client/package.json | 6 +- packages/core/client/src/acl/ACLProvider.tsx | 1 + packages/core/client/src/acl/index.ts | 18 + .../client/src/antd-config-provider/index.tsx | 7 + .../client/src/application-v2/Application.tsx | 91 ----- .../core/client/src/application-v2/Plugin.ts | 30 -- .../src/application-v2/PluginManager.ts | 83 ---- .../core/client/src/application-v2/Router.ts | 67 --- .../components/AppComponent.tsx | 24 -- .../components/MainComponent.tsx | 9 - .../components/RouterProvider.tsx | 119 ------ .../src/application-v2/components/index.ts | 13 - .../client/src/application-v2/compose.tsx | 18 - .../client/src/application-v2/hooks/index.ts | 3 - .../src/application-v2/hooks/useLoad.ts | 16 - .../core/client/src/application-v2/index.md | 3 - .../core/client/src/application-v2/index.ts | 3 - .../core/client/src/application-v2/types.ts | 37 -- .../client/src/application/Application.tsx | 268 ++++++------ .../core/client/src/application/Plugin.ts | 22 + .../client/src/application/PluginManager.ts | 59 +++ .../client/src/application/RouterManager.tsx | 139 +++++++ .../__tests__/Application.test.tsx | 340 ++++++++++++++++ .../src/application/__tests__/Plugin.test.ts | 99 +++++ .../__tests__/RouterManager.test.tsx | 198 +++++++++ .../__snapshots__/compose.test.tsx.snap | 77 ---- .../application/__tests__/compose.test.tsx | 95 ----- .../src/application/__tests__/hooks.test.tsx | 62 +++ .../src/application/__tests__/utils.test.tsx | 68 ++++ .../application/components/AppComponent.tsx | 25 ++ .../application/components/BlankComponent.tsx | 3 + .../application/components/MainComponent.tsx | 11 + .../components/RouterContextCleaner.tsx | 17 + .../components/defaultComponents.tsx | 16 + .../src/application/components/index.ts | 4 + .../core/client/src/application/compose.tsx | 18 - .../context.ts | 4 +- .../demos/demo1.tsx | 42 +- .../src/application/demos/demo1/Hello.tsx | 23 -- .../demos/demo1/RouteSchemaComponent.tsx | 7 - .../src/application/demos/demo1/index.tsx | 23 -- .../src/application/demos/demo1/routes.ts | 28 -- .../client/src/application/demos/demo2.tsx | 99 +++++ .../src/application/demos/demo2/apiClient.ts | 10 - .../src/application/demos/demo2/index.tsx | 58 --- .../src/application/demos/demo2/mock.ts | 197 --------- .../client/src/application/demos/demo3.tsx | 10 + .../client/src/application/hooks/index.ts | 4 + .../hooks/useApp.ts | 3 +- .../src/application/hooks/useAppPluginLoad.ts | 19 + .../client/src/application/hooks/usePlugin.ts | 9 + .../hooks/useRouter.ts | 0 packages/core/client/src/application/index.md | 385 +++++++++++++++++- packages/core/client/src/application/index.ts | 5 + .../core/client/src/application/index.tsx | 2 - .../client/src/application/utils/index.tsx | 39 ++ packages/core/client/src/auth/index.ts | 13 +- .../BlockSchemaComponentProvider.tsx | 49 ++- .../core/client/src/document-title/index.tsx | 7 + packages/core/client/src/index.ts | 3 +- packages/core/client/src/locale/zh_CN.ts | 1 + .../src/nocobase-buildin-plugin/index.tsx | 125 ++++++ .../core/client/src/plugin-manager/index.ts | 10 +- packages/core/client/src/pm/index.tsx | 68 +++- .../client/src/route-switch/RouteSwitch.tsx | 95 ----- .../src/route-switch/RouteSwitchProvider.tsx | 20 - .../__tests__/RouteSwitch.test.tsx | 32 -- .../__snapshots__/RouteSwitch.test.tsx.snap | 9 - .../route-switch/antd/admin-layout/index.tsx | 20 +- .../core/client/src/route-switch/context.ts | 11 - .../client/src/route-switch/demos/demo1.tsx | 68 ---- .../core/client/src/route-switch/hooks.ts | 23 -- .../core/client/src/route-switch/index.md | 9 - .../core/client/src/route-switch/index.tsx | 5 - .../core/client/src/route-switch/types.ts | 31 -- .../antd/AntdSchemaComponentProvider.tsx | 25 +- .../antd/error-fallback/ErrorFallback.tsx | 6 +- .../antd/filter/demos/demo6.tsx | 2 +- .../core/SchemaComponentOptions.tsx | 2 +- .../src/schema-component/core/index.tsx | 18 + .../src/schema-initializer/demos/demo4.tsx | 2 +- .../client/src/schema-initializer/index.ts | 27 +- .../SchemaTemplateManagerProvider.tsx | 51 +-- .../core/client/src/schema-templates/index.ts | 1 - .../core/client/src/system-settings/index.tsx | 8 + packages/core/database/src/index.ts | 23 +- packages/core/devtools/package.json | 1 + packages/core/evaluators/client.d.ts | 5 +- packages/core/evaluators/server.d.ts | 5 +- packages/core/sdk/src/APIClient.ts | 4 +- packages/core/utils/package.json | 1 + packages/core/utils/src/client.ts | 5 +- packages/core/utils/src/index.ts | 6 +- packages/plugins/acl/client.d.ts | 3 + packages/plugins/acl/client.js | 1 + packages/plugins/acl/package.json | 27 +- packages/plugins/acl/server.d.ts | 3 + packages/plugins/acl/server.js | 1 + packages/plugins/acl/src/client/index.ts | 8 + .../src/{ => server}/__tests__/acl.test.ts | 0 .../{ => server}/__tests__/actions.test.ts | 0 .../__tests__/association-field.test.ts | 0 .../__tests__/configuration.test.ts | 0 .../__tests__/list-action.test.ts | 0 .../{ => server}/__tests__/middleware.test.ts | 0 .../src/{ => server}/__tests__/own.test.ts | 0 .../acl/src/{ => server}/__tests__/prepare.ts | 2 +- .../{ => server}/__tests__/role-check.test.ts | 0 .../__tests__/role-resource.test.ts | 0 .../{ => server}/__tests__/role-user.test.ts | 4 +- .../src/{ => server}/__tests__/role.test.ts | 0 .../src/{ => server}/__tests__/scope.test.ts | 0 .../__tests__/setCurrentRole.test.ts | 0 .../{ => server}/__tests__/snippets.test.ts | 0 .../src/{ => server}/__tests__/users.test.ts | 0 .../__tests__/write-role-to-acl.test.ts | 0 .../{ => server}/actions/available-actions.ts | 0 .../src/{ => server}/actions/role-check.ts | 0 .../{ => server}/actions/role-collections.ts | 0 .../actions/user-setDefaultRole.ts | 0 .../{ => server}/collections/roles-users.ts | 0 .../acl/src/{ => server}/collections/roles.ts | 0 .../collections/rolesResources.ts | 0 .../collections/rolesResourcesActions.ts | 0 .../collections/rolesResourcesScopes.ts | 0 .../acl/src/{ => server}/collections/users.ts | 0 packages/plugins/acl/src/server/index.ts | 1 + .../middlewares/setCurrentRole.ts | 0 .../20221214072638-set-role-snippets.ts | 0 .../acl/src/{ => server}/model/RoleModel.ts | 0 .../model/RoleResourceActionModel.ts | 0 .../{ => server}/model/RoleResourceModel.ts | 0 .../plugins/acl/src/{ => server}/server.ts | 2 +- packages/plugins/api-keys/package.json | 28 +- .../plugins/api-keys/src/client/index.tsx | 10 +- packages/plugins/audit-logs/client.d.ts | 5 +- packages/plugins/audit-logs/client.js | 31 +- packages/plugins/audit-logs/package.json | 25 +- packages/plugins/audit-logs/server.d.ts | 5 +- packages/plugins/audit-logs/server.js | 31 +- .../plugins/audit-logs/src/client/index.ts | 11 +- packages/plugins/auth/client.d.ts | 5 +- packages/plugins/auth/package.json | 20 +- packages/plugins/auth/server.d.ts | 5 +- .../plugins/auth/src/client/AuthProvider.tsx | 41 ++ packages/plugins/auth/src/client/index.tsx | 49 +-- packages/plugins/charts/client.d.ts | 5 +- packages/plugins/charts/client.js | 31 +- packages/plugins/charts/package.json | 30 +- packages/plugins/charts/server.d.ts | 5 +- packages/plugins/charts/server.js | 31 +- .../src/client/ChartBlockEngineDesigner.tsx | 2 +- .../src/client/ChartBlockInitializer.tsx | 2 +- .../charts/src/client/DataSetPreviewTable.tsx | 13 +- packages/plugins/charts/src/client/index.tsx | 17 +- .../charts/src/client/select/CustomSelect.tsx | 3 +- .../charts/src/client/select/shared.ts | 5 +- .../charts/src/client/settings/queryTypes.ts | 5 +- packages/plugins/china-region/client.d.ts | 5 +- packages/plugins/china-region/client.js | 31 +- packages/plugins/china-region/package.json | 20 +- packages/plugins/china-region/server.d.ts | 5 +- packages/plugins/china-region/server.js | 31 +- .../src/client/ChinaRegionProvider.tsx | 69 ++++ .../plugins/china-region/src/client/index.tsx | 89 +--- packages/plugins/client/client.d.ts | 3 + packages/plugins/client/client.js | 1 + packages/plugins/client/package.json | 22 +- packages/plugins/client/server.d.ts | 3 + packages/plugins/client/server.js | 1 + packages/plugins/client/src/client/index.ts | 7 + .../plugins/client/src/{ => server}/antd.ts | 0 .../plugins/client/src/{ => server}/cron.ts | 0 .../client/src/{ => server}/cronstrue.ts | 0 packages/plugins/client/src/server/index.ts | 1 + .../client/src/{ => server}/locale/en-US.json | 0 .../client/src/{ => server}/locale/es-ES.json | 0 .../client/src/{ => server}/locale/index.ts | 0 .../client/src/{ => server}/locale/pt-BR.json | 0 .../client/src/{ => server}/locale/uk-UA.json | 0 .../client/src/{ => server}/locale/zh-CN.json | 0 .../20230620203216-admin-ui-schema-uid.ts | 0 .../client/src/{ => server}/moment-locale.ts | 0 .../client/src/{ => server}/resource.ts | 0 .../plugins/client/src/{ => server}/server.ts | 12 +- .../plugins/collection-manager/client.d.ts | 3 + packages/plugins/collection-manager/client.js | 1 + .../plugins/collection-manager/package.json | 23 +- .../plugins/collection-manager/server.d.ts | 3 + packages/plugins/collection-manager/server.js | 1 + .../collection-manager/src/client/index.ts | 7 + .../plugins/collection-manager/src/index.ts | 3 - .../src/{ => server}/__tests__/action.test.ts | 0 .../reference-integerity-check.test.ts | 0 .../__tests__/beforeInitOptions.test.ts | 0 .../__tests__/collection-categories.test.ts | 0 .../__tests__/collections.repository.test.ts | 0 .../field-options/default-value.test.ts | 0 .../__tests__/field-options/indexes.test.ts | 0 .../__tests__/fields.repository.test.ts | 0 .../__tests__/fields/belongs-to-many.test.ts | 0 .../__tests__/fields/belongsTo.test.ts | 0 .../__tests__/fields/hasMany.test.ts | 0 .../__tests__/fields/hasOne.test.ts | 0 .../__tests__/fields/reverseField.test.ts | 0 .../http-api/belongs-to-many.test.ts | 0 .../__tests__/http-api/collections.test.ts | 0 .../__tests__/http-api/find.test.ts | 0 .../http-api/inherited-collection.test.ts | 0 .../__tests__/http-api/recreate.test.ts | 0 .../__tests__/http-api/tree.test.ts | 0 .../http-api/view-collection.test.ts | 0 .../src/{ => server}/__tests__/index.ts | 0 .../inherits/inherited-collection.test.ts | 0 .../inhertied-collection-with-schema.test.ts | 0 ...04151410-update-collections-hidden.test.ts | 0 .../drop-ui-schema-relation.test.ts | 0 .../migrations/update-id-to-bigint.test.ts | 2 +- .../__tests__/reference-integerity.test.ts | 0 .../__tests__/remove-collection.test.ts | 0 .../resources/collections.fields.test.ts | 0 .../__tests__/resources/collections.test.ts | 0 .../src/{ => server}/__tests__/sync.test.ts | 0 .../{ => server}/__tests__/through.test.ts | 0 .../__tests__/view/view-collection.test.ts | 0 .../collections/collectionCategories.ts | 0 .../{ => server}/collections/collections.ts | 0 .../src/{ => server}/collections/fields.ts | 0 .../hooks/afterCreateForForeignKeyField.ts | 0 .../hooks/afterCreateForReverseField.ts | 0 .../hooks/afterDestroyForForeignKeyField.ts | 3 +- .../beforeCreateForChildrenCollection.ts | 0 .../hooks/beforeCreateForReverseField.ts | 0 .../hooks/beforeCreateForViewCollection.ts | 0 .../hooks/beforeDestroyForeignKey.ts | 0 .../{ => server}/hooks/beforeInitOptions.ts | 3 +- .../src/{ => server}/hooks/index.ts | 0 .../collection-manager/src/server/index.ts | 4 + .../20220613103214-alert-sub-table.ts | 0 .../20220704225714-drop-foreign-keys.ts | 0 .../20221101111110-update-foreign-fields.ts | 0 ...0221104151410-update-collections-hidden.ts | 0 .../20221121111110-update-fk-type.ts | 0 .../20221121111113-update-id-to-bigint.ts | 0 .../migrations/20221221103220-timestamps.ts | 0 .../20230225111112-drop-ui-schema-relation.ts | 0 .../20230509111114-alert-ui-schema.ts | 0 .../migrations/20230623145414-number-step.ts | 0 .../migrations/20230704222935-tableoid.ts | 2 +- .../src/{ => server}/models/collection.ts | 5 +- .../src/{ => server}/models/field.ts | 3 +- .../src/{ => server}/models/index.ts | 0 .../repositories/collection-repository.ts | 2 +- .../src/{ => server}/repositories/index.ts | 0 .../{ => server}/resourcers/collections.ts | 0 .../src/{ => server}/resourcers/views.ts | 0 .../src/{ => server}/server.ts | 17 +- .../plugins/data-visualization/package.json | 42 +- .../src/client/Settings.tsx | 2 +- .../src/client/block/transformers.ts | 2 +- .../data-visualization/src/client/index.tsx | 10 +- packages/plugins/duplicator/client.d.ts | 5 +- packages/plugins/duplicator/client.js | 31 +- packages/plugins/duplicator/package.json | 46 ++- packages/plugins/duplicator/server.d.ts | 5 +- packages/plugins/duplicator/server.js | 31 +- .../src/client/DuplicatorProvider.tsx | 36 ++ .../plugins/duplicator/src/client/index.tsx | 40 +- .../duplicator/src/server/app-migrator.ts | 2 +- .../plugins/duplicator/src/server/dumper.ts | 5 +- .../src/server/field-value-writer.ts | 2 +- .../plugins/duplicator/src/server/utils.ts | 2 +- packages/plugins/error-handler/client.d.ts | 3 + packages/plugins/error-handler/client.js | 1 + packages/plugins/error-handler/package.json | 21 +- packages/plugins/error-handler/server.d.ts | 3 + packages/plugins/error-handler/server.js | 1 + .../plugins/error-handler/src/client/index.ts | 7 + packages/plugins/error-handler/src/index.ts | 2 +- .../__tests__/render-error.test.ts | 0 .../src/{ => server}/error-handler.ts | 0 .../plugins/error-handler/src/server/index.ts | 1 + .../src/{ => server}/locale/en_US.ts | 0 .../src/{ => server}/locale/es-ES.ts | 0 .../src/{ => server}/locale/ja_JP.ts | 0 .../src/{ => server}/locale/pt-BR.ts | 0 .../src/{ => server}/locale/zh_CN.ts | 0 .../error-handler/src/{ => server}/server.ts | 4 +- .../plugins/excel-formula-field/client.d.ts | 5 +- .../plugins/excel-formula-field/client.js | 31 +- .../plugins/excel-formula-field/package.json | 19 +- .../plugins/excel-formula-field/server.d.ts | 5 +- .../plugins/excel-formula-field/server.js | 31 +- .../src/client/ExcelFormulaFieldProvider.tsx | 36 ++ .../excel-formula-field/src/client/index.tsx | 44 +- .../src/server/excel-formula-field.ts | 3 +- packages/plugins/export/client.d.ts | 5 +- packages/plugins/export/client.js | 31 +- packages/plugins/export/package.json | 35 +- packages/plugins/export/server.d.ts | 5 +- packages/plugins/export/server.js | 31 +- packages/plugins/export/src/client/index.ts | 11 +- .../export/src/client/useExportAction.ts | 4 +- .../plugins/export/src/client/useShared.ts | 3 +- packages/plugins/file-manager/client.d.ts | 5 +- packages/plugins/file-manager/client.js | 31 +- packages/plugins/file-manager/package.json | 38 +- packages/plugins/file-manager/server.d.ts | 5 +- packages/plugins/file-manager/server.js | 31 +- .../src/client/FileManagerProvider.tsx | 84 ++++ .../plugins/file-manager/src/client/index.tsx | 90 +--- .../file-manager/src/server/storages/local.ts | 2 +- packages/plugins/formula-field/client.d.ts | 5 +- packages/plugins/formula-field/client.js | 31 +- packages/plugins/formula-field/package.json | 26 +- packages/plugins/formula-field/server.d.ts | 5 +- packages/plugins/formula-field/server.js | 31 +- .../src/client/FormulaFieldProvider.tsx | 62 +++ .../formula-field/src/client/index.tsx | 72 +--- .../src/client/interfaces/formula.tsx | 9 +- .../formula-field/src/server/formula-field.ts | 3 +- .../graph-collection-manager/client.d.ts | 5 +- .../graph-collection-manager/client.js | 31 +- .../graph-collection-manager/package.json | 25 +- .../graph-collection-manager/server.d.ts | 5 +- .../graph-collection-manager/server.js | 31 +- .../src/client/GraphCollectionProvider.tsx | 12 +- .../src/client/GraphCollectionShortcut.tsx | 5 +- .../src/client/GraphDrawPage.tsx | 9 +- .../src/client/action-hooks.tsx | 6 +- .../components/EditCollectionAction.tsx | 3 +- .../src/client/components/Entity.tsx | 7 +- .../src/client/components/FieldSummary.tsx | 3 +- .../src/client/index.tsx | 11 +- .../src/client/style.tsx | 2 +- .../src/client/utils.tsx | 4 +- packages/plugins/iframe-block/client.d.ts | 5 +- packages/plugins/iframe-block/client.js | 31 +- packages/plugins/iframe-block/package.json | 26 +- packages/plugins/iframe-block/server.d.ts | 5 +- packages/plugins/iframe-block/server.js | 31 +- ...lockPlugin.tsx => IframeBlockProvider.tsx} | 2 +- .../plugins/iframe-block/src/client/index.ts | 11 +- packages/plugins/import/client.d.ts | 5 +- packages/plugins/import/client.js | 31 +- packages/plugins/import/package.json | 32 +- packages/plugins/import/server.d.ts | 5 +- packages/plugins/import/server.js | 31 +- .../src/client/ImportActionInitializer.tsx | 3 +- .../plugins/import/src/client/ImportModal.tsx | 2 +- packages/plugins/import/src/client/index.ts | 12 +- .../import/src/client/useImportAction.ts | 10 +- .../plugins/import/src/client/useShared.ts | 3 +- .../plugins/import/src/server/utils/index.ts | 4 +- .../import/src/server/utils/transform.ts | 5 +- packages/plugins/map/client.d.ts | 5 +- packages/plugins/map/client.js | 31 +- packages/plugins/map/package.json | 44 +- packages/plugins/map/server.d.ts | 5 +- packages/plugins/map/server.js | 31 +- .../map/src/client/block/MapBlockDesigner.tsx | 4 +- .../map/src/client/components/AMap/Block.tsx | 2 +- .../map/src/client/components/AMap/Map.tsx | 5 +- .../map/src/client/components/AMap/Search.tsx | 2 +- .../map/src/client/components/Designer.tsx | 4 +- .../client/components/GoogleMaps/Block.tsx | 2 +- .../src/client/components/GoogleMaps/Map.tsx | 5 +- .../client/components/GoogleMaps/Search.tsx | 4 +- .../plugins/map/src/client/components/Map.tsx | 2 +- packages/plugins/map/src/client/index.tsx | 9 +- .../plugins/map/src/server/fields/circle.ts | 3 +- .../map/src/server/fields/lineString.ts | 5 +- .../plugins/map/src/server/fields/point.ts | 3 +- .../plugins/map/src/server/fields/polygon.ts | 3 +- .../plugins/math-formula-field/client.d.ts | 5 +- packages/plugins/math-formula-field/client.js | 31 +- .../plugins/math-formula-field/package.json | 19 +- .../plugins/math-formula-field/server.d.ts | 5 +- packages/plugins/math-formula-field/server.js | 31 +- .../src/client/MathFormulaFieldProvider.tsx | 32 ++ .../math-formula-field/src/client/index.tsx | 40 +- .../src/server/math-formula-field.ts | 3 +- packages/plugins/mobile-client/client.d.ts | 5 +- packages/plugins/mobile-client/client.js | 31 +- packages/plugins/mobile-client/package.json | 21 +- packages/plugins/mobile-client/server.d.ts | 5 +- packages/plugins/mobile-client/server.js | 31 +- .../src/client/MobileClientProvider.tsx | 41 ++ .../schema/components/container/Container.tsx | 40 +- .../core/schema/components/header/Header.tsx | 3 +- .../core/schema/components/menu/Menu.Item.tsx | 12 +- .../core/schema/components/menu/Menu.tsx | 13 +- .../core/schema/components/page/Page.tsx | 3 +- .../schema/components/settings/Settings.tsx | 3 +- .../schema/components/tab-bar/TabBar.Item.tsx | 9 +- .../core/schema/components/tab-bar/TabBar.tsx | 15 +- .../core/schema/hooks/useSchemaPatch.ts | 4 +- .../client/core/schema/scopes/grid-card.ts | 2 +- .../mobile-client/src/client/devices/iOS6.tsx | 2 +- .../src/client/devices/index.tsx | 2 +- .../mobile-client/src/client/index.tsx | 75 ++-- .../src/client/router/Application.tsx | 4 +- .../src/client/router/InterfaceRouter.tsx | 54 +-- .../src/client/router/RouteSwitchProvider.tsx | 31 -- .../mobile-client/src/client/router/index.ts | 1 - packages/plugins/mobile-client/types.d.ts | 0 .../plugins/multi-app-manager/client.d.ts | 5 +- packages/plugins/multi-app-manager/client.js | 31 +- .../plugins/multi-app-manager/package.json | 28 +- .../plugins/multi-app-manager/server.d.ts | 5 +- packages/plugins/multi-app-manager/server.js | 31 +- ...{index.tsx => MultiAppManagerProvider.tsx} | 3 +- .../multi-app-manager/src/client/index.ts | 11 + .../multi-app-manager/src/server/server.ts | 2 +- .../multi-app-share-collection/client.d.ts | 5 +- .../multi-app-share-collection/client.js | 31 +- .../multi-app-share-collection/package.json | 26 +- .../multi-app-share-collection/server.d.ts | 5 +- .../multi-app-share-collection/server.js | 31 +- .../MultiAppShareCollectionProvider.tsx | 86 ++++ .../src/client/TableTransfer.tsx | 15 +- .../src/client/index.tsx | 92 +---- .../src/server/plugin.ts | 2 +- packages/plugins/notifications/client.d.ts | 3 + packages/plugins/notifications/client.js | 1 + packages/plugins/notifications/package.json | 20 +- packages/plugins/notifications/server.d.ts | 3 + packages/plugins/notifications/server.js | 1 + .../plugins/notifications/src/client/index.ts | 7 + .../__tests__/notifications.test.ts | 5 +- .../collections/notification_logs.ts | 0 .../collections/notification_services.ts | 0 .../{ => server}/collections/notifications.ts | 0 .../plugins/notifications/src/server/index.ts | 1 + .../src/{ => server}/models/Notification.ts | 4 +- .../{ => server}/models/NotificationLog.ts | 0 .../models/NotificationService.ts | 0 .../src/{ => server}/models/index.ts | 0 .../notifications/src/{ => server}/server.ts | 0 packages/plugins/oidc/client.d.ts | 5 +- packages/plugins/oidc/client.js | 31 +- packages/plugins/oidc/package.json | 24 +- packages/plugins/oidc/server.d.ts | 5 +- packages/plugins/oidc/server.js | 31 +- .../plugins/oidc/src/client/OIDCButton.tsx | 3 +- .../plugins/oidc/src/client/OidcProvider.tsx | 15 + packages/plugins/oidc/src/client/index.tsx | 21 +- .../oidc/src/server/__tests__/oidc.test.ts | 2 +- packages/plugins/saml/client.d.ts | 5 +- packages/plugins/saml/client.js | 31 +- packages/plugins/saml/package.json | 22 +- packages/plugins/saml/server.d.ts | 5 +- packages/plugins/saml/server.js | 31 +- .../plugins/saml/src/client/SAMLButton.tsx | 5 +- .../plugins/saml/src/client/SamlProvider.tsx | 15 + packages/plugins/saml/src/client/index.tsx | 21 +- .../saml/src/server/__tests__/saml.test.ts | 4 +- packages/plugins/sequence-field/client.d.ts | 5 +- packages/plugins/sequence-field/client.js | 31 +- packages/plugins/sequence-field/package.json | 31 +- packages/plugins/sequence-field/server.d.ts | 5 +- packages/plugins/sequence-field/server.js | 31 +- .../src/client/SequenceFieldProvider.tsx | 23 ++ .../sequence-field/src/client/index.tsx | 29 +- .../sequence-field/src/client/sequence.tsx | 6 +- .../server/__tests__/sequence-field.test.ts | 32 +- .../src/server/fields/sequence-field.ts | 21 +- packages/plugins/sms-auth/client.d.ts | 5 +- packages/plugins/sms-auth/package.json | 29 +- packages/plugins/sms-auth/server.d.ts | 5 +- .../sms-auth/src/client/SmsAuthProvider.tsx | 17 + .../sms-auth/src/client/VerificationCode.tsx | 8 +- .../plugins/sms-auth/src/client/index.tsx | 25 +- packages/plugins/snapshot-field/client.d.ts | 5 +- packages/plugins/snapshot-field/client.js | 31 +- packages/plugins/snapshot-field/package.json | 27 +- packages/plugins/snapshot-field/server.d.ts | 5 +- packages/plugins/snapshot-field/server.js | 31 +- .../src/client/SnapshotFieldProvider.tsx | 50 +++ .../snapshot-field/src/client/index.tsx | 58 +-- .../snapshot-field/src/client/interface.ts | 4 +- .../src/server/fields/snapshot-field.ts | 3 +- packages/plugins/system-settings/client.d.ts | 3 + packages/plugins/system-settings/client.js | 1 + packages/plugins/system-settings/package.json | 17 +- packages/plugins/system-settings/server.d.ts | 3 + packages/plugins/system-settings/server.js | 1 + .../system-settings/src/client/index.ts | 7 + .../collections/systemSettings.ts | 0 .../system-settings/src/server/index.ts | 1 + ...20220714204714-update-enabled-languages.ts | 0 .../src/{ => server}/server.ts | 0 .../plugins/ui-routes-storage/client.d.ts | 3 + packages/plugins/ui-routes-storage/client.js | 1 + .../plugins/ui-routes-storage/package.json | 18 +- .../plugins/ui-routes-storage/server.d.ts | 3 + packages/plugins/ui-routes-storage/server.js | 1 + .../ui-routes-storage/src/client/index.ts | 7 + .../src/{ => server}/actions/getAccessible.ts | 0 .../src/{ => server}/collections/uiRoutes.ts | 0 .../ui-routes-storage/src/server/index.ts | 1 + .../src/{ => server}/server.ts | 0 .../plugins/ui-schema-storage/client.d.ts | 3 + packages/plugins/ui-schema-storage/client.js | 1 + .../plugins/ui-schema-storage/package.json | 25 +- .../plugins/ui-schema-storage/server.d.ts | 3 + packages/plugins/ui-schema-storage/server.js | 1 + .../ui-schema-storage/src/client/index.ts | 7 + .../plugins/ui-schema-storage/src/index.ts | 1 - .../src/{ => server}/__tests__/action.test.ts | 0 .../{ => server}/__tests__/fixtures/data.ts | 0 .../__tests__/fixtures/simple-schema.ts | 0 .../20230330214649-filter-form-block.test.ts | 0 .../__tests__/server-hook-impl.test.ts | 0 .../__tests__/server-hook.test.ts | 0 .../__tests__/ui-schema-model.test.ts | 0 .../ui-schema-repository-with-cache.test.ts | 0 .../__tests__/ui-schema-repository.test.ts | 0 .../{ => server}/__tests__/ui-schema.test.ts | 0 .../{ => server}/actions/ui-schema-action.ts | 2 +- .../collections/uiSchemaServerHooks.ts | 0 .../collections/uiSchemaTemplates.ts | 0 .../collections/uiSchemaTreePath.ts | 0 .../src/{ => server}/collections/uiSchemas.ts | 0 .../src/{ => server}/dao/ui_schema_dao.ts | 0 .../{ => server}/dao/ui_schema_node_dao.ts | 0 .../src/{ => server}/helper.ts | 0 .../ui-schema-storage/src/server/index.ts | 3 + .../20230330214649-filter-form-block.ts | 0 .../20230509221649-association-select.ts | 0 .../20230509235247-record-picker.ts | 0 .../migrations/20230510235247-form-field.ts | 0 .../20230522231231-association-field.ts | 0 .../src/{ => server}/model.ts | 0 .../src/{ => server}/repository.ts | 6 +- .../server-hooks/hooks/bind-menu-to-role.ts | 0 .../server-hooks/hooks/factory.ts | 0 .../{ => server}/server-hooks/hooks/index.ts | 0 .../hooks/remove-parents-if-no-children.ts | 0 .../server-hooks/hooks/remove-schema.ts | 0 .../src/{ => server}/server-hooks/index.ts | 0 .../src/{ => server}/server-hooks/model.ts | 0 .../src/{ => server}/server.ts | 0 packages/plugins/users/package.json | 25 +- packages/plugins/users/src/client/index.ts | 7 + packages/plugins/users/src/index.ts | 2 - .../{ => server}/__tests__/actions.test.ts | 2 +- .../src/{ => server}/__tests__/fields.test.ts | 0 .../users/src/{ => server}/__tests__/utils.ts | 2 +- .../users/src/{ => server}/actions/users.ts | 0 .../src/{ => server}/authenticators/index.ts | 0 .../{ => server}/authenticators/password.ts | 0 .../src/{ => server}/collections/users.ts | 0 packages/plugins/users/src/server/index.ts | 3 + .../users/src/{ => server}/jwt-service.ts | 0 .../users/src/{ => server}/locale/en-US.ts | 0 .../users/src/{ => server}/locale/es-ES.ts | 0 .../users/src/{ => server}/locale/index.ts | 0 .../users/src/{ => server}/locale/ja-JP.ts | 0 .../users/src/{ => server}/locale/pt-BR.ts | 0 .../users/src/{ => server}/locale/zh-CN.ts | 0 .../src/{ => server}/middlewares/check.ts | 0 .../src/{ => server}/middlewares/index.ts | 0 .../{ => server}/middlewares/parseToken.ts | 0 .../20220818072639-add-users-phone.ts | 0 .../plugins/users/src/{ => server}/server.ts | 0 packages/plugins/verification/client.d.ts | 5 +- packages/plugins/verification/client.js | 31 +- packages/plugins/verification/package.json | 29 +- packages/plugins/verification/server.d.ts | 5 +- packages/plugins/verification/server.js | 31 +- .../src/client/VerificationProvider.tsx | 39 ++ .../plugins/verification/src/client/index.tsx | 45 +- .../src/server/actions/verifications.ts | 10 +- packages/plugins/workflow/client.d.ts | 5 +- packages/plugins/workflow/client.js | 31 +- packages/plugins/workflow/package.json | 41 +- packages/plugins/workflow/server.d.ts | 5 +- packages/plugins/workflow/server.js | 31 +- .../plugins/workflow/src/client/AddButton.tsx | 3 +- .../plugins/workflow/src/client/Branch.tsx | 4 +- .../workflow/src/client/CanvasContent.tsx | 5 +- .../workflow/src/client/ExecutionCanvas.tsx | 22 +- .../workflow/src/client/ExecutionPage.tsx | 3 +- .../workflow/src/client/WorkflowCanvas.tsx | 2 +- .../workflow/src/client/WorkflowPage.tsx | 3 +- .../workflow/src/client/WorkflowProvider.tsx | 63 +-- .../client/components/CollectionFieldset.tsx | 11 +- .../src/client/components/Duration.tsx | 2 +- .../src/client/components/NodeDescription.tsx | 4 +- .../client/components/RadioWithTooltip.tsx | 8 +- .../src/client/components/ValueBlock.tsx | 7 +- .../components/renderEngineReference.tsx | 3 +- .../plugins/workflow/src/client/index.tsx | 53 ++- .../workflow/src/client/nodes/calculation.tsx | 11 +- .../workflow/src/client/nodes/condition.tsx | 7 +- .../workflow/src/client/nodes/index.tsx | 47 +-- .../workflow/src/client/nodes/loop.tsx | 12 +- .../src/client/nodes/manual/ModeConfig.tsx | 11 +- .../src/client/nodes/manual/SchemaConfig.tsx | 32 +- .../src/client/nodes/manual/WorkflowTodo.tsx | 29 +- .../manual/WorkflowTodoBlockInitializer.tsx | 6 +- .../src/client/nodes/manual/forms/custom.tsx | 18 +- .../workflow/src/client/nodes/parallel.tsx | 11 +- .../workflow/src/client/schemas/collection.ts | 3 +- .../plugins/workflow/src/client/style.tsx | 2 +- .../workflow/src/client/triggers/index.tsx | 19 +- .../client/triggers/schedule/EndsByField.tsx | 5 +- .../src/client/triggers/schedule/OnField.tsx | 7 +- .../client/triggers/schedule/RepeatField.tsx | 3 +- .../triggers/schedule/ScheduleConfig.tsx | 17 +- .../plugins/workflow/src/server/Processor.ts | 3 +- .../workflow/src/server/__tests__/index.ts | 8 +- .../workflow/src/server/actions/nodes.ts | 3 +- .../src/server/fields/expression-field.ts | 4 +- .../src/server/instructions/aggregate.ts | 6 +- .../20230221162902-jsonb-to-json.ts | 2 +- .../20230411034722-manual-multi-form.ts | 6 +- .../workflow/src/server/models/Execution.ts | 5 +- .../workflow/src/server/models/FlowNode.ts | 3 +- .../plugins/workflow/src/server/models/Job.ts | 3 +- .../workflow/src/server/models/Workflow.ts | 7 +- .../workflow/src/server/triggers/schedule.ts | 2 +- packages/presets/nocobase/client.d.ts | 3 + packages/presets/nocobase/client.js | 1 + packages/presets/nocobase/package.json | 3 +- packages/presets/nocobase/server.d.ts | 3 + packages/presets/nocobase/server.js | 1 + packages/presets/nocobase/src/client/index.ts | 40 ++ packages/presets/nocobase/src/index.ts | 131 +----- packages/presets/nocobase/src/server/index.ts | 130 ++++++ .../migrations/2022-del-sample-plugins.ts | 0 packages/samples/command/client.d.ts | 5 +- packages/samples/command/client.js | 31 +- packages/samples/command/package.json | 18 +- packages/samples/command/server.d.ts | 5 +- packages/samples/command/server.js | 31 +- packages/samples/command/src/client/index.tsx | 11 +- packages/samples/custom-block/client.d.ts | 5 +- packages/samples/custom-block/client.js | 31 +- packages/samples/custom-block/package.json | 17 +- packages/samples/custom-block/server.d.ts | 5 +- packages/samples/custom-block/server.js | 31 +- .../samples/custom-block/src/client/index.tsx | 24 +- .../custom-collection-template/client.d.ts | 5 +- .../custom-collection-template/client.js | 31 +- .../custom-collection-template/package.json | 13 +- .../src/client/index.tsx | 12 +- packages/samples/custom-page/client.d.ts | 5 +- packages/samples/custom-page/client.js | 31 +- packages/samples/custom-page/package.json | 14 +- packages/samples/custom-page/server.d.ts | 5 +- packages/samples/custom-page/server.js | 31 +- .../samples/custom-page/src/client/index.tsx | 28 +- .../samples/custom-signup-page/client.d.ts | 5 +- packages/samples/custom-signup-page/client.js | 31 +- .../samples/custom-signup-page/package.json | 15 +- .../samples/custom-signup-page/server.d.ts | 5 +- packages/samples/custom-signup-page/server.js | 31 +- .../custom-signup-page/src/client/index.tsx | 22 +- packages/samples/hello/client.d.ts | 5 +- packages/samples/hello/client.js | 31 +- packages/samples/hello/package.json | 23 +- packages/samples/hello/server.d.ts | 5 +- packages/samples/hello/server.js | 31 +- packages/samples/hello/src/client/index.tsx | 13 +- packages/samples/ratelimit/client.d.ts | 5 +- packages/samples/ratelimit/client.js | 31 +- packages/samples/ratelimit/package.json | 13 +- packages/samples/ratelimit/server.d.ts | 5 +- packages/samples/ratelimit/server.js | 31 +- .../samples/ratelimit/src/client/index.tsx | 11 +- packages/samples/shop-actions/client.d.ts | 5 +- packages/samples/shop-actions/client.js | 31 +- packages/samples/shop-actions/package.json | 18 +- packages/samples/shop-actions/server.d.ts | 5 +- packages/samples/shop-actions/server.js | 31 +- .../samples/shop-actions/src/client/index.tsx | 11 +- packages/samples/shop-events/client.d.ts | 5 +- packages/samples/shop-events/client.js | 31 +- packages/samples/shop-events/package.json | 18 +- packages/samples/shop-events/server.d.ts | 5 +- packages/samples/shop-events/server.js | 31 +- .../samples/shop-events/src/client/index.tsx | 11 +- packages/samples/shop-i18n/client.d.ts | 5 +- packages/samples/shop-i18n/client.js | 31 +- packages/samples/shop-i18n/package.json | 21 +- packages/samples/shop-i18n/server.d.ts | 5 +- packages/samples/shop-i18n/server.js | 31 +- .../samples/shop-i18n/src/client/index.tsx | 17 +- packages/samples/shop-modeling/client.d.ts | 5 +- packages/samples/shop-modeling/client.js | 31 +- packages/samples/shop-modeling/package.json | 19 +- packages/samples/shop-modeling/server.d.ts | 5 +- packages/samples/shop-modeling/server.js | 31 +- .../shop-modeling/src/client/index.tsx | 11 +- .../src/server/fields/SnowflakeField.ts | 5 +- yarn.lock | 34 +- 743 files changed, 6253 insertions(+), 6165 deletions(-) delete mode 100644 docs/en-US/api/client/route-switch.md create mode 100644 docs/en-US/api/client/router.md create mode 100644 docs/en-US/welcome/release/v11-changelog.md delete mode 100644 docs/tr-TR/api/client/route-switch.md create mode 100644 docs/tr-TR/api/client/router.md create mode 100644 docs/tr-TR/welcome/release/v11-changelog.md delete mode 100644 docs/zh-CN/api/client/route-switch.md create mode 100644 docs/zh-CN/api/client/router.md create mode 100644 docs/zh-CN/welcome/release/v11-changelog.md delete mode 100644 packages/app/client/public/set-router.js create mode 100644 packages/app/client/src/plugins/acl.ts create mode 100644 packages/app/client/src/plugins/client.ts create mode 100644 packages/app/client/src/plugins/collection-manager.ts create mode 100644 packages/app/client/src/plugins/error-handler.ts create mode 100644 packages/app/client/src/plugins/system-settings.ts create mode 100644 packages/app/client/src/plugins/ui-routes-storage.ts create mode 100644 packages/app/client/src/plugins/ui-schema-storage.ts delete mode 100644 packages/core/cli/templates/plugin/src/client/index.tsx create mode 100644 packages/core/cli/templates/plugin/src/client/index.tsx.tpl delete mode 100644 packages/core/client/src/application-v2/Application.tsx delete mode 100644 packages/core/client/src/application-v2/Plugin.ts delete mode 100644 packages/core/client/src/application-v2/PluginManager.ts delete mode 100644 packages/core/client/src/application-v2/Router.ts delete mode 100644 packages/core/client/src/application-v2/components/AppComponent.tsx delete mode 100644 packages/core/client/src/application-v2/components/MainComponent.tsx delete mode 100644 packages/core/client/src/application-v2/components/RouterProvider.tsx delete mode 100644 packages/core/client/src/application-v2/components/index.ts delete mode 100644 packages/core/client/src/application-v2/compose.tsx delete mode 100644 packages/core/client/src/application-v2/hooks/index.ts delete mode 100644 packages/core/client/src/application-v2/hooks/useLoad.ts delete mode 100644 packages/core/client/src/application-v2/index.md delete mode 100755 packages/core/client/src/application-v2/index.ts delete mode 100644 packages/core/client/src/application-v2/types.ts create mode 100644 packages/core/client/src/application/Plugin.ts create mode 100644 packages/core/client/src/application/PluginManager.ts create mode 100644 packages/core/client/src/application/RouterManager.tsx create mode 100644 packages/core/client/src/application/__tests__/Application.test.tsx create mode 100644 packages/core/client/src/application/__tests__/Plugin.test.ts create mode 100644 packages/core/client/src/application/__tests__/RouterManager.test.tsx delete mode 100644 packages/core/client/src/application/__tests__/__snapshots__/compose.test.tsx.snap delete mode 100644 packages/core/client/src/application/__tests__/compose.test.tsx create mode 100644 packages/core/client/src/application/__tests__/hooks.test.tsx create mode 100644 packages/core/client/src/application/__tests__/utils.test.tsx create mode 100644 packages/core/client/src/application/components/AppComponent.tsx create mode 100644 packages/core/client/src/application/components/BlankComponent.tsx create mode 100644 packages/core/client/src/application/components/MainComponent.tsx create mode 100644 packages/core/client/src/application/components/RouterContextCleaner.tsx create mode 100644 packages/core/client/src/application/components/defaultComponents.tsx create mode 100644 packages/core/client/src/application/components/index.ts delete mode 100644 packages/core/client/src/application/compose.tsx rename packages/core/client/src/{application-v2 => application}/context.ts (65%) rename packages/core/client/src/{application-v2 => application}/demos/demo1.tsx (67%) delete mode 100644 packages/core/client/src/application/demos/demo1/Hello.tsx delete mode 100644 packages/core/client/src/application/demos/demo1/RouteSchemaComponent.tsx delete mode 100644 packages/core/client/src/application/demos/demo1/index.tsx delete mode 100644 packages/core/client/src/application/demos/demo1/routes.ts create mode 100644 packages/core/client/src/application/demos/demo2.tsx delete mode 100644 packages/core/client/src/application/demos/demo2/apiClient.ts delete mode 100644 packages/core/client/src/application/demos/demo2/index.tsx delete mode 100644 packages/core/client/src/application/demos/demo2/mock.ts create mode 100644 packages/core/client/src/application/demos/demo3.tsx create mode 100644 packages/core/client/src/application/hooks/index.ts rename packages/core/client/src/{application-v2 => application}/hooks/useApp.ts (50%) create mode 100644 packages/core/client/src/application/hooks/useAppPluginLoad.ts create mode 100644 packages/core/client/src/application/hooks/usePlugin.ts rename packages/core/client/src/{application-v2 => application}/hooks/useRouter.ts (100%) create mode 100644 packages/core/client/src/application/index.ts delete mode 100644 packages/core/client/src/application/index.tsx create mode 100644 packages/core/client/src/application/utils/index.tsx create mode 100644 packages/core/client/src/nocobase-buildin-plugin/index.tsx delete mode 100644 packages/core/client/src/route-switch/RouteSwitch.tsx delete mode 100644 packages/core/client/src/route-switch/RouteSwitchProvider.tsx delete mode 100644 packages/core/client/src/route-switch/__tests__/RouteSwitch.test.tsx delete mode 100644 packages/core/client/src/route-switch/__tests__/__snapshots__/RouteSwitch.test.tsx.snap delete mode 100644 packages/core/client/src/route-switch/context.ts delete mode 100644 packages/core/client/src/route-switch/demos/demo1.tsx delete mode 100644 packages/core/client/src/route-switch/hooks.ts delete mode 100644 packages/core/client/src/route-switch/index.md delete mode 100644 packages/core/client/src/route-switch/types.ts create mode 100644 packages/plugins/acl/client.d.ts create mode 100644 packages/plugins/acl/client.js create mode 100644 packages/plugins/acl/server.d.ts create mode 100644 packages/plugins/acl/server.js create mode 100644 packages/plugins/acl/src/client/index.ts rename packages/plugins/acl/src/{ => server}/__tests__/acl.test.ts (100%) rename packages/plugins/acl/src/{ => server}/__tests__/actions.test.ts (100%) rename packages/plugins/acl/src/{ => server}/__tests__/association-field.test.ts (100%) rename packages/plugins/acl/src/{ => server}/__tests__/configuration.test.ts (100%) rename packages/plugins/acl/src/{ => server}/__tests__/list-action.test.ts (100%) rename packages/plugins/acl/src/{ => server}/__tests__/middleware.test.ts (100%) rename packages/plugins/acl/src/{ => server}/__tests__/own.test.ts (100%) rename packages/plugins/acl/src/{ => server}/__tests__/prepare.ts (91%) rename packages/plugins/acl/src/{ => server}/__tests__/role-check.test.ts (100%) rename packages/plugins/acl/src/{ => server}/__tests__/role-resource.test.ts (100%) rename packages/plugins/acl/src/{ => server}/__tests__/role-user.test.ts (98%) rename packages/plugins/acl/src/{ => server}/__tests__/role.test.ts (100%) rename packages/plugins/acl/src/{ => server}/__tests__/scope.test.ts (100%) rename packages/plugins/acl/src/{ => server}/__tests__/setCurrentRole.test.ts (100%) rename packages/plugins/acl/src/{ => server}/__tests__/snippets.test.ts (100%) rename packages/plugins/acl/src/{ => server}/__tests__/users.test.ts (100%) rename packages/plugins/acl/src/{ => server}/__tests__/write-role-to-acl.test.ts (100%) rename packages/plugins/acl/src/{ => server}/actions/available-actions.ts (100%) rename packages/plugins/acl/src/{ => server}/actions/role-check.ts (100%) rename packages/plugins/acl/src/{ => server}/actions/role-collections.ts (100%) rename packages/plugins/acl/src/{ => server}/actions/user-setDefaultRole.ts (100%) rename packages/plugins/acl/src/{ => server}/collections/roles-users.ts (100%) rename packages/plugins/acl/src/{ => server}/collections/roles.ts (100%) rename packages/plugins/acl/src/{ => server}/collections/rolesResources.ts (100%) rename packages/plugins/acl/src/{ => server}/collections/rolesResourcesActions.ts (100%) rename packages/plugins/acl/src/{ => server}/collections/rolesResourcesScopes.ts (100%) rename packages/plugins/acl/src/{ => server}/collections/users.ts (100%) create mode 100644 packages/plugins/acl/src/server/index.ts rename packages/plugins/acl/src/{ => server}/middlewares/setCurrentRole.ts (100%) rename packages/plugins/acl/src/{ => server}/migrations/20221214072638-set-role-snippets.ts (100%) rename packages/plugins/acl/src/{ => server}/model/RoleModel.ts (100%) rename packages/plugins/acl/src/{ => server}/model/RoleResourceActionModel.ts (100%) rename packages/plugins/acl/src/{ => server}/model/RoleResourceModel.ts (100%) rename packages/plugins/acl/src/{ => server}/server.ts (99%) create mode 100644 packages/plugins/auth/src/client/AuthProvider.tsx create mode 100644 packages/plugins/china-region/src/client/ChinaRegionProvider.tsx create mode 100644 packages/plugins/client/client.d.ts create mode 100644 packages/plugins/client/client.js create mode 100644 packages/plugins/client/server.d.ts create mode 100644 packages/plugins/client/server.js create mode 100644 packages/plugins/client/src/client/index.ts rename packages/plugins/client/src/{ => server}/antd.ts (100%) rename packages/plugins/client/src/{ => server}/cron.ts (100%) rename packages/plugins/client/src/{ => server}/cronstrue.ts (100%) create mode 100644 packages/plugins/client/src/server/index.ts rename packages/plugins/client/src/{ => server}/locale/en-US.json (100%) rename packages/plugins/client/src/{ => server}/locale/es-ES.json (100%) rename packages/plugins/client/src/{ => server}/locale/index.ts (100%) rename packages/plugins/client/src/{ => server}/locale/pt-BR.json (100%) rename packages/plugins/client/src/{ => server}/locale/uk-UA.json (100%) rename packages/plugins/client/src/{ => server}/locale/zh-CN.json (100%) rename packages/plugins/client/src/{ => server}/migrations/20230620203216-admin-ui-schema-uid.ts (100%) rename packages/plugins/client/src/{ => server}/moment-locale.ts (100%) rename packages/plugins/client/src/{ => server}/resource.ts (100%) rename packages/plugins/client/src/{ => server}/server.ts (96%) create mode 100644 packages/plugins/collection-manager/client.d.ts create mode 100644 packages/plugins/collection-manager/client.js create mode 100644 packages/plugins/collection-manager/server.d.ts create mode 100644 packages/plugins/collection-manager/server.js create mode 100644 packages/plugins/collection-manager/src/client/index.ts rename packages/plugins/collection-manager/src/{ => server}/__tests__/action.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/associations/reference-integerity-check.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/beforeInitOptions.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/collection-categories.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/collections.repository.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/field-options/default-value.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/field-options/indexes.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/fields.repository.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/fields/belongs-to-many.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/fields/belongsTo.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/fields/hasMany.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/fields/hasOne.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/fields/reverseField.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/http-api/belongs-to-many.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/http-api/collections.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/http-api/find.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/http-api/inherited-collection.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/http-api/recreate.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/http-api/tree.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/http-api/view-collection.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/index.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/inherits/inherited-collection.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/inherits/inhertied-collection-with-schema.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/migrations/20221104151410-update-collections-hidden.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/migrations/drop-ui-schema-relation.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/migrations/update-id-to-bigint.test.ts (98%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/reference-integerity.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/remove-collection.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/resources/collections.fields.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/resources/collections.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/sync.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/through.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/__tests__/view/view-collection.test.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/collections/collectionCategories.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/collections/collections.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/collections/fields.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/hooks/afterCreateForForeignKeyField.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/hooks/afterCreateForReverseField.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/hooks/afterDestroyForForeignKeyField.ts (94%) rename packages/plugins/collection-manager/src/{ => server}/hooks/beforeCreateForChildrenCollection.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/hooks/beforeCreateForReverseField.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/hooks/beforeCreateForViewCollection.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/hooks/beforeDestroyForeignKey.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/hooks/beforeInitOptions.ts (96%) rename packages/plugins/collection-manager/src/{ => server}/hooks/index.ts (100%) create mode 100644 packages/plugins/collection-manager/src/server/index.ts rename packages/plugins/collection-manager/src/{ => server}/migrations/20220613103214-alert-sub-table.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/migrations/20220704225714-drop-foreign-keys.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/migrations/20221101111110-update-foreign-fields.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/migrations/20221104151410-update-collections-hidden.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/migrations/20221121111110-update-fk-type.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/migrations/20221121111113-update-id-to-bigint.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/migrations/20221221103220-timestamps.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/migrations/20230225111112-drop-ui-schema-relation.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/migrations/20230509111114-alert-ui-schema.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/migrations/20230623145414-number-step.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/migrations/20230704222935-tableoid.ts (96%) rename packages/plugins/collection-manager/src/{ => server}/models/collection.ts (96%) rename packages/plugins/collection-manager/src/{ => server}/models/field.ts (97%) rename packages/plugins/collection-manager/src/{ => server}/models/index.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/repositories/collection-repository.ts (98%) rename packages/plugins/collection-manager/src/{ => server}/repositories/index.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/resourcers/collections.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/resourcers/views.ts (100%) rename packages/plugins/collection-manager/src/{ => server}/server.ts (98%) create mode 100644 packages/plugins/duplicator/src/client/DuplicatorProvider.tsx create mode 100644 packages/plugins/error-handler/client.d.ts create mode 100644 packages/plugins/error-handler/client.js create mode 100644 packages/plugins/error-handler/server.d.ts create mode 100644 packages/plugins/error-handler/server.js create mode 100644 packages/plugins/error-handler/src/client/index.ts rename packages/plugins/error-handler/src/{ => server}/__tests__/render-error.test.ts (100%) rename packages/plugins/error-handler/src/{ => server}/error-handler.ts (100%) create mode 100644 packages/plugins/error-handler/src/server/index.ts rename packages/plugins/error-handler/src/{ => server}/locale/en_US.ts (100%) rename packages/plugins/error-handler/src/{ => server}/locale/es-ES.ts (100%) rename packages/plugins/error-handler/src/{ => server}/locale/ja_JP.ts (100%) rename packages/plugins/error-handler/src/{ => server}/locale/pt-BR.ts (100%) rename packages/plugins/error-handler/src/{ => server}/locale/zh_CN.ts (100%) rename packages/plugins/error-handler/src/{ => server}/server.ts (94%) create mode 100644 packages/plugins/excel-formula-field/src/client/ExcelFormulaFieldProvider.tsx create mode 100644 packages/plugins/file-manager/src/client/FileManagerProvider.tsx create mode 100644 packages/plugins/formula-field/src/client/FormulaFieldProvider.tsx rename packages/plugins/iframe-block/src/client/{IframeBlockPlugin.tsx => IframeBlockProvider.tsx} (90%) create mode 100644 packages/plugins/math-formula-field/src/client/MathFormulaFieldProvider.tsx create mode 100644 packages/plugins/mobile-client/src/client/MobileClientProvider.tsx delete mode 100644 packages/plugins/mobile-client/src/client/router/RouteSwitchProvider.tsx delete mode 100644 packages/plugins/mobile-client/types.d.ts rename packages/plugins/multi-app-manager/src/client/{index.tsx => MultiAppManagerProvider.tsx} (95%) create mode 100644 packages/plugins/multi-app-manager/src/client/index.ts create mode 100644 packages/plugins/multi-app-share-collection/src/client/MultiAppShareCollectionProvider.tsx create mode 100644 packages/plugins/notifications/client.d.ts create mode 100644 packages/plugins/notifications/client.js create mode 100644 packages/plugins/notifications/server.d.ts create mode 100644 packages/plugins/notifications/server.js create mode 100644 packages/plugins/notifications/src/client/index.ts rename packages/plugins/notifications/src/{ => server}/__tests__/notifications.test.ts (98%) rename packages/plugins/notifications/src/{ => server}/collections/notification_logs.ts (100%) rename packages/plugins/notifications/src/{ => server}/collections/notification_services.ts (100%) rename packages/plugins/notifications/src/{ => server}/collections/notifications.ts (100%) create mode 100644 packages/plugins/notifications/src/server/index.ts rename packages/plugins/notifications/src/{ => server}/models/Notification.ts (95%) rename packages/plugins/notifications/src/{ => server}/models/NotificationLog.ts (100%) rename packages/plugins/notifications/src/{ => server}/models/NotificationService.ts (100%) rename packages/plugins/notifications/src/{ => server}/models/index.ts (100%) rename packages/plugins/notifications/src/{ => server}/server.ts (100%) create mode 100644 packages/plugins/oidc/src/client/OidcProvider.tsx create mode 100644 packages/plugins/saml/src/client/SamlProvider.tsx create mode 100644 packages/plugins/sequence-field/src/client/SequenceFieldProvider.tsx create mode 100644 packages/plugins/sms-auth/src/client/SmsAuthProvider.tsx create mode 100644 packages/plugins/snapshot-field/src/client/SnapshotFieldProvider.tsx create mode 100644 packages/plugins/system-settings/client.d.ts create mode 100644 packages/plugins/system-settings/client.js create mode 100644 packages/plugins/system-settings/server.d.ts create mode 100644 packages/plugins/system-settings/server.js create mode 100644 packages/plugins/system-settings/src/client/index.ts rename packages/plugins/system-settings/src/{ => server}/collections/systemSettings.ts (100%) create mode 100644 packages/plugins/system-settings/src/server/index.ts rename packages/plugins/system-settings/src/{ => server}/migrations/20220714204714-update-enabled-languages.ts (100%) rename packages/plugins/system-settings/src/{ => server}/server.ts (100%) create mode 100644 packages/plugins/ui-routes-storage/client.d.ts create mode 100644 packages/plugins/ui-routes-storage/client.js create mode 100644 packages/plugins/ui-routes-storage/server.d.ts create mode 100644 packages/plugins/ui-routes-storage/server.js create mode 100644 packages/plugins/ui-routes-storage/src/client/index.ts rename packages/plugins/ui-routes-storage/src/{ => server}/actions/getAccessible.ts (100%) rename packages/plugins/ui-routes-storage/src/{ => server}/collections/uiRoutes.ts (100%) create mode 100644 packages/plugins/ui-routes-storage/src/server/index.ts rename packages/plugins/ui-routes-storage/src/{ => server}/server.ts (100%) create mode 100644 packages/plugins/ui-schema-storage/client.d.ts create mode 100644 packages/plugins/ui-schema-storage/client.js create mode 100644 packages/plugins/ui-schema-storage/server.d.ts create mode 100644 packages/plugins/ui-schema-storage/server.js create mode 100644 packages/plugins/ui-schema-storage/src/client/index.ts rename packages/plugins/ui-schema-storage/src/{ => server}/__tests__/action.test.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/__tests__/fixtures/data.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/__tests__/fixtures/simple-schema.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/__tests__/migrations/20230330214649-filter-form-block.test.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/__tests__/server-hook-impl.test.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/__tests__/server-hook.test.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/__tests__/ui-schema-model.test.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/__tests__/ui-schema-repository-with-cache.test.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/__tests__/ui-schema-repository.test.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/__tests__/ui-schema.test.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/actions/ui-schema-action.ts (98%) rename packages/plugins/ui-schema-storage/src/{ => server}/collections/uiSchemaServerHooks.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/collections/uiSchemaTemplates.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/collections/uiSchemaTreePath.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/collections/uiSchemas.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/dao/ui_schema_dao.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/dao/ui_schema_node_dao.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/helper.ts (100%) create mode 100644 packages/plugins/ui-schema-storage/src/server/index.ts rename packages/plugins/ui-schema-storage/src/{ => server}/migrations/20230330214649-filter-form-block.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/migrations/20230509221649-association-select.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/migrations/20230509235247-record-picker.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/migrations/20230510235247-form-field.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/migrations/20230522231231-association-field.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/model.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/repository.ts (99%) rename packages/plugins/ui-schema-storage/src/{ => server}/server-hooks/hooks/bind-menu-to-role.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/server-hooks/hooks/factory.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/server-hooks/hooks/index.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/server-hooks/hooks/remove-parents-if-no-children.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/server-hooks/hooks/remove-schema.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/server-hooks/index.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/server-hooks/model.ts (100%) rename packages/plugins/ui-schema-storage/src/{ => server}/server.ts (100%) create mode 100644 packages/plugins/users/src/client/index.ts rename packages/plugins/users/src/{ => server}/__tests__/actions.test.ts (98%) rename packages/plugins/users/src/{ => server}/__tests__/fields.test.ts (100%) rename packages/plugins/users/src/{ => server}/__tests__/utils.ts (75%) rename packages/plugins/users/src/{ => server}/actions/users.ts (100%) rename packages/plugins/users/src/{ => server}/authenticators/index.ts (100%) rename packages/plugins/users/src/{ => server}/authenticators/password.ts (100%) rename packages/plugins/users/src/{ => server}/collections/users.ts (100%) create mode 100644 packages/plugins/users/src/server/index.ts rename packages/plugins/users/src/{ => server}/jwt-service.ts (100%) rename packages/plugins/users/src/{ => server}/locale/en-US.ts (100%) rename packages/plugins/users/src/{ => server}/locale/es-ES.ts (100%) rename packages/plugins/users/src/{ => server}/locale/index.ts (100%) rename packages/plugins/users/src/{ => server}/locale/ja-JP.ts (100%) rename packages/plugins/users/src/{ => server}/locale/pt-BR.ts (100%) rename packages/plugins/users/src/{ => server}/locale/zh-CN.ts (100%) rename packages/plugins/users/src/{ => server}/middlewares/check.ts (100%) rename packages/plugins/users/src/{ => server}/middlewares/index.ts (100%) rename packages/plugins/users/src/{ => server}/middlewares/parseToken.ts (100%) rename packages/plugins/users/src/{ => server}/migrations/20220818072639-add-users-phone.ts (100%) rename packages/plugins/users/src/{ => server}/server.ts (100%) create mode 100644 packages/plugins/verification/src/client/VerificationProvider.tsx create mode 100644 packages/presets/nocobase/client.d.ts create mode 100644 packages/presets/nocobase/client.js create mode 100644 packages/presets/nocobase/server.d.ts create mode 100644 packages/presets/nocobase/server.js create mode 100644 packages/presets/nocobase/src/client/index.ts create mode 100644 packages/presets/nocobase/src/server/index.ts rename packages/presets/nocobase/src/{ => server}/migrations/2022-del-sample-plugins.ts (100%) diff --git a/.eslintignore b/.eslintignore index aa5a3a110..e6e7eedb6 100755 --- a/.eslintignore +++ b/.eslintignore @@ -23,3 +23,4 @@ packages/core/database/src/sql-parser/index.js **/.dumi/tmp **/.dumi/tmp-test **/.dumi/tmp-production +packages/core/cli/templates/plugin/src/client/*.tpl diff --git a/.eslintrc b/.eslintrc index 805d21c4d..d23c6be12 100755 --- a/.eslintrc +++ b/.eslintrc @@ -34,6 +34,8 @@ } }, "rules": { + "@typescript-eslint/no-this-alias": "off", + "@typescript-eslint/ban-types": "off", "no-unused-vars": "off", "@typescript-eslint/no-unused-vars": "off", "no-empty-function": "off", diff --git a/.prettierignore b/.prettierignore index 2899bee96..439b62d59 100644 --- a/.prettierignore +++ b/.prettierignore @@ -13,3 +13,4 @@ packages/core/client/src/locale/* **/.dumi/tmp **/.dumi/tmp-test **/.dumi/tmp-production +packages/core/cli/templates/plugin/src/client/*.tpl diff --git a/docs/config.ts b/docs/config.ts index 4d1c192e9..ce2345eda 100644 --- a/docs/config.ts +++ b/docs/config.ts @@ -85,6 +85,7 @@ const sidebar = { // '/welcome/release/index', // '/welcome/release/v08-changelog', '/welcome/release/v10-changelog', + '/welcome/release/v11-changelog', ], }, { @@ -260,7 +261,7 @@ const sidebar = { children: [ // '/api/client', '/api/client/application', - '/api/client/route-switch', + '/api/client/router', { title: 'SchemaDesigner', 'title.zh-CN': 'SchemaDesigner', diff --git a/docs/en-US/api/client/application.md b/docs/en-US/api/client/application.md index ae237311f..38387db90 100644 --- a/docs/en-US/api/client/application.md +++ b/docs/en-US/api/client/application.md @@ -32,7 +32,6 @@ Add Providers, build-in Providers are: - APIClientProvider - I18nextProvider - AntdConfigProvider -- RemoteRouteSwitchProvider - SystemSettingsProvider - PluginManagerProvider - SchemaComponentProvider diff --git a/docs/en-US/api/client/route-switch.md b/docs/en-US/api/client/route-switch.md deleted file mode 100644 index 8af0f744a..000000000 --- a/docs/en-US/api/client/route-switch.md +++ /dev/null @@ -1,74 +0,0 @@ -# RouteSwitch - -## `` - -```ts -interface RouteSwitchProviderProps { - components?: ReactComponent; - routes?: RouteRedirectProps[]; -} -``` - -## `` - -```ts -interface RouteSwitchProps { - routes?: RouteRedirectProps[]; - components?: ReactComponent; -} - -type RouteRedirectProps = RedirectProps | RouteProps; - -interface RedirectProps { - type: 'redirect'; - to: any; - path?: string; - push?: boolean; - from?: string; - [key: string]: any; -} - -interface RouteProps { - type: 'route'; - path?: string | string[]; - sensitive?: boolean; - component?: any; - routes?: RouteProps[]; - [key: string]: any; -} -``` - -## Full Example - -```tsx | pure -import React from 'react'; -import { Link, MemoryRouter as Router } from 'react-router-dom'; -import { RouteRedirectProps, RouteSwitchProvider, RouteSwitch } from '@nocobase/client'; - -const Home = () =>

Home

; -const About = () =>

About

; - -const routes: RouteRedirectProps[] = [ - { - type: 'route', - path: '/', - component: 'Home', - }, - { - type: 'route', - path: '/about', - component: 'About', - }, -]; - -export default () => { - return ( - - - Home, About - - - - ); -}; -``` diff --git a/docs/en-US/api/client/router.md b/docs/en-US/api/client/router.md new file mode 100644 index 000000000..38436ea7c --- /dev/null +++ b/docs/en-US/api/client/router.md @@ -0,0 +1,180 @@ +# Router + +## API + +### Initial + +```tsx | pure + +const app = new Application({ + router: { + type: 'browser' // type default value is `browser` + } +}) + +// or +const app = new Application({ + router: { + type: 'memory', + initialEntries: ['/'] + } +}) +``` + +### add Route + +#### basic + +```tsx | pure +import { RouteObject } from 'react-router-dom' +const app = new Application() + +const Hello = () => { + return
Hello
+} + +// first argument is `name` of route, second argument is `RouteObject` +app.router.add('root', { + path: '/', + element: +}) + +app.router.add('root', { + path: '/', + Component: Hello +}) +``` + +#### Component is String + +```tsx | pure +app.addComponents({ + Hello +}) +app.router.add('root', { + path: '/', + Component: 'Hello' +}) +``` + +#### nested + +```tsx | pure +import { Outlet } from 'react-router-dom' + +const Layout = () => { + return
+ Home + about + + +
+} + +const Home = () => { + return
Home
+} + +const About = () => { + return
About
+} + +app.router.add('root', { + element: +}) +app.router.add('root.home', { + path: '/home', + element: +}) +app.router.add('root.about', { + path: '/about', + element: +}) +``` + +It will generate the following routes: + +```tsx | pure +{ + element: , + children: [ + { + path: '/home', + element: + }, + { + path: '/about', + element: + } + ] +} +``` + +### remove Route + +```tsx | pure +// remove route by name +app.router.remove('root.home') +app.router.remove('hello') +``` + +#### Router in plugin + +```tsx | pure +class MyPlugin extends Plugin { + async load() { + // add route + this.app.router.add('hello', { + path: '/hello', + element:
hello
, + }) + + // remove route + this.app.router.remove('world'); + } +} +``` + +## Example + +```tsx +/** + * defaultShowCode: true + */ +import React from 'react'; +import { Link, Outlet } from 'react-router-dom'; +import { Application } from '@nocobase/client'; + +const Home = () =>

Home

; +const About = () =>

About

; + +const Layout = () => { + return
+
Home, About
+ +
+} + +const app = new Application({ + router: { + type: 'memory', + initialEntries: ['/'] + } +}) + +app.router.add('root', { + element: +}) + +app.router.add('root.home', { + path: '/', + element: +}) + +app.router.add('root.about', { + path: '/about', + element: +}) + +export default app.getRootComponent(); +``` diff --git a/docs/en-US/development/client/index.md b/docs/en-US/development/client/index.md index 9f51ef40a..6080eff9a 100644 --- a/docs/en-US/development/client/index.md +++ b/docs/en-US/development/client/index.md @@ -7,7 +7,6 @@ Most of the extensions for the NocoBase client are provided as Providers. - APIClientProvider - I18nextProvider - AntdConfigProvider -- RemoteRouteSwitchProvider - SystemSettingsProvider - PluginManagerProvider - SchemaComponentProvider diff --git a/docs/en-US/development/client/ui-router.md b/docs/en-US/development/client/ui-router.md index bd27b1994..ace071fb2 100644 --- a/docs/en-US/development/client/ui-router.md +++ b/docs/en-US/development/client/ui-router.md @@ -1,62 +1,66 @@ # UI Routing -NocoBase Client's Router is based on [React Router](https://v5.reactrouter.com/web/guides/quick-start) and can be configured via `` to configure ui routes with the following example. +NocoBase Client's Router is based on [React Router](https://v5.reactrouter.com/web/guides/quick-start) and can be configured via `app.router` to configure ui routes with the following example. ```tsx /** * defaultShowCode: true */ import React from 'react'; -import { Link, MemoryRouter as Router } from 'react-router-dom'; -import { RouteRedirectProps, RouteSwitchProvider, RouteSwitch } from '@nocobase/client'; +import { Link, Outlet } from 'react-router-dom'; +import { Application } from '@nocobase/client'; const Home = () =>

Home

; const About = () =>

About

; -const routes: RouteRedirectProps[] = [ - { - type: 'route', - path: '/', - component: 'Home', - }, - { - type: 'route', - path: '/about', - component: 'About', - }, -]; +const Layout = () => { + return
+
Home, About
+ +
+} -export default () => { - return ( - - - Home, About - - - - ); -}; +const app = new Application({ + router: { + type: 'memory', + initialEntries: ['/'] + } +}) + +app.router.add('root', { + element: +}) + +app.router.add('root.home', { + path: '/', + element: +}) + +app.router.add('root.about', { + path: '/about', + element: +}) + +export default app.getRootComponent(); ``` In a full NocoBase application, the Route can be extended in a similar way as follows. ```tsx | pure -import { RouteSwitchContext } from '@nocobase/client'; -import React, { useContext } from 'react'; +import { Plugin } from '@nocobase/client'; -const HelloWorld = () => { - return
Hello ui router
; -}; +class MyPlugin extends Plugin { + async load() { + // add + this.app.router.add('hello', { + path: '/hello', + element:
hello
, + }) -export default React.memo((props) => { - const ctx = useContext(RouteSwitchContext); - ctx.routes.push({ - type: 'route', - path: '/hello-world', - component: HelloWorld, - }); - return {props.children}; -}); + // remove + this.app.router.remove('hello'); + } +} ``` See [packages/samples/custom-page](https://github.com/nocobase/nocobase/tree/develop/packages/samples/custom-page) for the full example diff --git a/docs/en-US/welcome/release/v11-changelog.md b/docs/en-US/welcome/release/v11-changelog.md new file mode 100644 index 000000000..928faef47 --- /dev/null +++ b/docs/en-US/welcome/release/v11-changelog.md @@ -0,0 +1,100 @@ +# v0.11: Update instructions + +## Plugin registration and use + +before you had to pass a component and the component needed to pass `props.children`, for example: + +```tsx | pure +const HelloProvider = (props) => { + // do something logic + return
+ {props.children} +
; +} + +export default HelloProvider +``` + +now you need to change to the plugin way, for example: + +```diff | pure ++import { Plugin } from '@nocobase/client' + +const HelloProvider = (props) => { + // do something logic + return
+ {props.children} +
; +} + ++ export class HelloPlugin extends Plugin { ++ async load() { ++ this.app.addProvider(HelloProvider); ++ } ++ } + +- export default HelloProvider; ++ export default HelloPlugin; +``` + +plugins are very powerful and can do a lot of things in the `load` phase: + +- modify routes +- add Components +- add Providers +- add Scopes +- load other plugins + +if you used `RouteSwitchContext` to modify the route before, you now need to replace it with a plugin: + +```tsx | pure +import { RouteSwitchContext } from '@nocobase/client'; + +const HelloProvider = () => { + const { routes, ...others } = useContext(RouteSwitchContext); + routes[1].routes.unshift({ + path: '/hello', + component: Hello, + }); + + return
+ + {props.children} + +
+} +``` + +now you need to change to the plugin way, for example: + +```diff | pure +- import { RouteSwitchContext } from '@nocobase/client'; ++ import { Plugin } from '@nocobase/client'; + +const HelloProvider = (props) => { +- const { routes, ...others } = useContext(RouteSwitchContext); +- routes[1].routes.unshift({ +- path: '/hello', +- component: Hello, +- }); + + return
+- + {props.children} +- +
+} + ++ export class HelloPlugin extends Plugin { ++ async load() { ++ this.app.router.add('admin.hello', { ++ path: '/hello', ++ Component: Hello, ++ }); ++ this.app.addProvider(HelloProvider); ++ } ++ } ++ export default HelloPlugin; +``` + +more details can be found in [plugin development](/development/client). diff --git a/docs/tr-TR/api/client/application.md b/docs/tr-TR/api/client/application.md index a7f126b4a..7f8ac6e03 100644 --- a/docs/tr-TR/api/client/application.md +++ b/docs/tr-TR/api/client/application.md @@ -32,7 +32,6 @@ const app = new Application({ - APIClientProvider - I18nextProvider - AntdConfigProvider -- RemoteRouteSwitchProvider - SystemSettingsProvider - PluginManagerProvider - SchemaComponentProvider @@ -59,4 +58,4 @@ export const app = new Application({ }); export default app.render(); -``` \ No newline at end of file +``` diff --git a/docs/tr-TR/api/client/route-switch.md b/docs/tr-TR/api/client/route-switch.md deleted file mode 100644 index 6739d10a1..000000000 --- a/docs/tr-TR/api/client/route-switch.md +++ /dev/null @@ -1,74 +0,0 @@ -# RouteSwitch - -## `` - -```ts -interface RouteSwitchProviderProps { - components?: ReactComponent; - routes?: RouteRedirectProps[]; -} -``` - -## `` - -```ts -interface RouteSwitchProps { - routes?: RouteRedirectProps[]; - components?: ReactComponent; -} - -type RouteRedirectProps = RedirectProps | RouteProps; - -interface RedirectProps { - type: 'redirect'; - to: any; - path?: string; - push?: boolean; - from?: string; - [key: string]: any; -} - -interface RouteProps { - type: 'route'; - path?: string | string[]; - sensitive?: boolean; - component?: any; - routes?: RouteProps[]; - [key: string]: any; -} -``` - -## 完整示例 - -```tsx | pure -import React from 'react'; -import { Link, MemoryRouter as Router } from 'react-router-dom'; -import { RouteRedirectProps, RouteSwitchProvider, RouteSwitch } from '@nocobase/client'; - -const Home = () =>

Home

; -const About = () =>

About

; - -const routes: RouteRedirectProps[] = [ - { - type: 'route', - path: '/', - component: 'Home', - }, - { - type: 'route', - path: '/about', - component: 'About', - }, -]; - -export default () => { - return ( - - - Home, About - - - - ); -}; -``` diff --git a/docs/tr-TR/api/client/router.md b/docs/tr-TR/api/client/router.md new file mode 100644 index 000000000..38436ea7c --- /dev/null +++ b/docs/tr-TR/api/client/router.md @@ -0,0 +1,180 @@ +# Router + +## API + +### Initial + +```tsx | pure + +const app = new Application({ + router: { + type: 'browser' // type default value is `browser` + } +}) + +// or +const app = new Application({ + router: { + type: 'memory', + initialEntries: ['/'] + } +}) +``` + +### add Route + +#### basic + +```tsx | pure +import { RouteObject } from 'react-router-dom' +const app = new Application() + +const Hello = () => { + return
Hello
+} + +// first argument is `name` of route, second argument is `RouteObject` +app.router.add('root', { + path: '/', + element: +}) + +app.router.add('root', { + path: '/', + Component: Hello +}) +``` + +#### Component is String + +```tsx | pure +app.addComponents({ + Hello +}) +app.router.add('root', { + path: '/', + Component: 'Hello' +}) +``` + +#### nested + +```tsx | pure +import { Outlet } from 'react-router-dom' + +const Layout = () => { + return
+ Home + about + + +
+} + +const Home = () => { + return
Home
+} + +const About = () => { + return
About
+} + +app.router.add('root', { + element: +}) +app.router.add('root.home', { + path: '/home', + element: +}) +app.router.add('root.about', { + path: '/about', + element: +}) +``` + +It will generate the following routes: + +```tsx | pure +{ + element: , + children: [ + { + path: '/home', + element: + }, + { + path: '/about', + element: + } + ] +} +``` + +### remove Route + +```tsx | pure +// remove route by name +app.router.remove('root.home') +app.router.remove('hello') +``` + +#### Router in plugin + +```tsx | pure +class MyPlugin extends Plugin { + async load() { + // add route + this.app.router.add('hello', { + path: '/hello', + element:
hello
, + }) + + // remove route + this.app.router.remove('world'); + } +} +``` + +## Example + +```tsx +/** + * defaultShowCode: true + */ +import React from 'react'; +import { Link, Outlet } from 'react-router-dom'; +import { Application } from '@nocobase/client'; + +const Home = () =>

Home

; +const About = () =>

About

; + +const Layout = () => { + return
+
Home, About
+ +
+} + +const app = new Application({ + router: { + type: 'memory', + initialEntries: ['/'] + } +}) + +app.router.add('root', { + element: +}) + +app.router.add('root.home', { + path: '/', + element: +}) + +app.router.add('root.about', { + path: '/about', + element: +}) + +export default app.getRootComponent(); +``` diff --git a/docs/tr-TR/development/client/index.md b/docs/tr-TR/development/client/index.md index 83983e138..ce958ea31 100644 --- a/docs/tr-TR/development/client/index.md +++ b/docs/tr-TR/development/client/index.md @@ -7,7 +7,6 @@ Most of the extensions for the NocoBase client are provided as Providers. - APIClientProvider - I18nextProvider - AntdConfigProvider -- RemoteRouteSwitchProvider - SystemSettingsProvider - PluginManagerProvider - SchemaComponentProvider diff --git a/docs/tr-TR/development/client/ui-router.md b/docs/tr-TR/development/client/ui-router.md index bd27b1994..ace071fb2 100644 --- a/docs/tr-TR/development/client/ui-router.md +++ b/docs/tr-TR/development/client/ui-router.md @@ -1,62 +1,66 @@ # UI Routing -NocoBase Client's Router is based on [React Router](https://v5.reactrouter.com/web/guides/quick-start) and can be configured via `` to configure ui routes with the following example. +NocoBase Client's Router is based on [React Router](https://v5.reactrouter.com/web/guides/quick-start) and can be configured via `app.router` to configure ui routes with the following example. ```tsx /** * defaultShowCode: true */ import React from 'react'; -import { Link, MemoryRouter as Router } from 'react-router-dom'; -import { RouteRedirectProps, RouteSwitchProvider, RouteSwitch } from '@nocobase/client'; +import { Link, Outlet } from 'react-router-dom'; +import { Application } from '@nocobase/client'; const Home = () =>

Home

; const About = () =>

About

; -const routes: RouteRedirectProps[] = [ - { - type: 'route', - path: '/', - component: 'Home', - }, - { - type: 'route', - path: '/about', - component: 'About', - }, -]; +const Layout = () => { + return
+
Home, About
+ +
+} -export default () => { - return ( - - - Home, About - - - - ); -}; +const app = new Application({ + router: { + type: 'memory', + initialEntries: ['/'] + } +}) + +app.router.add('root', { + element: +}) + +app.router.add('root.home', { + path: '/', + element: +}) + +app.router.add('root.about', { + path: '/about', + element: +}) + +export default app.getRootComponent(); ``` In a full NocoBase application, the Route can be extended in a similar way as follows. ```tsx | pure -import { RouteSwitchContext } from '@nocobase/client'; -import React, { useContext } from 'react'; +import { Plugin } from '@nocobase/client'; -const HelloWorld = () => { - return
Hello ui router
; -}; +class MyPlugin extends Plugin { + async load() { + // add + this.app.router.add('hello', { + path: '/hello', + element:
hello
, + }) -export default React.memo((props) => { - const ctx = useContext(RouteSwitchContext); - ctx.routes.push({ - type: 'route', - path: '/hello-world', - component: HelloWorld, - }); - return {props.children}; -}); + // remove + this.app.router.remove('hello'); + } +} ``` See [packages/samples/custom-page](https://github.com/nocobase/nocobase/tree/develop/packages/samples/custom-page) for the full example diff --git a/docs/tr-TR/welcome/release/v11-changelog.md b/docs/tr-TR/welcome/release/v11-changelog.md new file mode 100644 index 000000000..928faef47 --- /dev/null +++ b/docs/tr-TR/welcome/release/v11-changelog.md @@ -0,0 +1,100 @@ +# v0.11: Update instructions + +## Plugin registration and use + +before you had to pass a component and the component needed to pass `props.children`, for example: + +```tsx | pure +const HelloProvider = (props) => { + // do something logic + return
+ {props.children} +
; +} + +export default HelloProvider +``` + +now you need to change to the plugin way, for example: + +```diff | pure ++import { Plugin } from '@nocobase/client' + +const HelloProvider = (props) => { + // do something logic + return
+ {props.children} +
; +} + ++ export class HelloPlugin extends Plugin { ++ async load() { ++ this.app.addProvider(HelloProvider); ++ } ++ } + +- export default HelloProvider; ++ export default HelloPlugin; +``` + +plugins are very powerful and can do a lot of things in the `load` phase: + +- modify routes +- add Components +- add Providers +- add Scopes +- load other plugins + +if you used `RouteSwitchContext` to modify the route before, you now need to replace it with a plugin: + +```tsx | pure +import { RouteSwitchContext } from '@nocobase/client'; + +const HelloProvider = () => { + const { routes, ...others } = useContext(RouteSwitchContext); + routes[1].routes.unshift({ + path: '/hello', + component: Hello, + }); + + return
+ + {props.children} + +
+} +``` + +now you need to change to the plugin way, for example: + +```diff | pure +- import { RouteSwitchContext } from '@nocobase/client'; ++ import { Plugin } from '@nocobase/client'; + +const HelloProvider = (props) => { +- const { routes, ...others } = useContext(RouteSwitchContext); +- routes[1].routes.unshift({ +- path: '/hello', +- component: Hello, +- }); + + return
+- + {props.children} +- +
+} + ++ export class HelloPlugin extends Plugin { ++ async load() { ++ this.app.router.add('admin.hello', { ++ path: '/hello', ++ Component: Hello, ++ }); ++ this.app.addProvider(HelloProvider); ++ } ++ } ++ export default HelloPlugin; +``` + +more details can be found in [plugin development](/development/client). diff --git a/docs/zh-CN/api/client/application.md b/docs/zh-CN/api/client/application.md index a7f126b4a..7f8ac6e03 100644 --- a/docs/zh-CN/api/client/application.md +++ b/docs/zh-CN/api/client/application.md @@ -32,7 +32,6 @@ const app = new Application({ - APIClientProvider - I18nextProvider - AntdConfigProvider -- RemoteRouteSwitchProvider - SystemSettingsProvider - PluginManagerProvider - SchemaComponentProvider @@ -59,4 +58,4 @@ export const app = new Application({ }); export default app.render(); -``` \ No newline at end of file +``` diff --git a/docs/zh-CN/api/client/route-switch.md b/docs/zh-CN/api/client/route-switch.md deleted file mode 100644 index 6739d10a1..000000000 --- a/docs/zh-CN/api/client/route-switch.md +++ /dev/null @@ -1,74 +0,0 @@ -# RouteSwitch - -## `` - -```ts -interface RouteSwitchProviderProps { - components?: ReactComponent; - routes?: RouteRedirectProps[]; -} -``` - -## `` - -```ts -interface RouteSwitchProps { - routes?: RouteRedirectProps[]; - components?: ReactComponent; -} - -type RouteRedirectProps = RedirectProps | RouteProps; - -interface RedirectProps { - type: 'redirect'; - to: any; - path?: string; - push?: boolean; - from?: string; - [key: string]: any; -} - -interface RouteProps { - type: 'route'; - path?: string | string[]; - sensitive?: boolean; - component?: any; - routes?: RouteProps[]; - [key: string]: any; -} -``` - -## 完整示例 - -```tsx | pure -import React from 'react'; -import { Link, MemoryRouter as Router } from 'react-router-dom'; -import { RouteRedirectProps, RouteSwitchProvider, RouteSwitch } from '@nocobase/client'; - -const Home = () =>

Home

; -const About = () =>

About

; - -const routes: RouteRedirectProps[] = [ - { - type: 'route', - path: '/', - component: 'Home', - }, - { - type: 'route', - path: '/about', - component: 'About', - }, -]; - -export default () => { - return ( - - - Home, About - - - - ); -}; -``` diff --git a/docs/zh-CN/api/client/router.md b/docs/zh-CN/api/client/router.md new file mode 100644 index 000000000..14f2e4956 --- /dev/null +++ b/docs/zh-CN/api/client/router.md @@ -0,0 +1,183 @@ +# Router + +## API + +### 初始化 + +```tsx | pure + +const app = new Application({ + router: { + type: 'browser' // type 的默认值就是 `browser` + } +}) + +// or +const app = new Application({ + router: { + type: 'memory', + initialEntries: ['/'] + } +}) +``` + +### 添加路由 + +#### 基础用法 + +```tsx | pure +import { RouteObject } from 'react-router-dom' +const app = new Application() + +const Hello = () => { + return
Hello
+} + +// 第一个参数是名称, 第二个参数是 `RouteObject` +app.router.add('root', { + path: '/', + element: +}) + +app.router.add('root', { + path: '/', + Component: Hello +}) +``` + +#### 支持 Component 是字符串 + +```tsx | pure +// register Hello +app.addComponents({ + Hello +}) + +// Component is `Hello` string +app.router.add('root', { + path: '/', + Component: 'Hello' +}) +``` + +#### 嵌套路由 + +```tsx | pure +import { Outlet } from 'react-router-dom' + +const Layout = () => { + return
+ Home + about + + +
+} + +const Home = () => { + return
Home
+} + +const About = () => { + return
About
+} + +app.router.add('root', { + element: +}) +app.router.add('root.home', { + path: '/home', + element: +}) +app.router.add('root.about', { + path: '/about', + element: +}) +``` + +它将会被渲染为如下形式: + +```tsx | pure +{ + element: , + children: [ + { + path: '/home', + element: + }, + { + path: '/about', + element: + } + ] +} +``` + +### 删除路由 + +```tsx | pure +// 传递 name 即可删除 +app.router.remove('root.home') +app.router.remove('hello') +``` + +#### 插件中修改路由 + +```tsx | pure +class MyPlugin extends Plugin { + async load() { + // add route + this.app.router.add('hello', { + path: '/hello', + element:
hello
, + }) + + // remove route + this.app.router.remove('world'); + } +} +``` + +## 示例 + +```tsx +/** + * defaultShowCode: true + */ +import React from 'react'; +import { Link, Outlet } from 'react-router-dom'; +import { Application } from '@nocobase/client'; + +const Home = () =>

Home

; +const About = () =>

About

; + +const Layout = () => { + return
+
Home, About
+ +
+} + +const app = new Application({ + router: { + type: 'memory', + initialEntries: ['/'] + } +}) + +app.router.add('root', { + element: +}) + +app.router.add('root.home', { + path: '/', + element: +}) + +app.router.add('root.about', { + path: '/about', + element: +}) + +export default app.getRootComponent(); +``` diff --git a/docs/zh-CN/development/client/index.md b/docs/zh-CN/development/client/index.md index d33ac8b86..c1e257850 100644 --- a/docs/zh-CN/development/client/index.md +++ b/docs/zh-CN/development/client/index.md @@ -7,7 +7,6 @@ NocoBase 客户端的扩展大多以 Provider 的形式提供。 - APIClientProvider - I18nextProvider - AntdConfigProvider -- RemoteRouteSwitchProvider - SystemSettingsProvider - PluginManagerProvider - SchemaComponentProvider diff --git a/docs/zh-CN/development/client/ui-router.md b/docs/zh-CN/development/client/ui-router.md index a4c40946e..b6ace0db3 100644 --- a/docs/zh-CN/development/client/ui-router.md +++ b/docs/zh-CN/development/client/ui-router.md @@ -1,62 +1,66 @@ # UI 路由 -NocoBase Client 的 Router 基于 [React Router](https://v5.reactrouter.com/web/guides/quick-start),可以通过 `` 来配置 ui routes,例子如下: +NocoBase Client 的 Router 基于 [React Router](https://v5.reactrouter.com/web/guides/quick-start),可以通过 `app.router` 来配置 ui routes,例子如下: ```tsx /** * defaultShowCode: true */ import React from 'react'; -import { Link, MemoryRouter as Router } from 'react-router-dom'; -import { RouteRedirectProps, RouteSwitchProvider, RouteSwitch } from '@nocobase/client'; +import { Link, Outlet } from 'react-router-dom'; +import { Application } from '@nocobase/client'; const Home = () =>

Home

; const About = () =>

About

; -const routes: RouteRedirectProps[] = [ - { - type: 'route', - path: '/', - component: 'Home', - }, - { - type: 'route', - path: '/about', - component: 'About', - }, -]; +const Layout = () => { + return
+
Home, About
+ +
+} -export default () => { - return ( - - - Home, About - - - - ); -}; +const app = new Application({ + router: { + type: 'memory', + initialEntries: ['/'] + } +}) + +app.router.add('root', { + element: +}) + +app.router.add('root.home', { + path: '/', + element: +}) + +app.router.add('root.about', { + path: '/about', + element: +}) + +export default app.getRootComponent(); ``` 在完整的 NocoBase 应用里,可以类似以下的的方式扩展 Route: ```tsx | pure -import { RouteSwitchContext } from '@nocobase/client'; -import React, { useContext } from 'react'; +import { Plugin } from '@nocobase/client'; -const HelloWorld = () => { - return
Hello ui router
; -}; +class MyPlugin extends Plugin { + async load() { + // 添加一条路由 + this.app.router.add('hello', { + path: '/hello', + element:
hello
, + }) -export default React.memo((props) => { - const ctx = useContext(RouteSwitchContext); - ctx.routes.push({ - type: 'route', - path: '/hello-world', - component: HelloWorld, - }); - return {props.children}; -}); + // 删除一条路由 + this.app.router.remove('hello'); + } +} ``` 完整示例查看 [packages/samples/custom-page](https://github.com/nocobase/nocobase/tree/develop/packages/samples/custom-page) diff --git a/docs/zh-CN/welcome/release/v11-changelog.md b/docs/zh-CN/welcome/release/v11-changelog.md new file mode 100644 index 000000000..1eacd3e0d --- /dev/null +++ b/docs/zh-CN/welcome/release/v11-changelog.md @@ -0,0 +1,120 @@ +# v0.11:更新说明 + +## 新特性 + +- 全新的客户端 Application、Plugin 和 Router +- antd 升级到 v5 +- 新插件 + - 数据可视化 + - API 秘钥 + - Google 地图 + +## 不兼容的变化 + +### 全新的客户端 Application、Plugin 和 Router + +#### 插件的变化 + +以前必须传递一个组件,并且组件需要透传 `props.children`,例如: + +```tsx | pure +const HelloProvider = (props) => { + // do something logic + return
+ {props.children} +
; +} + +export default HelloProvider +``` + +现在需要改为插件的方式,例如: + +```diff | pure ++import { Plugin } from '@nocobase/client' + +const HelloProvider = (props) => { + // do something logic + return
+ {props.children} +
; +} + ++ export class HelloPlugin extends Plugin { ++ async load() { ++ this.app.addProvider(HelloProvider); ++ } ++ } + +- export default HelloProvider; ++ export default HelloPlugin; +``` + +插件的功能很强大,可以在 `load` 阶段做很多事情: + +- 修改路由 +- 增加 Components +- 增加 Providers +- 增加 Scopes +- 加载其他插件 + +#### 路由的变化 + +如果之前使用了 `RouteSwitchContext` 进行路由修改,现在需要通过插件替换: + +```tsx | pure +import { RouteSwitchContext } from '@nocobase/client'; + +const HelloProvider = () => { + const { routes, ...others } = useContext(RouteSwitchContext); + routes[1].routes.unshift({ + path: '/hello', + component: Hello, + }); + + return
+ + {props.children} + +
+} +``` + +需要改为: + +```diff | pure +- import { RouteSwitchContext } from '@nocobase/client'; ++ import { Plugin } from '@nocobase/client'; + +const HelloProvider = (props) => { +- const { routes, ...others } = useContext(RouteSwitchContext); +- routes[1].routes.unshift({ +- path: '/hello', +- component: Hello, +- }); + + return
+- + {props.children} +- +
+} + ++ export class HelloPlugin extends Plugin { ++ async load() { ++ this.app.router.add('admin.hello', { ++ path: '/hello', ++ Component: Hello, ++ }); ++ this.app.addProvider(HelloProvider); ++ } ++ } ++ export default HelloPlugin; +``` + +更多文档和示例见 [packages/core/client/src/application/index.md](https://github.com/nocobase/nocobase/blob/main/packages/core/client/src/application/index.md) + +### antd 升级到 v5 + +- antd 相关详情查看官网 [从 v4 到 v5](https://ant.design/docs/react/migration-v5-cn) +- `@formily/antd` 替换为 `@formily/antd-v5` diff --git a/package.json b/package.json index 0e405358c..ec6667d5e 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ } }, "devDependencies": { + "commander": "^9.2.0", "@types/react": "^17.0.0", "@types/react-dom": "^17.0.0", "react": "^18.0.0", @@ -57,7 +58,7 @@ "@vitejs/plugin-react": "^4.0.0", "auto-changelog": "^2.4.0", "dumi": "^2.2.0", - "dumi-theme-nocobase": "^0.2.12", + "dumi-theme-nocobase": "^0.2.14", "ghooks": "^2.0.4", "jsdom-worker": "^0.3.0", "prettier": "^2.2.1", diff --git a/packages/app/client/.umirc.ts b/packages/app/client/.umirc.ts index 31708ed5b..2cecc1d2f 100644 --- a/packages/app/client/.umirc.ts +++ b/packages/app/client/.umirc.ts @@ -20,8 +20,7 @@ export default defineConfig({ { rel: 'stylesheet', href: '/global.css' }, ], headScripts: [ - '/browser-checker.js', - '/set-router.js', + '/browser-checker.js' ], hash: true, alias: { diff --git a/packages/app/client/public/set-router.js b/packages/app/client/public/set-router.js deleted file mode 100644 index 6e9c95382..000000000 --- a/packages/app/client/public/set-router.js +++ /dev/null @@ -1,2 +0,0 @@ -var match = location.pathname.match(/^\/apps\/([^/]*)\//); -window.routerBase = match ? match[0] : "/"; \ No newline at end of file diff --git a/packages/app/client/src/pages/index.tsx b/packages/app/client/src/pages/index.tsx index 56a28e6ca..98a45bf37 100644 --- a/packages/app/client/src/pages/index.tsx +++ b/packages/app/client/src/pages/index.tsx @@ -1,5 +1,6 @@ import '@/theme'; import { Application } from '@nocobase/client'; +import { NocoBaseClientPresetPlugin } from '@nocobase/preset-nocobase/client'; export const app = new Application({ apiClient: { @@ -8,6 +9,7 @@ export const app = new Application({ dynamicImport: (name: string) => { return import(`../plugins/${name}`); }, + plugins: [NocoBaseClientPresetPlugin], }); -export default app.render(); +export default app.getRootComponent(); diff --git a/packages/app/client/src/plugins/acl.ts b/packages/app/client/src/plugins/acl.ts new file mode 100644 index 000000000..a31541bb8 --- /dev/null +++ b/packages/app/client/src/plugins/acl.ts @@ -0,0 +1,2 @@ +export { default } from '@nocobase/plugin-acl/client'; + diff --git a/packages/app/client/src/plugins/client.ts b/packages/app/client/src/plugins/client.ts new file mode 100644 index 000000000..af9dc0350 --- /dev/null +++ b/packages/app/client/src/plugins/client.ts @@ -0,0 +1 @@ +export { default } from '@nocobase/plugin-client/client'; diff --git a/packages/app/client/src/plugins/collection-manager.ts b/packages/app/client/src/plugins/collection-manager.ts new file mode 100644 index 000000000..c8315a7db --- /dev/null +++ b/packages/app/client/src/plugins/collection-manager.ts @@ -0,0 +1 @@ +export { default } from '@nocobase/plugin-collection-manager/client'; diff --git a/packages/app/client/src/plugins/error-handler.ts b/packages/app/client/src/plugins/error-handler.ts new file mode 100644 index 000000000..25b0dffe7 --- /dev/null +++ b/packages/app/client/src/plugins/error-handler.ts @@ -0,0 +1 @@ +export { default } from '@nocobase/plugin-error-handler/client'; diff --git a/packages/app/client/src/plugins/system-settings.ts b/packages/app/client/src/plugins/system-settings.ts new file mode 100644 index 000000000..60bc887b9 --- /dev/null +++ b/packages/app/client/src/plugins/system-settings.ts @@ -0,0 +1 @@ +export { default } from '@nocobase/plugin-system-settings/client'; diff --git a/packages/app/client/src/plugins/ui-routes-storage.ts b/packages/app/client/src/plugins/ui-routes-storage.ts new file mode 100644 index 000000000..f885e0faa --- /dev/null +++ b/packages/app/client/src/plugins/ui-routes-storage.ts @@ -0,0 +1 @@ +export { default } from '@nocobase/plugin-ui-routes-storage/client'; diff --git a/packages/app/client/src/plugins/ui-schema-storage.ts b/packages/app/client/src/plugins/ui-schema-storage.ts new file mode 100644 index 000000000..a0c77eec9 --- /dev/null +++ b/packages/app/client/src/plugins/ui-schema-storage.ts @@ -0,0 +1 @@ +export { default } from '@nocobase/plugin-ui-schema-storage/client'; diff --git a/packages/core/build/src/build.ts b/packages/core/build/src/build.ts index 49b396758..b4ac84b6d 100755 --- a/packages/core/build/src/build.ts +++ b/packages/core/build/src/build.ts @@ -11,13 +11,24 @@ import randomColor from './randomColor'; import registerBabel from './registerBabel'; import rollup from './rollup'; import { Dispose, IBundleOptions, IBundleTypeOutput, ICjs, IEsm, IOpts } from './types'; -import { getExistFile, getLernaPackages } from './utils'; +import { getExistFiles, getLernaPackages } from './utils'; export function getBundleOpts(opts: IOpts): IBundleOptions[] { const { cwd, buildArgs = {}, rootConfig = {} } = opts; - const entry = getExistFile({ + const entry = getExistFiles({ cwd, - files: ['src/index.tsx', 'src/index.ts', 'src/index.jsx', 'src/index.js'], + files: [ + 'src/index.tsx', + 'src/index.ts', + 'src/index.jsx', + 'src/index.js', + 'src/server/index.ts', + 'src/server/index.js', + 'src/client/index.js', + 'src/client/index.ts', + 'src/client/index.tsx' + ], + onlyOne: false, returnRelative: true, }); const userConfig = getUserConfig({ cwd, customPath: buildArgs.config }); diff --git a/packages/core/build/src/getUserConfig.ts b/packages/core/build/src/getUserConfig.ts index 02cb05f7f..98aed9187 100755 --- a/packages/core/build/src/getUserConfig.ts +++ b/packages/core/build/src/getUserConfig.ts @@ -5,7 +5,7 @@ import signale from 'signale'; import slash from 'slash2'; import schema from './schema'; import { IBundleOptions } from './types'; -import { getExistFile } from './utils'; +import { getExistFiles } from './utils'; function testDefault(obj) { return obj.default || obj; @@ -51,7 +51,7 @@ export default function({ cwd, customPath }: { cwd: string; customPath?: string const configFile = finalPath || - getExistFile({ + getExistFiles({ cwd, files: CONFIG_FILES, returnRelative: false, diff --git a/packages/core/build/src/utils/index.ts b/packages/core/build/src/utils/index.ts index 4784d57c6..52a875006 100755 --- a/packages/core/build/src/utils/index.ts +++ b/packages/core/build/src/utils/index.ts @@ -1,13 +1,17 @@ import { existsSync } from 'fs'; import { join } from 'path'; -export function getExistFile({ cwd, files, returnRelative }) { +export function getExistFiles({ cwd, files, returnRelative, onlyOne = true }) { + const res = []; for (const file of files) { const absFilePath = join(cwd, file); if (existsSync(absFilePath)) { - return returnRelative ? file : absFilePath; + const filePath = returnRelative ? file : absFilePath; + res.push(filePath); } } + + return onlyOne ? res[0] : res; // undefined or string[] } export { getLernaPackages } from './getLernaPackages'; diff --git a/packages/core/cli/templates/plugin/client.d.ts b/packages/core/cli/templates/plugin/client.d.ts index bd53a2f77..d515d1feb 100755 --- a/packages/core/cli/templates/plugin/client.d.ts +++ b/packages/core/cli/templates/plugin/client.d.ts @@ -1,3 +1,3 @@ -// @ts-nocheck -export * from './lib/client'; -export { default } from './lib/client'; +export * from './src/client'; +export { default } from './src/client'; + diff --git a/packages/core/cli/templates/plugin/client.js b/packages/core/cli/templates/plugin/client.js index c83e7e450..3c39956ca 100755 --- a/packages/core/cli/templates/plugin/client.js +++ b/packages/core/cli/templates/plugin/client.js @@ -1,65 +1 @@ -'use strict'; - -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== 'function') return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} - -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) { - return { default: obj }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for (var key in obj) { - if (key !== 'default' && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} - -var _index = _interopRequireWildcard(require('./lib/client')); - -Object.defineProperty(exports, '__esModule', { - value: true, -}); -var _exportNames = {}; -Object.defineProperty(exports, 'default', { - enumerable: true, - get: function get() { - return _index.default; - }, -}); - -Object.keys(_index).forEach(function (key) { - if (key === 'default' || key === '__esModule') return; - if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; - if (key in exports && exports[key] === _index[key]) return; - Object.defineProperty(exports, key, { - enumerable: true, - get: function get() { - return _index[key]; - }, - }); -}); +module.exports = require('./lib/client/index.js'); diff --git a/packages/core/cli/templates/plugin/package.json.tpl b/packages/core/cli/templates/plugin/package.json.tpl index 2eb499b1f..aeb78e6f0 100644 --- a/packages/core/cli/templates/plugin/package.json.tpl +++ b/packages/core/cli/templates/plugin/package.json.tpl @@ -2,6 +2,17 @@ "name": "{{{packageName}}}", "version": "{{{packageVersion}}}", "main": "lib/server/index.js", + "files": [ + "lib", + "src", + "README.md", + "README.zh-CN.md", + "CHANGELOG.md", + "server.js", + "server.d.ts", + "client.js", + "client.d.ts" + ], "devDependencies": { "@nocobase/server": "{{{nocobaseVersion}}}", "@nocobase/test": "{{{nocobaseVersion}}}" diff --git a/packages/core/cli/templates/plugin/server.d.ts b/packages/core/cli/templates/plugin/server.d.ts index 4d922a91b..b55e6f70d 100755 --- a/packages/core/cli/templates/plugin/server.d.ts +++ b/packages/core/cli/templates/plugin/server.d.ts @@ -1,3 +1,3 @@ -// @ts-nocheck -export * from './lib/server'; -export { default } from './lib/server'; +export * from './src/server'; +export { default } from './src/server'; + diff --git a/packages/core/cli/templates/plugin/server.js b/packages/core/cli/templates/plugin/server.js index 4f16903a6..adcc9d90d 100755 --- a/packages/core/cli/templates/plugin/server.js +++ b/packages/core/cli/templates/plugin/server.js @@ -1,65 +1 @@ -'use strict'; - -function _getRequireWildcardCache(nodeInterop) { - if (typeof WeakMap !== 'function') return null; - var cacheBabelInterop = new WeakMap(); - var cacheNodeInterop = new WeakMap(); - return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { - return nodeInterop ? cacheNodeInterop : cacheBabelInterop; - })(nodeInterop); -} - -function _interopRequireWildcard(obj, nodeInterop) { - if (!nodeInterop && obj && obj.__esModule) { - return obj; - } - if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) { - return { default: obj }; - } - var cache = _getRequireWildcardCache(nodeInterop); - if (cache && cache.has(obj)) { - return cache.get(obj); - } - var newObj = {}; - var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; - for (var key in obj) { - if (key !== 'default' && Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; - if (desc && (desc.get || desc.set)) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - newObj.default = obj; - if (cache) { - cache.set(obj, newObj); - } - return newObj; -} - -var _index = _interopRequireWildcard(require('./lib/server')); - -Object.defineProperty(exports, '__esModule', { - value: true, -}); -var _exportNames = {}; -Object.defineProperty(exports, 'default', { - enumerable: true, - get: function get() { - return _index.default; - }, -}); - -Object.keys(_index).forEach(function (key) { - if (key === 'default' || key === '__esModule') return; - if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; - if (key in exports && exports[key] === _index[key]) return; - Object.defineProperty(exports, key, { - enumerable: true, - get: function get() { - return _index[key]; - }, - }); -}); +module.exports = require('./lib/server/index.js'); diff --git a/packages/core/cli/templates/plugin/src/client/index.tsx b/packages/core/cli/templates/plugin/src/client/index.tsx deleted file mode 100644 index e99af76e1..000000000 --- a/packages/core/cli/templates/plugin/src/client/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react'; - -const MyProvider = React.memo((props) => { - return <>{props.children}; -}); -MyProvider.displayName = 'MyProvider'; - -export default MyProvider; diff --git a/packages/core/cli/templates/plugin/src/client/index.tsx.tpl b/packages/core/cli/templates/plugin/src/client/index.tsx.tpl new file mode 100644 index 000000000..3b509bc2d --- /dev/null +++ b/packages/core/cli/templates/plugin/src/client/index.tsx.tpl @@ -0,0 +1,21 @@ +import { Plugin } from '@nocobase/client'; + +export class {{{pascalCaseName}}}Plugin extends Plugin { + async afterAdd() { + // this.app.pm.add() + } + + async beforeLoad() {} + + // You can get and modify the app instance here + async load() { + console.log(this.app); + // this.app.addComponents({}) + // this.app.addScopes({}) + // this.app.addProvider() + // this.app.addProviders() + // this.app.router.add() + } +} + +export default {{{pascalCaseName}}}Plugin; diff --git a/packages/core/client/docs/develop.md b/packages/core/client/docs/develop.md index 78c8cf4f7..72c1138e2 100644 --- a/packages/core/client/docs/develop.md +++ b/packages/core/client/docs/develop.md @@ -2,4 +2,4 @@ sidebar: false --- - + diff --git a/packages/core/client/docs/intro.md b/packages/core/client/docs/intro.md index 1951d0768..526b115ba 100644 --- a/packages/core/client/docs/intro.md +++ b/packages/core/client/docs/intro.md @@ -8,92 +8,48 @@ order: 1 示例: -```tsx | pure -const app = new Application(); - -app.use([MemoryRouter, { initialEntries: ['/'] }]); - -app.use(({ children }) => { - const location = useLocation(); - if (location.pathname === '/hello') { - return
Hello NocoBase!
; - } - return children; -}); - -export default app.compose(); -``` - -## RouteSwitch - -稍微复杂的应用都会用到路由来管理前端的页面,如下: - -```jsx -/** - * defaultShowCode: true - * title: Router - */ -import React from 'react'; -import { Route, Routes, Link, MemoryRouter as Router } from 'react-router-dom'; - -const Home = () =>

Home

; -const About = () =>

About

; - -const App = () => ( - - Home, About - - }> - }> - - -); - -export default App; -``` - -上述例子,组件经由路由转发,`/` 转发给 `Home`,`/about` 转发给 `About`。这种 JSX 的写法,对于熟悉 JSX 的开发来说,十分便捷,但需要开发来编写和维护,不符合 NocoBase 低代码、无代码的设计理念。所以将 Route 做了封装和配置化改造,如下: - ```tsx /** * defaultShowCode: true - * title: RouteSwitch */ import React from 'react'; -import { Link, MemoryRouter as Router } from 'react-router-dom'; -import { RouteRedirectProps, RouteSwitchProvider, RouteSwitch } from '@nocobase/client'; +import { Link, Outlet } from 'react-router-dom'; +import { Application } from '@nocobase/client'; const Home = () =>

Home

; const About = () =>

About

; -const routes: RouteRedirectProps[] = [ - { - type: 'route', - path: '/', - component: 'Home', - }, - { - type: 'route', - path: '/about', - component: 'About', - }, -]; +const Layout = () => { + return
+
Home, About
+ +
+} -export default () => { - return ( - - - Home, About - - - - ); -}; +const app = new Application({ + router: { + type: 'memory', + initialEntries: ['/'] + } +}) + +app.router.add('root', { + element: +}) + +app.router.add('root.home', { + path: '/', + element: +}) + +app.router.add('root.about', { + path: '/about', + element: +}) + +export default app.getRootComponent(); ``` -- 由 RouteSwitchProvider 配置 components,由开发编写,以 Layout 或 Template 的方式提供给 RouteSwitch 使用。 -- 由 RouteSwitch 配置 routes,JSON 的方式,可以由后端获取,方便后续的动态化、无代码的支持。 - ## SchemaComponent 路由可以通过 JSON 的方式配置,可以注册诸多可供路由使用的组件模板,以方便各种场景支持,但是这些组件还是需要开发编写和维护,所以进一步将组件抽象,转换成配置化的方式。如: @@ -459,101 +415,6 @@ export default function App() { } ``` -## RouteSwitch + SchemaComponent - -当路由和组件都可以配置之后,可以进一步将二者结合,例子如下: - -```tsx -/** - * defaultShowCode: true - * title: RouteSwitch + SchemaComponent - */ -import React, { useMemo, useEffect } from 'react'; -import { Link, MemoryRouter as Router } from 'react-router-dom'; -import { - RouteRedirectProps, - RouteSwitchProvider, - RouteSwitch, - useRoute, - SchemaComponentProvider, - SchemaComponent, - useDesignable, - useSchemaComponentContext, -} from '@nocobase/client'; -import { Spin, Button } from 'antd'; -import { observer, Schema } from '@formily/react'; - -const Hello = observer(({ name }) => { - const { patch, remove } = useDesignable(); - return ( -
-

Hello {name}!

- -
- ) -}, { displayName: 'Hello' }); - -const RouteSchemaComponent = (props) => { - const route = useRoute(); - const { reset } = useSchemaComponentContext(); - useEffect(() => { - reset(); - }, route.schema); - return -} - -const routes: RouteRedirectProps[] = [ - { - type: 'route', - path: '/', - component: 'RouteSchemaComponent', - schema: { - name: 'home', - 'x-component': 'Hello', - 'x-component-props': { - name: 'Home', - }, - }, - }, - { - type: 'route', - path: '/about', - component: 'RouteSchemaComponent', - schema: { - name: 'home', - 'x-component': 'Hello', - 'x-component-props': { - name: 'About', - }, - }, - }, -]; - -export default () => { - return ( - - - - Home, About - - - - - ); -}; -``` - -以上例子实现了路由和组件层面的配置化,在开发层面配置了两个组件: - -- `` 简易的可以在路由里配置 schema 的方案 -- `` 自定义的 Schema 组件 - -为了让大家更加能感受到 Schema 组件的不一样之处,例子添加了一个简易的随机更新 `x-component-props.name` 值的按钮,当路由切换后,更新后的 name 并不会被重置。这也是 Schema 组件的 Designable 的能力,可以任意的动态更新 schema 配置,实时更新,实时渲染。 - ## Designable SchemaComponent 基于 Formily 的 SchemaField,Formily 提供了 [Designable](https://github.com/alibaba/designable) 来解决 Schema 的配置问题,但是这套方案: @@ -781,7 +642,6 @@ const { data, loading } = useRequest(); 客户端的扩展以 Providers 的形式存在,提供各种可供组件使用的 Context,可全局也可以局部使用。上文我们已经介绍了核心的三个 Providers: -- RouteSwitchProvider,提供配置路由所需的 Layout 和 Template 组件 - SchemaComponentProvider,提供配置 Schema 所需的各种组件 - ApiClientProvider,提供客户端 SDK @@ -800,16 +660,14 @@ const { data, loading } = useRequest(); ```tsx | pure - {...} - ``` 但是这样的方式不利于 Providers 的管理和扩展,为此提炼了 `compose()` 函数用于配置多个 providers,如下: - + ## Application diff --git a/packages/core/client/package.json b/packages/core/client/package.json index 5441f679b..31965ff65 100644 --- a/packages/core/client/package.json +++ b/packages/core/client/package.json @@ -53,12 +53,12 @@ "react-is": ">=18.0.0" }, "devDependencies": { + "dumi": "^2.2.0", + "dumi-theme-nocobase": "^0.2.14", "@testing-library/react": "^12.1.2", "@types/markdown-it": "12.2.3", "@types/markdown-it-highlightjs": "3.3.1", - "axios-mock-adapter": "^1.20.0", - "dumi": "^2.2.0", - "dumi-theme-nocobase": "^0.2.9" + "axios-mock-adapter": "^1.20.0" }, "gitHead": "ce588eefb0bfc50f7d5bbee575e0b5e843bf6644" } diff --git a/packages/core/client/src/acl/ACLProvider.tsx b/packages/core/client/src/acl/ACLProvider.tsx index b41568f11..fc8486b2f 100644 --- a/packages/core/client/src/acl/ACLProvider.tsx +++ b/packages/core/client/src/acl/ACLProvider.tsx @@ -12,6 +12,7 @@ import { SchemaComponentOptions, useDesignable } from '../schema-component'; export const ACLContext = createContext({}); +// TODO: delete this,replace by `ACLPlugin` export const ACLProvider = (props) => { return ( ({}); @@ -50,3 +51,9 @@ export function AntdConfigProvider(props) { ); } + +export class AntdConfigPlugin extends Plugin { + async load() { + this.app.use(AntdConfigProvider, this.options?.config || {}); + } +} diff --git a/packages/core/client/src/application-v2/Application.tsx b/packages/core/client/src/application-v2/Application.tsx deleted file mode 100644 index 6dbfaafd3..000000000 --- a/packages/core/client/src/application-v2/Application.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import { i18n } from 'i18next'; -import { merge } from 'lodash'; -import get from 'lodash/get'; -import set from 'lodash/set'; -import React from 'react'; -import { createRoot } from 'react-dom/client'; -import { I18nextProvider } from 'react-i18next'; -import { APIClient, APIClientProvider } from '../api-client'; -import { Plugin } from './Plugin'; -import { PluginManager } from './PluginManager'; -import { Router } from './Router'; -import { AppComponent, defaultAppComponents } from './components'; -import { ApplicationOptions } from './types'; - -export class Application { - providers: any[]; - router: Router; - plugins: Map; - scopes: Record; - i18n: i18n; - apiClient: APIClient; - components: any; - pm: PluginManager; - - constructor(protected _options: ApplicationOptions) { - this.providers = []; - this.plugins = new Map(); - this.scopes = merge(this.scopes, _options.scopes || {}); - this.components = merge(defaultAppComponents, _options.components || {}); - this.apiClient = new APIClient(_options.apiClient); - this.router = new Router(_options.router, { app: this }); - this.pm = new PluginManager(this); - this.useDefaultProviders(); - } - - get options() { - return this._options; - } - - useDefaultProviders() { - this.use([APIClientProvider, { apiClient: this.apiClient }]); - this.use(I18nextProvider, { i18n: this.i18n }); - } - - getPlugin(name: string) { - return this.plugins.get(name); - } - - getComponent(name: string) { - return get(this.components, name); - } - - renderComponent(name: string, props = {}) { - return React.createElement(this.getComponent(name), props); - } - - registerComponent(name: string, component: any) { - set(this.components, name, component); - } - - registerComponents(components: any) { - Object.keys(components).forEach((name) => { - this.registerComponent(name, components[name]); - }); - } - - registerScopes(scopes: Record) { - this.scopes = merge(this.scopes, scopes); - } - - use(component: any, props?: any) { - this.providers.push(props ? [component, props] : component); - } - - async load() { - return this.pm.load(); - } - - getRootComponent() { - return () => ; - } - - mount(selector: string) { - const container = typeof selector === 'string' ? document.querySelector(selector) : selector; - if (container) { - const App = this.getRootComponent(); - const root = createRoot(container); - root.render(); - } - } -} diff --git a/packages/core/client/src/application-v2/Plugin.ts b/packages/core/client/src/application-v2/Plugin.ts deleted file mode 100644 index 9abf92693..000000000 --- a/packages/core/client/src/application-v2/Plugin.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Application } from './Application'; -import { PluginOptions } from './types'; - -export class Plugin { - constructor(protected _options: PluginOptions, protected app: Application) { - this.app = app; - } - - get options() { - return this._options; - } - - get name() { - return this._options.name; - } - - get pm() { - return this.app.pm; - } - - get router() { - return this.app.router; - } - - async afterAdd() {} - - async beforeLoad() {} - - async load() {} -} diff --git a/packages/core/client/src/application-v2/PluginManager.ts b/packages/core/client/src/application-v2/PluginManager.ts deleted file mode 100644 index 32f6221d3..000000000 --- a/packages/core/client/src/application-v2/PluginManager.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Application } from './Application'; -import { Plugin } from './Plugin'; -import { type PluginOptions } from './types'; - -export interface PluginManagerOptions { - plugins: string[]; -} - -type PluginNameOrClass = string | typeof Plugin; - -export class PluginManager { - protected pluginInstances: Map; - protected pluginPrepares: Map; - - constructor(protected app: Application) { - this.pluginInstances = new Map(); - this.pluginPrepares = new Map(); - this.addPresetPlugins(); - } - - protected addPresetPlugins() { - const { plugins } = this.app.options; - for (const plugin of plugins) { - if (typeof plugin === 'string') { - this.prepare(plugin); - } else { - this.prepare(...plugin); - } - } - } - - prepare(nameOrClass: PluginNameOrClass, options?: PluginOptions) { - let opts: any = {}; - if (typeof nameOrClass === 'string') { - opts['name'] = nameOrClass; - } else { - opts = { ...options, Plugin: nameOrClass }; - } - return this.pluginPrepares.set(opts.name, opts); - } - - async add(nameOrClass: PluginNameOrClass, options?: PluginOptions) { - let opts: any = {}; - if (typeof nameOrClass === 'string') { - opts['name'] = nameOrClass; - } else { - opts = { ...options, Plugin: nameOrClass }; - } - const plugin = await this.makePlugin(opts); - this.pluginInstances.set(plugin.name, plugin); - await plugin.afterAdd(); - return plugin; - } - - async makePlugin(opts) { - const { importPlugins } = this.app.options; - let P: typeof Plugin = opts.Plugin; - if (!P) { - P = await importPlugins(opts.name); - } - if (!P) { - throw new Error(`Plugin "${opts.name} " not found`); - } - console.log(opts, P); - return new P(opts, this.app); - } - - async load() { - for (const opts of this.pluginPrepares.values()) { - const plugin = await this.makePlugin(opts); - this.pluginInstances.set(plugin.name, plugin); - await plugin.afterAdd(); - } - - for (const plugin of this.pluginInstances.values()) { - await plugin.beforeLoad(); - } - - for (const plugin of this.pluginInstances.values()) { - await plugin.load(); - } - } -} diff --git a/packages/core/client/src/application-v2/Router.ts b/packages/core/client/src/application-v2/Router.ts deleted file mode 100644 index 5886bd542..000000000 --- a/packages/core/client/src/application-v2/Router.ts +++ /dev/null @@ -1,67 +0,0 @@ -import set from 'lodash/set'; -import { createBrowserRouter, createHashRouter, createMemoryRouter } from 'react-router-dom'; -import { Application } from './Application'; -import { RouterOptions } from './types'; - -export class Router { - protected app: Application; - protected routes: Map; - - constructor(protected options?: RouterOptions, protected context?: any) { - this.routes = new Map(); - this.app = context.app; - } - - getRoutes() { - const routes = {}; - for (const [name, route] of this.routes) { - set(routes, name.split('.').join('.children.'), route); - } - - const transform = (item) => { - if (item.component) { - item.Component = this.app.getComponent(item.component); - } - return item; - }; - - const toArr = (items: any) => { - return Object.values(items || {}).map((item) => { - if (item.children) { - item.children = toArr(item.children); - } - return transform(item); - }); - }; - return toArr(routes); - } - - createRouter() { - const { type, ...opts } = this.options; - const routes = this.getRoutes(); - if (routes.length === 0) { - return null; - } - switch (type) { - case 'hash': - return createHashRouter(routes, opts) as any; - case 'browser': - return createBrowserRouter(routes, opts) as any; - case 'memory': - return createMemoryRouter(routes, opts) as any; - default: - return createMemoryRouter(routes, opts) as any; - } - } - - add(name: string, route: any) { - this.routes.set(name, route); - Object.keys(route.children || {}).forEach((key) => { - this.routes.set(`${name}.${key}`, route.children[key]); - }); - } - - remove(name: string) { - this.routes.delete(name); - } -} diff --git a/packages/core/client/src/application-v2/components/AppComponent.tsx b/packages/core/client/src/application-v2/components/AppComponent.tsx deleted file mode 100644 index 7b7de37aa..000000000 --- a/packages/core/client/src/application-v2/components/AppComponent.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; -import { ApplicationContext } from '../context'; -import { useApp, useLoad } from '../hooks'; - -const Internal = React.memo(() => { - const app = useApp(); - const loading = useLoad(); - if (loading) { - return app.renderComponent('App.Spin'); - } - return app.renderComponent('App.Main', { - app, - providers: app.providers, - }); -}); - -export const AppComponent = (props) => { - const { app } = props; - return ( - - - - ); -}; diff --git a/packages/core/client/src/application-v2/components/MainComponent.tsx b/packages/core/client/src/application-v2/components/MainComponent.tsx deleted file mode 100644 index ae9a046f0..000000000 --- a/packages/core/client/src/application-v2/components/MainComponent.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import React, { useMemo } from 'react'; -import { Application } from '../Application'; -import { RouterProvider } from './RouterProvider'; - -export const MainComponent = React.memo((props: { app: Application; providers: any[] }) => { - const { app, providers } = props; - const router = useMemo(() => app.router.createRouter(), []); - return ; -}); diff --git a/packages/core/client/src/application-v2/components/RouterProvider.tsx b/packages/core/client/src/application-v2/components/RouterProvider.tsx deleted file mode 100644 index 06131985e..000000000 --- a/packages/core/client/src/application-v2/components/RouterProvider.tsx +++ /dev/null @@ -1,119 +0,0 @@ -// @ts-nocheck -import type { RouterState } from '@remix-run/router'; -import React from 'react'; -import { - UNSAFE_DataRouterContext as DataRouterContext, - UNSAFE_DataRouterStateContext as DataRouterStateContext, - UNSAFE_LocationContext as LocationContext, - UNSAFE_RouteContext as RouteContext, - Router, - UNSAFE_useRoutesImpl as useRoutesImpl, - type DataRouteObject, - type RouterProviderProps, -} from 'react-router'; -import { compose } from '../compose'; - -const START_TRANSITION = 'startTransition'; - -/** - * Given a Remix Router instance, render the appropriate UI - */ -export function RouterProvider({ - fallbackElement, - router, - providers, -}: RouterProviderProps & { providers?: any }): React.ReactElement { - // Need to use a layout effect here so we are subscribed early enough to - // pick up on any render-driven redirects/navigations (useEffect/) - const [state, setStateImpl] = React.useState(router.state); - const setState = React.useCallback( - (newState: RouterState) => { - START_TRANSITION in React ? React[START_TRANSITION](() => setStateImpl(newState)) : setStateImpl(newState); - }, - [setStateImpl], - ); - React.useLayoutEffect(() => router.subscribe(setState), [router, setState]); - - const navigator = React.useMemo((): Navigator => { - return { - createHref: router.createHref, - encodeLocation: router.encodeLocation, - go: (n) => router.navigate(n), - push: (to, state, opts) => - router.navigate(to, { - state, - preventScrollReset: opts?.preventScrollReset, - }), - replace: (to, state, opts) => - router.navigate(to, { - replace: true, - state, - preventScrollReset: opts?.preventScrollReset, - }), - }; - }, [router]); - - const basename = router.basename || '/'; - - const dataRouterContext = React.useMemo( - () => ({ - router, - navigator, - static: false, - basename, - }), - [router, navigator, basename], - ); - const Providers = compose(...providers)((props) => <>{props.children}); - // The fragment and {null} here are important! We need them to keep React 18's - // useId happy when we are server-rendering since we may have a