@qlover/create-app 0.7.15 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/dist/configs/_common/.gitignore.template +6 -0
- package/dist/configs/_common/.prettierignore +17 -5
- package/dist/configs/_common/.vscode/settings.json +6 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/templates/next-app/.env.template +1 -1
- package/dist/templates/next-app/README.en.md +0 -1
- package/dist/templates/next-app/README.md +0 -1
- package/dist/templates/next-app/config/Identifier/api.ts +5 -5
- package/dist/templates/next-app/config/Identifier/common/admint.table.ts +69 -0
- package/dist/templates/next-app/config/Identifier/common/common.ts +76 -0
- package/dist/templates/next-app/config/Identifier/common/index.ts +3 -0
- package/dist/templates/next-app/config/Identifier/{validator.ts → common/validators.ts} +5 -5
- package/dist/templates/next-app/config/Identifier/index.ts +2 -12
- package/dist/templates/next-app/config/Identifier/pages/index.ts +6 -0
- package/dist/templates/next-app/config/Identifier/pages/page.admin.home.ts +27 -0
- package/dist/templates/next-app/config/Identifier/pages/page.admin.locales.ts +266 -0
- package/dist/templates/next-app/config/Identifier/pages/page.admin.user.ts +293 -0
- package/dist/templates/{react-app/config/Identifier → next-app/config/Identifier/pages}/page.home.ts +15 -22
- package/dist/templates/next-app/config/Identifier/{page.login.ts → pages/page.login.ts} +28 -34
- package/dist/templates/next-app/config/Identifier/{page.register.ts → pages/page.register.ts} +30 -29
- package/dist/templates/next-app/config/adminNavs.ts +19 -0
- package/dist/templates/next-app/config/common.ts +22 -13
- package/dist/templates/next-app/config/i18n/HomeI18n.ts +5 -5
- package/dist/templates/next-app/config/i18n/admin18n.ts +61 -19
- package/dist/templates/next-app/config/i18n/i18nConfig.ts +2 -0
- package/dist/templates/next-app/config/i18n/i18nKeyScheam.ts +36 -0
- package/dist/templates/next-app/config/i18n/loginI18n.ts +22 -22
- package/dist/templates/next-app/config/i18n/register18n.ts +23 -24
- package/dist/templates/next-app/docs/en/index.md +0 -1
- package/dist/templates/next-app/docs/en/project-structure.md +0 -1
- package/dist/templates/next-app/docs/zh/index.md +0 -1
- package/dist/templates/next-app/docs/zh/project-structure.md +0 -1
- package/dist/templates/next-app/make/generateLocales.ts +19 -12
- package/dist/templates/next-app/migrations/schema/LocalesSchema.ts +15 -0
- package/dist/templates/next-app/migrations/sql/1694244000000.sql +11 -0
- package/dist/templates/next-app/package.json +7 -3
- package/dist/templates/next-app/public/locales/en.json +172 -207
- package/dist/templates/next-app/public/locales/zh.json +172 -207
- package/dist/templates/next-app/src/app/[locale]/admin/locales/page.tsx +153 -0
- package/dist/templates/next-app/src/app/[locale]/admin/users/page.tsx +48 -50
- package/dist/templates/next-app/src/app/[locale]/login/LoginForm.tsx +2 -2
- package/dist/templates/next-app/src/app/api/admin/locales/create/route.ts +34 -0
- package/dist/templates/next-app/src/app/api/admin/locales/import/route.ts +40 -0
- package/dist/templates/next-app/src/app/api/admin/locales/route.ts +42 -0
- package/dist/templates/next-app/src/app/api/admin/locales/update/route.ts +32 -0
- package/dist/templates/next-app/src/app/api/locales/json/route.ts +44 -0
- package/dist/templates/next-app/src/base/cases/AdminPageManager.ts +1 -13
- package/dist/templates/next-app/src/base/cases/Datetime.ts +18 -0
- package/dist/templates/next-app/src/base/cases/DialogErrorPlugin.ts +12 -6
- package/dist/templates/next-app/src/base/cases/ResourceState.ts +17 -0
- package/dist/templates/next-app/src/base/cases/TranslateI18nInterface.ts +25 -0
- package/dist/templates/next-app/src/base/cases/ZodColumnBuilder.ts +200 -0
- package/dist/templates/next-app/src/base/port/ZodBuilderInterface.ts +8 -0
- package/dist/templates/next-app/src/base/services/AdminLocalesService.ts +20 -0
- package/dist/templates/next-app/src/base/services/AdminPageEvent.ts +26 -0
- package/dist/templates/next-app/src/base/services/AdminPageScheduler.ts +42 -0
- package/dist/templates/next-app/src/base/services/ResourceService.ts +122 -0
- package/dist/templates/next-app/src/base/services/adminApi/AdminLocalesApi.ts +104 -0
- package/dist/templates/next-app/src/base/services/adminApi/AdminUserApi.ts +38 -5
- package/dist/templates/next-app/src/base/services/appApi/AppApiPlugin.ts +1 -1
- package/dist/templates/next-app/src/i18n/request.ts +30 -1
- package/dist/templates/next-app/src/server/PageParams.ts +2 -10
- package/dist/templates/next-app/src/server/port/DBBridgeInterface.ts +5 -0
- package/dist/templates/next-app/src/server/port/DBTableInterface.ts +2 -0
- package/dist/templates/next-app/src/server/port/LocalesRepositoryInterface.ts +43 -0
- package/dist/templates/next-app/src/server/repositorys/LocalesRepository.ts +197 -0
- package/dist/templates/next-app/src/server/services/ApiLocaleService.ts +122 -0
- package/dist/templates/next-app/src/server/sqlBridges/SupabaseBridge.ts +60 -11
- package/dist/templates/next-app/src/server/validators/ExtendedExecutorError.ts +6 -0
- package/dist/templates/next-app/src/server/validators/LocalesValidator.ts +131 -0
- package/dist/templates/next-app/src/server/validators/LoginValidator.ts +2 -5
- package/dist/templates/next-app/src/server/validators/PaginationValidator.ts +32 -16
- package/dist/templates/next-app/src/styles/css/antd-themes/pagination/_default.css +2 -1
- package/dist/templates/next-app/src/styles/css/antd-themes/pagination/dark.css +28 -29
- package/dist/templates/next-app/src/styles/css/antd-themes/pagination/pink.css +2 -1
- package/dist/templates/next-app/src/uikit/components/AdminLayout.tsx +17 -3
- package/dist/templates/next-app/src/uikit/components/BaseHeader.tsx +5 -4
- package/dist/templates/next-app/src/uikit/components/BaseLayout.tsx +5 -4
- package/dist/templates/next-app/src/uikit/components/BootstrapsProvider.tsx +3 -2
- package/dist/templates/next-app/src/uikit/components/ComboProvider.tsx +1 -1
- package/dist/templates/next-app/src/uikit/components/EditableCell.tsx +118 -0
- package/dist/templates/next-app/src/uikit/components/LogoutButton.tsx +5 -6
- package/dist/templates/next-app/src/uikit/components/ThemeSwitcher.tsx +1 -1
- package/dist/templates/next-app/src/uikit/components/With.tsx +2 -2
- package/dist/templates/next-app/src/uikit/components/localesImportButton/LocalesImportButton.tsx +62 -0
- package/dist/templates/next-app/src/uikit/components/localesImportButton/LocalesImportEvent.ts +28 -0
- package/dist/templates/next-app/src/uikit/components/localesImportButton/import.module.css +6 -0
- package/dist/templates/next-app/src/uikit/hook/useI18nInterface.ts +8 -14
- package/dist/templates/next-app/src/uikit/hook/useWarnTranslations.ts +25 -0
- package/dist/templates/react-app/.prettierignore +17 -0
- package/dist/templates/react-app/README.en.md +71 -54
- package/dist/templates/react-app/README.md +35 -18
- package/dist/templates/react-app/__tests__/__mocks__/BootstrapTest.ts +14 -0
- package/dist/templates/react-app/__tests__/__mocks__/MockAppConfit.ts +1 -1
- package/dist/templates/react-app/__tests__/__mocks__/MockDialogHandler.ts +2 -2
- package/dist/templates/react-app/__tests__/__mocks__/MockLogger.ts +1 -1
- package/dist/templates/react-app/__tests__/__mocks__/components/TestApp.tsx +45 -0
- package/dist/templates/react-app/__tests__/__mocks__/components/TestBootstrapsProvider.tsx +34 -0
- package/dist/templates/react-app/__tests__/__mocks__/components/TestRouter.tsx +46 -0
- package/dist/templates/react-app/__tests__/__mocks__/components/index.ts +12 -0
- package/dist/templates/react-app/__tests__/__mocks__/createMockGlobals.ts +1 -2
- package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOC.ts +51 -0
- package/dist/templates/react-app/__tests__/__mocks__/testIOC/TestIOCRegister.ts +69 -0
- package/dist/templates/react-app/__tests__/setup/index.ts +1 -51
- package/dist/templates/react-app/__tests__/setup/setupGlobal.ts +51 -0
- package/dist/templates/react-app/__tests__/src/App.structure.test.tsx +115 -0
- package/dist/templates/react-app/__tests__/src/base/cases/AppConfig.test.ts +2 -2
- package/dist/templates/react-app/__tests__/src/base/cases/AppError.test.ts +1 -1
- package/dist/templates/react-app/__tests__/src/base/cases/DialogHandler.test.ts +3 -5
- package/dist/templates/react-app/__tests__/src/base/cases/I18nKeyErrorPlugin.test.ts +13 -2
- package/dist/templates/react-app/__tests__/src/base/cases/InversifyContainer.test.ts +1 -1
- package/dist/templates/react-app/__tests__/src/base/cases/PublicAssetsPath.test.ts +1 -1
- package/dist/templates/react-app/__tests__/src/base/cases/RequestLogger.test.ts +5 -5
- package/dist/templates/react-app/__tests__/src/base/cases/RequestStatusCatcher.test.ts +1 -2
- package/dist/templates/react-app/__tests__/src/base/cases/RouterLoader.test.ts +25 -15
- package/dist/templates/react-app/__tests__/src/base/services/I18nService.test.ts +29 -15
- package/dist/templates/react-app/__tests__/src/core/IOC.test.ts +19 -9
- package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapClient.test.ts +153 -0
- package/dist/templates/react-app/__tests__/src/core/bootstraps/BootstrapsApp.test.ts +9 -7
- package/dist/templates/react-app/__tests__/src/main.integration.test.tsx +4 -5
- package/dist/templates/react-app/__tests__/src/main.test.tsx +4 -4
- package/dist/templates/react-app/__tests__/src/uikit/components/BaseHeader.test.tsx +68 -59
- package/dist/templates/react-app/config/IOCIdentifier.ts +8 -8
- package/dist/templates/react-app/config/Identifier/{common.error.ts → common/common.error.ts} +5 -5
- package/dist/templates/react-app/config/Identifier/{common.ts → common/common.ts} +9 -9
- package/dist/templates/react-app/config/Identifier/common/index.ts +2 -0
- package/dist/templates/react-app/config/Identifier/index.ts +1 -9
- package/dist/templates/react-app/config/Identifier/pages/index.ts +8 -0
- package/dist/templates/react-app/config/Identifier/{page.about.ts → pages/page.about.ts} +34 -26
- package/dist/templates/react-app/config/Identifier/{page.executor.ts → pages/page.executor.ts} +47 -39
- package/dist/templates/{next-app/config/Identifier → react-app/config/Identifier/pages}/page.home.ts +24 -23
- package/dist/templates/react-app/config/Identifier/pages/page.identifiter.ts +102 -0
- package/dist/templates/react-app/config/Identifier/{page.jsonStorage.ts → pages/page.jsonStorage.ts} +18 -11
- package/dist/templates/react-app/config/Identifier/{page.login.ts → pages/page.login.ts} +37 -27
- package/dist/templates/react-app/config/Identifier/{page.register.ts → pages/page.register.ts} +37 -25
- package/dist/templates/react-app/config/Identifier/{page.request.ts → pages/page.request.ts} +34 -44
- package/dist/templates/react-app/config/app.router.ts +66 -69
- package/dist/templates/react-app/config/i18n/PageI18nInterface.ts +51 -0
- package/dist/templates/react-app/config/i18n/aboutI18n.ts +42 -0
- package/dist/templates/react-app/config/i18n/executorI18n.ts +51 -0
- package/dist/templates/react-app/config/i18n/homeI18n.ts +24 -0
- package/dist/templates/react-app/config/i18n/i18nConfig.ts +30 -0
- package/dist/templates/react-app/config/i18n/identifiter18n.ts +30 -0
- package/dist/templates/react-app/config/i18n/jsonStorage18n.ts +27 -0
- package/dist/templates/react-app/config/i18n/login18n.ts +42 -0
- package/dist/templates/react-app/config/i18n/notFoundI18n.ts +34 -0
- package/dist/templates/react-app/config/i18n/register18n.ts +40 -0
- package/dist/templates/react-app/config/i18n/request18n.ts +41 -0
- package/dist/templates/react-app/config/theme.ts +14 -4
- package/dist/templates/react-app/docs/en/bootstrap.md +1670 -341
- package/dist/templates/react-app/docs/en/development-guide.md +1021 -345
- package/dist/templates/react-app/docs/en/env.md +1132 -278
- package/dist/templates/react-app/docs/en/i18n.md +858 -147
- package/dist/templates/react-app/docs/en/index.md +733 -104
- package/dist/templates/react-app/docs/en/ioc.md +1228 -287
- package/dist/templates/react-app/docs/en/playwright/e2e-tests.md +321 -0
- package/dist/templates/react-app/docs/en/playwright/index.md +19 -0
- package/dist/templates/react-app/docs/en/playwright/installation-summary.md +332 -0
- package/dist/templates/react-app/docs/en/playwright/overview.md +222 -0
- package/dist/templates/react-app/docs/en/playwright/quickstart.md +325 -0
- package/dist/templates/react-app/docs/en/playwright/reorganization-notes.md +340 -0
- package/dist/templates/react-app/docs/en/playwright/setup-complete.md +290 -0
- package/dist/templates/react-app/docs/en/playwright/testing-guide.md +565 -0
- package/dist/templates/react-app/docs/en/store.md +1194 -184
- package/dist/templates/react-app/docs/en/why-no-globals.md +797 -0
- package/dist/templates/react-app/docs/zh/bootstrap.md +1670 -341
- package/dist/templates/react-app/docs/zh/development-guide.md +1021 -345
- package/dist/templates/react-app/docs/zh/env.md +1132 -275
- package/dist/templates/react-app/docs/zh/i18n.md +858 -147
- package/dist/templates/react-app/docs/zh/index.md +717 -104
- package/dist/templates/react-app/docs/zh/ioc.md +1229 -287
- package/dist/templates/react-app/docs/zh/playwright/e2e-tests.md +321 -0
- package/dist/templates/react-app/docs/zh/playwright/index.md +19 -0
- package/dist/templates/react-app/docs/zh/playwright/installation-summary.md +332 -0
- package/dist/templates/react-app/docs/zh/playwright/overview.md +222 -0
- package/dist/templates/react-app/docs/zh/playwright/quickstart.md +325 -0
- package/dist/templates/react-app/docs/zh/playwright/reorganization-notes.md +340 -0
- package/dist/templates/react-app/docs/zh/playwright/setup-complete.md +290 -0
- package/dist/templates/react-app/docs/zh/playwright/testing-guide.md +565 -0
- package/dist/templates/react-app/docs/zh/store.md +1192 -184
- package/dist/templates/react-app/docs/zh/why-no-globals.md +797 -0
- package/dist/templates/react-app/e2e/App.spec.ts +319 -0
- package/dist/templates/react-app/e2e/fixtures/base.fixture.ts +40 -0
- package/dist/templates/react-app/e2e/main.spec.ts +20 -0
- package/dist/templates/react-app/e2e/utils/test-helpers.ts +19 -0
- package/dist/templates/react-app/eslint.config.mjs +247 -0
- package/dist/templates/react-app/makes/eslint-utils.mjs +195 -0
- package/dist/templates/react-app/makes/generateTs2LocalesOptions.ts +26 -0
- package/dist/templates/react-app/package.json +31 -3
- package/dist/templates/react-app/playwright.config.ts +79 -0
- package/dist/templates/react-app/public/locales/en/common.json +190 -179
- package/dist/templates/react-app/public/locales/zh/common.json +190 -179
- package/dist/templates/react-app/src/App.tsx +15 -42
- package/dist/templates/react-app/src/base/apis/AiApi.ts +5 -5
- package/dist/templates/react-app/src/base/apis/feApi/FeApi.ts +1 -1
- package/dist/templates/react-app/src/base/apis/feApi/FeApiAdapter.ts +1 -1
- package/dist/templates/react-app/src/base/apis/feApi/FeApiBootstarp.ts +8 -8
- package/dist/templates/react-app/src/base/apis/feApi/FeApiType.ts +1 -1
- package/dist/templates/react-app/src/base/apis/userApi/UserApi.ts +6 -6
- package/dist/templates/react-app/src/base/apis/userApi/UserApiAdapter.ts +1 -1
- package/dist/templates/react-app/src/base/apis/userApi/UserApiBootstarp.ts +12 -14
- package/dist/templates/react-app/src/base/apis/userApi/UserApiType.ts +1 -1
- package/dist/templates/react-app/src/base/cases/DialogHandler.ts +5 -2
- package/dist/templates/react-app/src/base/cases/I18nKeyErrorPlugin.ts +3 -3
- package/dist/templates/react-app/src/base/cases/InversifyContainer.ts +3 -3
- package/dist/templates/react-app/src/base/cases/RequestLanguages.ts +2 -2
- package/dist/templates/react-app/src/base/cases/RequestLogger.ts +4 -4
- package/dist/templates/react-app/src/base/cases/RequestStatusCatcher.ts +1 -1
- package/dist/templates/react-app/src/base/cases/ResourceState.ts +23 -0
- package/dist/templates/react-app/src/base/cases/RouterLoader.ts +4 -4
- package/dist/templates/react-app/src/base/cases/TranslateI18nInterface.ts +26 -0
- package/dist/templates/react-app/src/base/port/ExecutorPageBridgeInterface.ts +2 -3
- package/dist/templates/react-app/src/base/port/I18nServiceInterface.ts +1 -1
- package/dist/templates/react-app/src/base/port/IOCInterface.ts +36 -0
- package/dist/templates/react-app/src/base/port/JSONStoragePageBridgeInterface.ts +2 -1
- package/dist/templates/react-app/src/base/port/ProcesserExecutorInterface.ts +1 -1
- package/dist/templates/react-app/src/base/port/RequestPageBridgeInterface.ts +2 -2
- package/dist/templates/react-app/src/base/port/RouteServiceInterface.ts +9 -5
- package/dist/templates/react-app/src/base/port/UserServiceInterface.ts +1 -1
- package/dist/templates/react-app/src/base/services/I18nService.ts +29 -29
- package/dist/templates/react-app/src/base/services/IdentifierService.ts +143 -0
- package/dist/templates/react-app/src/base/services/ProcesserExecutor.ts +3 -3
- package/dist/templates/react-app/src/base/services/RouteService.ts +27 -8
- package/dist/templates/react-app/src/base/services/UserService.ts +8 -8
- package/dist/templates/react-app/src/base/types/Page.ts +14 -2
- package/dist/templates/react-app/src/base/types/global.d.ts +1 -1
- package/dist/templates/react-app/src/core/IOC.ts +5 -46
- package/dist/templates/react-app/src/core/bootstraps/{BootstrapApp.ts → BootstrapClient.ts} +44 -17
- package/dist/templates/react-app/src/core/bootstraps/BootstrapsRegistry.ts +14 -7
- package/dist/templates/react-app/src/core/bootstraps/IocIdentifierTest.ts +1 -1
- package/dist/templates/react-app/src/core/bootstraps/PrintBootstrap.ts +1 -1
- package/dist/templates/react-app/src/core/clientIoc/ClientIOC.ts +40 -0
- package/dist/templates/react-app/src/core/{IocRegisterImpl.ts → clientIoc/ClientIOCRegister.ts} +35 -24
- package/dist/templates/react-app/src/core/globals.ts +9 -9
- package/dist/templates/react-app/src/main.tsx +4 -4
- package/dist/templates/react-app/src/pages/404.tsx +6 -3
- package/dist/templates/react-app/src/pages/500.tsx +5 -2
- package/dist/templates/react-app/src/pages/NoRouteFound.tsx +5 -0
- package/dist/templates/react-app/src/pages/auth/Layout.tsx +9 -6
- package/dist/templates/react-app/src/pages/auth/LoginPage.tsx +46 -56
- package/dist/templates/react-app/src/pages/auth/RegisterPage.tsx +46 -58
- package/dist/templates/react-app/src/pages/base/AboutPage.tsx +35 -40
- package/dist/templates/react-app/src/pages/base/ExecutorPage.tsx +51 -51
- package/dist/templates/react-app/src/pages/base/HomePage.tsx +14 -15
- package/dist/templates/react-app/src/pages/base/IdentifierPage.tsx +70 -11
- package/dist/templates/react-app/src/pages/base/JSONStoragePage.tsx +24 -25
- package/dist/templates/react-app/src/pages/base/Layout.tsx +2 -2
- package/dist/templates/react-app/src/pages/base/RedirectPathname.tsx +3 -2
- package/dist/templates/react-app/src/pages/base/RequestPage.tsx +41 -59
- package/dist/templates/react-app/src/styles/css/antd-themes/{_default.css → _common/_default.css} +85 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/{dark.css → _common/dark.css} +99 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/_common/index.css +3 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/{pink.css → _common/pink.css} +86 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/index.css +4 -3
- package/dist/templates/react-app/src/styles/css/antd-themes/menu/_default.css +108 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/menu/dark.css +67 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/menu/index.css +3 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/menu/pink.css +67 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/pagination/_default.css +34 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/pagination/dark.css +31 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/pagination/index.css +3 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/pagination/pink.css +36 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/table/_default.css +44 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/table/dark.css +43 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/table/index.css +3 -0
- package/dist/templates/react-app/src/styles/css/antd-themes/table/pink.css +43 -0
- package/dist/templates/react-app/src/styles/css/page.css +4 -3
- package/dist/templates/react-app/src/styles/css/themes/_default.css +1 -0
- package/dist/templates/react-app/src/styles/css/themes/dark.css +1 -0
- package/dist/templates/react-app/src/styles/css/themes/pink.css +1 -0
- package/dist/templates/react-app/src/styles/css/zIndex.css +1 -1
- package/dist/templates/react-app/src/uikit/bridges/ExecutorPageBridge.ts +3 -3
- package/dist/templates/react-app/src/uikit/bridges/JSONStoragePageBridge.ts +2 -2
- package/dist/templates/react-app/src/uikit/bridges/NavigateBridge.ts +1 -1
- package/dist/templates/react-app/src/uikit/bridges/RequestPageBridge.ts +3 -3
- package/dist/templates/react-app/src/uikit/components/AppRouterProvider.tsx +35 -0
- package/dist/templates/react-app/src/uikit/components/BaseHeader.tsx +15 -11
- package/dist/templates/react-app/src/uikit/components/BaseRouteProvider.tsx +14 -11
- package/dist/templates/react-app/src/uikit/components/BaseRouteSeo.tsx +18 -0
- package/dist/templates/react-app/src/uikit/components/BootstrapsProvider.tsx +13 -0
- package/dist/templates/react-app/src/uikit/components/ClientSeo.tsx +62 -0
- package/dist/templates/react-app/src/uikit/components/ComboProvider.tsx +38 -0
- package/dist/templates/react-app/src/uikit/components/LanguageSwitcher.tsx +48 -27
- package/dist/templates/react-app/src/uikit/components/Loading.tsx +4 -2
- package/dist/templates/react-app/src/uikit/components/LocaleLink.tsx +4 -5
- package/dist/templates/react-app/src/uikit/components/LogoutButton.tsx +34 -11
- package/dist/templates/react-app/src/uikit/components/ProcessExecutorProvider.tsx +9 -5
- package/dist/templates/react-app/src/uikit/components/RouterRenderComponent.tsx +6 -3
- package/dist/templates/react-app/src/uikit/components/ThemeSwitcher.tsx +97 -40
- package/dist/templates/react-app/src/uikit/components/UserAuthProvider.tsx +5 -5
- package/dist/templates/react-app/src/uikit/components/With.tsx +17 -0
- package/dist/templates/react-app/src/uikit/contexts/BaseRouteContext.ts +17 -11
- package/dist/templates/react-app/src/uikit/contexts/IOCContext.ts +13 -0
- package/dist/templates/react-app/src/uikit/hooks/useAppTranslation.ts +26 -0
- package/dist/templates/react-app/src/uikit/hooks/useI18nGuard.ts +8 -11
- package/dist/templates/react-app/src/uikit/hooks/useI18nInterface.ts +25 -0
- package/dist/templates/react-app/src/uikit/hooks/useIOC.ts +35 -0
- package/dist/templates/react-app/src/uikit/hooks/useNavigateBridge.ts +3 -3
- package/dist/templates/react-app/src/uikit/hooks/useStrictEffect.ts +0 -1
- package/dist/templates/react-app/tsconfig.e2e.json +21 -0
- package/dist/templates/react-app/tsconfig.json +8 -1
- package/dist/templates/react-app/tsconfig.node.json +1 -1
- package/dist/templates/react-app/tsconfig.test.json +3 -1
- package/dist/templates/react-app/vite.config.ts +50 -34
- package/package.json +2 -1
- package/dist/configs/react-app/eslint.config.js +0 -94
- package/dist/templates/next-app/config/Identifier/common.error.ts +0 -41
- package/dist/templates/next-app/config/Identifier/common.ts +0 -69
- package/dist/templates/next-app/config/Identifier/page.about.ts +0 -181
- package/dist/templates/next-app/config/Identifier/page.admin.ts +0 -48
- package/dist/templates/next-app/config/Identifier/page.executor.ts +0 -272
- package/dist/templates/next-app/config/Identifier/page.identifiter.ts +0 -39
- package/dist/templates/next-app/config/Identifier/page.jsonStorage.ts +0 -72
- package/dist/templates/next-app/config/Identifier/page.request.ts +0 -182
- package/dist/templates/next-app/src/base/cases/ChatAction.ts +0 -21
- package/dist/templates/next-app/src/base/cases/FocusBarAction.ts +0 -36
- package/dist/templates/next-app/src/base/cases/RequestState.ts +0 -20
- package/dist/templates/next-app/src/base/port/AdminPageInterface.ts +0 -85
- package/dist/templates/next-app/src/base/port/AsyncStateInterface.ts +0 -7
- package/dist/templates/next-app/src/base/services/AdminUserService.ts +0 -45
- package/dist/templates/next-app/src/uikit/components/ChatRoot.tsx +0 -17
- package/dist/templates/next-app/src/uikit/components/chat/ChatActionInterface.ts +0 -30
- package/dist/templates/next-app/src/uikit/components/chat/ChatFocusBar.tsx +0 -65
- package/dist/templates/next-app/src/uikit/components/chat/ChatMessages.tsx +0 -59
- package/dist/templates/next-app/src/uikit/components/chat/ChatWrap.tsx +0 -28
- package/dist/templates/next-app/src/uikit/components/chat/FocusBarActionInterface.ts +0 -19
- package/dist/templates/next-app/src/uikit/hook/useMountedClient.ts +0 -17
- package/dist/templates/next-app/src/uikit/hook/useStore.ts +0 -15
- package/dist/templates/react-app/__tests__/__mocks__/I18nService.ts +0 -13
- package/dist/templates/react-app/__tests__/src/App.test.tsx +0 -139
- package/dist/templates/react-app/config/Identifier/page.identifiter.ts +0 -39
- package/dist/templates/react-app/config/i18n.ts +0 -15
- package/dist/templates/react-app/docs/en/project-structure.md +0 -434
- package/dist/templates/react-app/docs/zh/project-structure.md +0 -434
- package/dist/templates/react-app/src/base/cases/RequestState.ts +0 -20
- package/dist/templates/react-app/src/base/port/AsyncStateInterface.ts +0 -7
- package/dist/templates/react-app/src/uikit/hooks/useDocumentTitle.ts +0 -15
- package/dist/templates/react-app/src/uikit/hooks/useStore.ts +0 -15
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
FetchAbortPlugin,
|
|
3
|
-
RequestAdapterConfig,
|
|
4
|
-
RequestAdapterResponse,
|
|
5
|
-
RequestTransactionInterface
|
|
6
|
-
} from '@qlover/fe-corekit';
|
|
7
|
-
import { IOC } from '@/core/IOC';
|
|
8
1
|
import { IOCIdentifier } from '@config/IOCIdentifier';
|
|
9
|
-
import { RequestLogger } from '@/base/cases/RequestLogger';
|
|
10
|
-
import { FetchURLPlugin } from '@qlover/fe-corekit';
|
|
11
2
|
import {
|
|
12
3
|
type BootstrapContext,
|
|
13
4
|
type BootstrapExecutorPlugin,
|
|
@@ -15,8 +6,15 @@ import {
|
|
|
15
6
|
type ApiCatchPluginConfig,
|
|
16
7
|
type ApiCatchPluginResponse
|
|
17
8
|
} from '@qlover/corekit-bridge';
|
|
9
|
+
import { FetchAbortPlugin, FetchURLPlugin } from '@qlover/fe-corekit';
|
|
10
|
+
import { RequestLogger } from '@/base/cases/RequestLogger';
|
|
18
11
|
import { UserApi } from './UserApi';
|
|
19
12
|
import { RequestLanguages } from '../../cases/RequestLanguages';
|
|
13
|
+
import type {
|
|
14
|
+
RequestAdapterConfig,
|
|
15
|
+
RequestAdapterResponse,
|
|
16
|
+
RequestTransactionInterface
|
|
17
|
+
} from '@qlover/fe-corekit';
|
|
20
18
|
|
|
21
19
|
/**
|
|
22
20
|
* UserApiConfig
|
|
@@ -68,13 +66,13 @@ export class UserApiBootstarp implements BootstrapExecutorPlugin {
|
|
|
68
66
|
ioc
|
|
69
67
|
.get<UserApi>(UserApi)
|
|
70
68
|
.usePlugin(new FetchURLPlugin())
|
|
71
|
-
.usePlugin(
|
|
69
|
+
.usePlugin(ioc.get(IOCIdentifier.FeApiCommonPlugin))
|
|
72
70
|
.usePlugin(
|
|
73
71
|
new RequestLanguages(ioc.get(IOCIdentifier.I18nServiceInterface))
|
|
74
72
|
)
|
|
75
|
-
.usePlugin(
|
|
76
|
-
.usePlugin(
|
|
77
|
-
.usePlugin(
|
|
78
|
-
.usePlugin(
|
|
73
|
+
.usePlugin(ioc.get(IOCIdentifier.ApiMockPlugin))
|
|
74
|
+
.usePlugin(ioc.get(RequestLogger))
|
|
75
|
+
.usePlugin(ioc.get(FetchAbortPlugin))
|
|
76
|
+
.usePlugin(ioc.get(IOCIdentifier.ApiCatchPlugin));
|
|
79
77
|
}
|
|
80
78
|
}
|
|
@@ -4,8 +4,11 @@ import type {
|
|
|
4
4
|
ModalApi,
|
|
5
5
|
NotificationApi
|
|
6
6
|
} from '@brain-toolkit/antd-theme-override/react';
|
|
7
|
-
import {
|
|
8
|
-
|
|
7
|
+
import type {
|
|
8
|
+
UIDialogInterface,
|
|
9
|
+
NotificationOptions
|
|
10
|
+
} from '@qlover/corekit-bridge';
|
|
11
|
+
import type { ModalFuncProps } from 'antd';
|
|
9
12
|
|
|
10
13
|
export interface DialogHandlerOptions
|
|
11
14
|
extends NotificationOptions,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { ExecutorContext, ExecutorPlugin } from '@qlover/fe-corekit';
|
|
2
|
-
import type { LoggerInterface } from '@qlover/logger';
|
|
3
|
-
import { inject, injectable } from 'inversify';
|
|
4
1
|
import { IOCIdentifier } from '@config/IOCIdentifier';
|
|
2
|
+
import { inject, injectable } from 'inversify';
|
|
5
3
|
import type { I18nServiceInterface } from '../port/I18nServiceInterface';
|
|
4
|
+
import type { ExecutorContext, ExecutorPlugin } from '@qlover/fe-corekit';
|
|
5
|
+
import type { LoggerInterface } from '@qlover/logger';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* When throw error, it will be converted to i18n key
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Container } from 'inversify';
|
|
2
|
+
import type { IOCIdentifierMap } from '@config/IOCIdentifier';
|
|
3
|
+
import type {
|
|
3
4
|
IOCContainerInterface,
|
|
4
5
|
ServiceIdentifier
|
|
5
6
|
} from '@qlover/corekit-bridge';
|
|
6
|
-
import { Container } from 'inversify';
|
|
7
7
|
|
|
8
8
|
export class InversifyContainer implements IOCContainerInterface {
|
|
9
9
|
protected container: Container;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { IOCIdentifier } from '@config/IOCIdentifier';
|
|
2
|
+
import {
|
|
3
|
+
type ApiCatchPluginConfig,
|
|
4
|
+
type ApiCatchPluginResponse
|
|
5
|
+
} from '@qlover/corekit-bridge';
|
|
2
6
|
import {
|
|
3
7
|
type ExecutorPlugin,
|
|
4
8
|
type ExecutorContext,
|
|
5
9
|
type RequestAdapterFetchConfig,
|
|
6
10
|
type RequestAdapterResponse
|
|
7
11
|
} from '@qlover/fe-corekit';
|
|
8
|
-
import {
|
|
9
|
-
type ApiCatchPluginConfig,
|
|
10
|
-
type ApiCatchPluginResponse
|
|
11
|
-
} from '@qlover/corekit-bridge';
|
|
12
12
|
import { injectable, inject } from 'inversify';
|
|
13
13
|
import type { LoggerInterface } from '@qlover/logger';
|
|
14
14
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { IOCIdentifier } from '@config/IOCIdentifier';
|
|
2
|
+
import { inject, injectable } from 'inversify';
|
|
2
3
|
import type { RequestCatcherInterface } from '@qlover/corekit-bridge';
|
|
3
4
|
import type { RequestAdapterResponse } from '@qlover/fe-corekit';
|
|
4
5
|
import type { LoggerInterface } from '@qlover/logger';
|
|
5
|
-
import { inject, injectable } from 'inversify';
|
|
6
6
|
|
|
7
7
|
@injectable()
|
|
8
8
|
export class RequestStatusCatcher
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { RequestState } from '@qlover/corekit-bridge';
|
|
2
|
+
import type {
|
|
3
|
+
ResourceQuery,
|
|
4
|
+
ResourceStateInterface
|
|
5
|
+
} from '@qlover/corekit-bridge';
|
|
6
|
+
|
|
7
|
+
export interface PaginationInterface<T> {
|
|
8
|
+
list: T[];
|
|
9
|
+
total: number;
|
|
10
|
+
page: number;
|
|
11
|
+
pageSize: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class ResourceState implements ResourceStateInterface {
|
|
15
|
+
searchParams: ResourceQuery = {
|
|
16
|
+
page: 1,
|
|
17
|
+
pageSize: 10,
|
|
18
|
+
orderBy: 'updated_at',
|
|
19
|
+
order: 1
|
|
20
|
+
};
|
|
21
|
+
initState = new RequestState<unknown>();
|
|
22
|
+
listState = new RequestState<PaginationInterface<unknown>>();
|
|
23
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { ComponentType, LazyExoticComponent, ReactNode } from 'react';
|
|
2
|
-
import { RouteObject } from 'react-router-dom';
|
|
3
1
|
import isString from 'lodash/isString';
|
|
4
|
-
import { RouteMeta } from '../types/Page';
|
|
5
|
-
import { LoggerInterface } from '@qlover/logger';
|
|
2
|
+
import type { RouteMeta } from '../types/Page';
|
|
3
|
+
import type { LoggerInterface } from '@qlover/logger';
|
|
4
|
+
import type { ComponentType, LazyExoticComponent, ReactNode } from 'react';
|
|
5
|
+
import type { RouteObject } from 'react-router-dom';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Component mapping type for lazy-loaded components
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { PageI18nInterface } from '@config/i18n/PageI18nInterface';
|
|
2
|
+
import type { TFunction } from 'i18next';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Translate I18n Interface tools class
|
|
6
|
+
*
|
|
7
|
+
* @param i18nInterface - The i18n interface to translate
|
|
8
|
+
* @param t - The translations function
|
|
9
|
+
* @returns The translated i18n interface
|
|
10
|
+
*/
|
|
11
|
+
export class TranslateI18nInterface {
|
|
12
|
+
static translate<T extends PageI18nInterface | Record<string, string>>(
|
|
13
|
+
source: T,
|
|
14
|
+
t: TFunction<string, string>
|
|
15
|
+
): T {
|
|
16
|
+
return Object.fromEntries(
|
|
17
|
+
Object.entries(source).map(([key, value]) => {
|
|
18
|
+
if (typeof value === 'string') {
|
|
19
|
+
// 禁用命名空间分隔符,避免冒号被解析为命名空间
|
|
20
|
+
return [key, t(value, { nsSeparator: false })];
|
|
21
|
+
}
|
|
22
|
+
return [key, value];
|
|
23
|
+
})
|
|
24
|
+
) as T;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { StoreInterface
|
|
2
|
-
import { RequestState } from '
|
|
1
|
+
import { StoreInterface } from '@qlover/corekit-bridge';
|
|
2
|
+
import type { StoreStateInterface, RequestState } from '@qlover/corekit-bridge';
|
|
3
3
|
|
|
4
4
|
export interface ExecutorPageStateInterface extends StoreStateInterface {
|
|
5
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
5
|
helloState: RequestState<any>;
|
|
7
6
|
}
|
|
8
7
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BootstrapExecutorPlugin } from '@qlover/corekit-bridge';
|
|
1
|
+
import type { BootstrapExecutorPlugin } from '@qlover/corekit-bridge';
|
|
2
2
|
|
|
3
3
|
export interface I18nServiceInterface extends BootstrapExecutorPlugin {
|
|
4
4
|
t(key: string, params?: Record<string, unknown>): string;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
EnvConfigInterface,
|
|
3
|
+
IOCContainerInterface,
|
|
4
|
+
IOCFunctionInterface,
|
|
5
|
+
IOCRegisterInterface
|
|
6
|
+
} from '@qlover/corekit-bridge';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* IOC register options
|
|
10
|
+
*/
|
|
11
|
+
export type IocRegisterOptions = {
|
|
12
|
+
/**
|
|
13
|
+
* The pathname of the current page
|
|
14
|
+
*/
|
|
15
|
+
pathname: string;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The app config
|
|
19
|
+
*/
|
|
20
|
+
appConfig: EnvConfigInterface;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export interface IOCInterface<
|
|
24
|
+
IdentifierMap,
|
|
25
|
+
IOCContainer extends IOCContainerInterface
|
|
26
|
+
> {
|
|
27
|
+
create(
|
|
28
|
+
options: IocRegisterOptions
|
|
29
|
+
): IOCFunctionInterface<IdentifierMap, IOCContainer>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 提供一个快捷的注册器类型名
|
|
34
|
+
*/
|
|
35
|
+
export interface IOCRegister
|
|
36
|
+
extends IOCRegisterInterface<IOCContainerInterface, IocRegisterOptions> {}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { StoreInterface
|
|
1
|
+
import { StoreInterface } from '@qlover/corekit-bridge';
|
|
2
|
+
import type { StoreStateInterface } from '@qlover/corekit-bridge';
|
|
2
3
|
|
|
3
4
|
export interface JSONStoragePageStateInterface extends StoreStateInterface {
|
|
4
5
|
testKey1?: number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { StoreInterface
|
|
2
|
-
import { RequestState } from '
|
|
1
|
+
import { StoreInterface } from '@qlover/corekit-bridge';
|
|
2
|
+
import type { StoreStateInterface, RequestState } from '@qlover/corekit-bridge';
|
|
3
3
|
|
|
4
4
|
export interface RequestPageStateInterface extends StoreStateInterface {
|
|
5
5
|
helloState: RequestState<unknown>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { StoreInterface } from '@qlover/corekit-bridge';
|
|
2
|
+
import type { RouteConfigValue } from '../cases/RouterLoader';
|
|
3
|
+
import type {
|
|
2
4
|
LoggerInterface,
|
|
3
|
-
StoreInterface,
|
|
4
5
|
StoreStateInterface
|
|
5
6
|
} from '@qlover/corekit-bridge';
|
|
6
|
-
import {
|
|
7
|
-
import { NavigateFunction, NavigateOptions } from 'react-router-dom';
|
|
7
|
+
import type { NavigateFunction, NavigateOptions } from 'react-router-dom';
|
|
8
8
|
|
|
9
9
|
export interface RouteServiceStateInterface extends StoreStateInterface {
|
|
10
10
|
routes: RouteConfigValue[];
|
|
@@ -23,5 +23,9 @@ export abstract class RouteServiceInterface extends StoreInterface<RouteServiceS
|
|
|
23
23
|
abstract gotoLogin(): void;
|
|
24
24
|
abstract replaceToHome(): void;
|
|
25
25
|
abstract redirectToDefault(navigate: NavigateFunction): void;
|
|
26
|
-
abstract i18nGuard(
|
|
26
|
+
abstract i18nGuard(
|
|
27
|
+
currentPath: string,
|
|
28
|
+
lng: string,
|
|
29
|
+
navigate?: NavigateFunction
|
|
30
|
+
): void;
|
|
27
31
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UserAuthService } from '@qlover/corekit-bridge';
|
|
2
|
-
import { ExecutorPlugin } from '@qlover/fe-corekit';
|
|
3
2
|
import type { UserInfo } from '@/base/apis/userApi/UserApiType';
|
|
3
|
+
import type { ExecutorPlugin } from '@qlover/fe-corekit';
|
|
4
4
|
|
|
5
5
|
export abstract class UserServiceInterface
|
|
6
6
|
extends UserAuthService<UserInfo>
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import HttpApi from 'i18next-http-backend';
|
|
5
|
-
import merge from 'lodash/merge';
|
|
6
|
-
import i18nConfig from '@config/i18n';
|
|
1
|
+
/* eslint-disable import/no-named-as-default-member */
|
|
2
|
+
import { useLocaleRoutes } from '@config/common';
|
|
3
|
+
import { i18nConfig } from '@config/i18n/i18nConfig';
|
|
7
4
|
import {
|
|
8
5
|
type StoreStateInterface,
|
|
9
6
|
StoreInterface
|
|
10
7
|
} from '@qlover/corekit-bridge';
|
|
11
|
-
import
|
|
12
|
-
import
|
|
8
|
+
import i18n from 'i18next';
|
|
9
|
+
import LanguageDetector from 'i18next-browser-languagedetector';
|
|
10
|
+
import HttpApi from 'i18next-http-backend';
|
|
11
|
+
import merge from 'lodash/merge';
|
|
12
|
+
import { initReactI18next } from 'react-i18next';
|
|
13
|
+
import type { LocaleType } from '@config/i18n/i18nConfig';
|
|
14
|
+
import type { I18nServiceInterface } from '../port/I18nServiceInterface';
|
|
13
15
|
|
|
14
16
|
const { supportedLngs, fallbackLng } = i18nConfig;
|
|
15
17
|
|
|
16
|
-
export type I18nServiceLocale = (typeof supportedLngs)[number];
|
|
17
|
-
|
|
18
18
|
export class I18nServiceState implements StoreStateInterface {
|
|
19
19
|
loading: boolean = false;
|
|
20
|
-
constructor(public language:
|
|
20
|
+
constructor(public language: LocaleType) {}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export class I18nService
|
|
@@ -27,11 +27,12 @@ export class I18nService
|
|
|
27
27
|
readonly pluginName = 'I18nService';
|
|
28
28
|
|
|
29
29
|
selector = {
|
|
30
|
-
loading: (state: I18nServiceState) => state.loading
|
|
30
|
+
loading: (state: I18nServiceState) => state.loading,
|
|
31
|
+
language: (state: I18nServiceState) => state.language
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
constructor(protected pathname: string) {
|
|
34
|
-
super(() => new I18nServiceState(i18n.language as
|
|
35
|
+
super(() => new I18nServiceState(i18n.language as LocaleType));
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
/**
|
|
@@ -70,31 +71,30 @@ export class I18nService
|
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
return fallbackLng;
|
|
73
|
-
},
|
|
74
|
-
cacheUserLanguage(lng: string) {
|
|
75
|
-
// Only cache language if not using locale routes
|
|
76
|
-
if (!useLocaleRoutes) {
|
|
77
|
-
localStorage.setItem('i18nextLng', lng);
|
|
78
|
-
}
|
|
79
74
|
}
|
|
80
75
|
};
|
|
81
76
|
i18n.services.languageDetector.addDetector(pathLanguageDetector);
|
|
77
|
+
|
|
78
|
+
// Sync i18n.language with state.language
|
|
79
|
+
i18n.on('languageChanged', (lng: string) => {
|
|
80
|
+
if (this.isValidLanguage(lng) && this.state.language !== lng) {
|
|
81
|
+
this.emit({ ...this.state, language: lng as LocaleType });
|
|
82
|
+
}
|
|
83
|
+
});
|
|
82
84
|
}
|
|
83
85
|
|
|
84
|
-
async changeLanguage(language:
|
|
86
|
+
async changeLanguage(language: LocaleType): Promise<void> {
|
|
85
87
|
await i18n.changeLanguage(language);
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
localStorage.setItem('i18nextLng', language);
|
|
89
|
-
}
|
|
88
|
+
// Sync state with i18n.language
|
|
89
|
+
this.emit({ ...this.state, language });
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
changeLoading(loading: boolean): void {
|
|
93
93
|
this.emit({ ...this.state, loading });
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
-
getCurrentLanguage():
|
|
97
|
-
return i18n.language as
|
|
96
|
+
getCurrentLanguage(): LocaleType {
|
|
97
|
+
return i18n.language as LocaleType;
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
/**
|
|
@@ -102,11 +102,11 @@ export class I18nService
|
|
|
102
102
|
* @param language - language to check
|
|
103
103
|
* @returns true if the language is supported, false otherwise
|
|
104
104
|
*/
|
|
105
|
-
isValidLanguage(language: string): language is
|
|
106
|
-
return supportedLngs.includes(language as
|
|
105
|
+
isValidLanguage(language: string): language is LocaleType {
|
|
106
|
+
return supportedLngs.includes(language as LocaleType);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
getSupportedLanguages():
|
|
109
|
+
getSupportedLanguages(): LocaleType[] {
|
|
110
110
|
return [...supportedLngs];
|
|
111
111
|
}
|
|
112
112
|
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { routerPrefix } from '@config/common';
|
|
2
|
+
import { I } from '@config/IOCIdentifier';
|
|
3
|
+
import {
|
|
4
|
+
RequestState,
|
|
5
|
+
type ResourceStateInterface,
|
|
6
|
+
type ResourceServiceInterface,
|
|
7
|
+
type ResourceInterface,
|
|
8
|
+
type ResourceQuery,
|
|
9
|
+
ResourceStore
|
|
10
|
+
} from '@qlover/corekit-bridge';
|
|
11
|
+
import { inject, injectable } from 'inversify';
|
|
12
|
+
import type { LocaleType } from '@config/i18n/i18nConfig';
|
|
13
|
+
import { I18nService } from './I18nService';
|
|
14
|
+
import { PaginationInterface, ResourceState } from '../cases/ResourceState';
|
|
15
|
+
|
|
16
|
+
export interface IdentifierRecord {
|
|
17
|
+
id: string;
|
|
18
|
+
locale: LocaleType;
|
|
19
|
+
localeValue: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@injectable()
|
|
23
|
+
export class IdentifierService<T>
|
|
24
|
+
implements ResourceServiceInterface<T, ResourceStore<ResourceStateInterface>>
|
|
25
|
+
{
|
|
26
|
+
readonly unionKey: string = 'id';
|
|
27
|
+
readonly serviceName: string = 'IdentifierService';
|
|
28
|
+
readonly store: ResourceStore<ResourceStateInterface>;
|
|
29
|
+
// Not implemented
|
|
30
|
+
readonly resourceApi!: ResourceInterface<T>;
|
|
31
|
+
private unsubscribe: (() => void) | null = null;
|
|
32
|
+
|
|
33
|
+
constructor(
|
|
34
|
+
@inject(I.I18nServiceInterface)
|
|
35
|
+
protected readonly i18nService: I18nService
|
|
36
|
+
) {
|
|
37
|
+
this.store = new ResourceStore(() => new ResourceState());
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
getStore(): ResourceStore<ResourceStateInterface> {
|
|
41
|
+
return this.store;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
protected async init(): Promise<unknown> {
|
|
45
|
+
this.store.changeInitState(new RequestState(true));
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const result = await this.search({
|
|
49
|
+
locale: this.i18nService.getCurrentLanguage() as LocaleType
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
this.store.changeInitState(new RequestState(false, result).end());
|
|
53
|
+
return result;
|
|
54
|
+
} catch (error) {
|
|
55
|
+
this.store.changeInitState(new RequestState(false, null, error).end());
|
|
56
|
+
|
|
57
|
+
return error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @override
|
|
63
|
+
*/
|
|
64
|
+
async created(): Promise<unknown> {
|
|
65
|
+
this.unsubscribe = this.i18nService.observe(
|
|
66
|
+
(state) => state.language,
|
|
67
|
+
() => {
|
|
68
|
+
this.init();
|
|
69
|
+
}
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
return this.init();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @override
|
|
77
|
+
*/
|
|
78
|
+
destroyed(): void {
|
|
79
|
+
this.unsubscribe?.();
|
|
80
|
+
this.unsubscribe = null;
|
|
81
|
+
|
|
82
|
+
this.store.reset();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @override
|
|
87
|
+
*/
|
|
88
|
+
updated(): void {}
|
|
89
|
+
|
|
90
|
+
async search(
|
|
91
|
+
params: Partial<ResourceQuery & { locale: LocaleType }>
|
|
92
|
+
): Promise<PaginationInterface<IdentifierRecord>> {
|
|
93
|
+
this.store.changeListState(
|
|
94
|
+
new RequestState(true, this.store.state.listState.result)
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const locale = params.locale!;
|
|
98
|
+
|
|
99
|
+
const response = await fetch(
|
|
100
|
+
`${routerPrefix}/locales/${locale}/common.json`
|
|
101
|
+
);
|
|
102
|
+
const data = await response.json();
|
|
103
|
+
|
|
104
|
+
let index = 0;
|
|
105
|
+
const resultList: IdentifierRecord[] = Object.entries(data).map(
|
|
106
|
+
([key, value]) => ({
|
|
107
|
+
index: (index += 1),
|
|
108
|
+
id: key,
|
|
109
|
+
locale: locale,
|
|
110
|
+
localeValue: value as string
|
|
111
|
+
})
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
const result: PaginationInterface<IdentifierRecord> = {
|
|
115
|
+
list: resultList,
|
|
116
|
+
total: resultList.length,
|
|
117
|
+
page: 1,
|
|
118
|
+
pageSize: 10
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
this.store.changeListState(new RequestState(false, result).end());
|
|
122
|
+
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
refresh(): Promise<unknown> {
|
|
127
|
+
return this.search(this.store.state.searchParams);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async update(_data: Partial<T>): Promise<unknown> {
|
|
131
|
+
return Promise.resolve(null);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
create(_data: T): Promise<unknown> {
|
|
135
|
+
return Promise.resolve(null);
|
|
136
|
+
}
|
|
137
|
+
remove(_data: T): Promise<unknown> {
|
|
138
|
+
return Promise.resolve(null);
|
|
139
|
+
}
|
|
140
|
+
export(_data: T): Promise<unknown> {
|
|
141
|
+
return Promise.resolve(null);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
+
import { IOCIdentifier } from '@config/IOCIdentifier';
|
|
1
2
|
import {
|
|
2
3
|
AsyncExecutor,
|
|
3
4
|
ExecutorContext,
|
|
4
5
|
ExecutorPlugin
|
|
5
6
|
} from '@qlover/fe-corekit';
|
|
6
|
-
import { IOCIdentifier } from '@config/IOCIdentifier';
|
|
7
7
|
import { injectable, inject } from 'inversify';
|
|
8
|
-
import type { LoggerInterface } from '@qlover/logger';
|
|
9
8
|
import type { ProcesserExecutorInterface } from '../port/ProcesserExecutorInterface';
|
|
10
|
-
import type { BootstrapContextValue } from '@qlover/corekit-bridge';
|
|
11
9
|
import type { RouteServiceInterface } from '../port/RouteServiceInterface';
|
|
10
|
+
import type { BootstrapContextValue } from '@qlover/corekit-bridge';
|
|
11
|
+
import type { LoggerInterface } from '@qlover/logger';
|
|
12
12
|
|
|
13
13
|
@injectable()
|
|
14
14
|
export class ProcesserExecutor implements ProcesserExecutorInterface {
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import { i18nConfig } from '@config/i18n/i18nConfig';
|
|
1
2
|
import type { RouteConfigValue } from '@/base/cases/RouterLoader';
|
|
2
|
-
import type { NavigateFunction, NavigateOptions } from 'react-router-dom';
|
|
3
|
-
import type { LoggerInterface } from '@qlover/logger';
|
|
4
3
|
import { RouteServiceInterface } from '../port/RouteServiceInterface';
|
|
4
|
+
import type { I18nServiceInterface } from '../port/I18nServiceInterface';
|
|
5
5
|
import type {
|
|
6
6
|
UIBridgeInterface,
|
|
7
7
|
StoreStateInterface
|
|
8
8
|
} from '@qlover/corekit-bridge';
|
|
9
|
-
import {
|
|
9
|
+
import type { LoggerInterface } from '@qlover/logger';
|
|
10
|
+
import type { NavigateFunction, NavigateOptions } from 'react-router-dom';
|
|
10
11
|
|
|
11
12
|
export type RouterServiceOptions = {
|
|
13
|
+
routerPrefix: string;
|
|
12
14
|
routes: RouteConfigValue[];
|
|
13
15
|
/**
|
|
14
16
|
* Whether to use locale routes
|
|
@@ -82,15 +84,32 @@ export class RouteService extends RouteServiceInterface {
|
|
|
82
84
|
this.goto('/', { replace: true, navigate });
|
|
83
85
|
}
|
|
84
86
|
|
|
85
|
-
override i18nGuard(
|
|
87
|
+
override i18nGuard(
|
|
88
|
+
currentPath: string,
|
|
89
|
+
lng: string,
|
|
90
|
+
navigate?: NavigateFunction
|
|
91
|
+
): void {
|
|
92
|
+
// 只在使用本地化路由时才检查
|
|
86
93
|
if (!this.state.localeRoutes) {
|
|
87
94
|
return;
|
|
88
95
|
}
|
|
89
96
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
97
|
+
const _navigate = navigate || this.uiBridge.getUIBridge();
|
|
98
|
+
|
|
99
|
+
lng = lng || i18nConfig.fallbackLng;
|
|
100
|
+
|
|
101
|
+
// 如果没有语言参数或语言无效
|
|
102
|
+
if (!this.i18nService.isValidLanguage(lng)) {
|
|
103
|
+
// 重定向到默认语言?
|
|
104
|
+
if (i18nConfig.noValidRedirectFallbackLng) {
|
|
105
|
+
const newPath = currentPath.replace(lng, i18nConfig.fallbackLng);
|
|
106
|
+
|
|
107
|
+
_navigate?.(newPath, { replace: true });
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// 不支持的语言直接404
|
|
112
|
+
_navigate?.('/404', { replace: true });
|
|
94
113
|
}
|
|
95
114
|
}
|
|
96
115
|
}
|