create-react-admin-template 0.0.0-stage → 0.1.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/README.md +46 -2
- package/bin/create.mjs +5 -0
- package/package.json +22 -4
- package/template/.dockerignore +12 -0
- package/template/.editorconfig +12 -0
- package/template/.env +14 -0
- package/template/.env.development +5 -0
- package/template/.env.production +2 -0
- package/template/.env.test +5 -0
- package/template/.github/workflows/ci.yml +40 -0
- package/template/.gitlab-ci.yml +208 -0
- package/template/.husky/commit-msg +1 -0
- package/template/.husky/pre-commit +1 -0
- package/template/.nvmrc +1 -0
- package/template/.prettierignore +11 -0
- package/template/.prettierrc +47 -0
- package/template/Dockerfile +16 -0
- package/template/README.md +372 -0
- package/template/build/advancedTable.ts +103 -0
- package/template/build/environment.ts +150 -0
- package/template/commitlint.config.js +32 -0
- package/template/components.json +21 -0
- package/template/deploy/README.md +132 -0
- package/template/deploy/host-nginx/react-admin-api.conf +14 -0
- package/template/deploy/host-nginx/react-admin-web.conf +8 -0
- package/template/deploy/nginx.conf +38 -0
- package/template/docs/activity-status.md +217 -0
- package/template/docs/audit-logs.md +158 -0
- package/template/docs/authentication-adapters.md +219 -0
- package/template/docs/browser-security.md +58 -0
- package/template/docs/bundle-budgets.md +65 -0
- package/template/docs/component-source-governance.md +99 -0
- package/template/docs/data-masking.md +169 -0
- package/template/docs/enterprise-scaffold.md +208 -0
- package/template/docs/feature-data-template.md +227 -0
- package/template/docs/feature-flags.md +169 -0
- package/template/docs/file-capabilities.md +196 -0
- package/template/docs/locale-and-i18n.md +132 -0
- package/template/docs/mutation-idempotency.md +24 -0
- package/template/docs/optional-editors.md +203 -0
- package/template/docs/page-feedback.md +83 -0
- package/template/docs/query-data-conventions.md +178 -0
- package/template/docs/realtime-collaboration.md +140 -0
- package/template/docs/reporting-printing-templates.md +156 -0
- package/template/docs/scaffold-capability-roadmap.md +226 -0
- package/template/docs/scaffold-guide.md +443 -0
- package/template/docs/template-changelog.md +30 -0
- package/template/docs/template-versioning.md +26 -0
- package/template/docs/tenant-workspace-context.md +147 -0
- package/template/docs/unsaved-changes.md +58 -0
- package/template/docs/white-label.md +102 -0
- package/template/eslint.config.js +697 -0
- package/template/gitignore +39 -0
- package/template/index.html +26 -0
- package/template/knip.config.ts +42 -0
- package/template/lint-staged.config.js +8 -0
- package/template/package.json +133 -0
- package/template/pnpm-lock.yaml +8694 -0
- package/template/public/favicon.ico +0 -0
- package/template/public/logo.svg +1 -0
- package/template/public/runtime-config.json +49 -0
- package/template/scaffold.template.json +5 -0
- package/template/src/Application.tsx +114 -0
- package/template/src/api/ApiError.ts +33 -0
- package/template/src/api/activity/ActivityProvider.tsx +167 -0
- package/template/src/api/activity/access.ts +13 -0
- package/template/src/api/activity/errors.ts +17 -0
- package/template/src/api/activity/index.ts +67 -0
- package/template/src/api/activity/model.ts +227 -0
- package/template/src/api/activity/query.ts +163 -0
- package/template/src/api/activity/source.ts +16 -0
- package/template/src/api/activity/subscription.ts +292 -0
- package/template/src/api/activity/transports.ts +271 -0
- package/template/src/api/activity/types.ts +402 -0
- package/template/src/api/authClient.ts +134 -0
- package/template/src/api/authSession.ts +307 -0
- package/template/src/api/clients/configureApiClient.ts +62 -0
- package/template/src/api/clients/httpStatus.ts +4 -0
- package/template/src/api/config/services.json +7 -0
- package/template/src/api/demoAuthClient.ts +46 -0
- package/template/src/api/enums/EnumCatalogProvider.tsx +169 -0
- package/template/src/api/enums/EnumDictionary.ts +55 -0
- package/template/src/api/enums/access.ts +130 -0
- package/template/src/api/enums/catalog.ts +216 -0
- package/template/src/api/enums/errors.ts +21 -0
- package/template/src/api/enums/index.ts +48 -0
- package/template/src/api/enums/query.ts +82 -0
- package/template/src/api/enums/scope.ts +58 -0
- package/template/src/api/enums/types.ts +251 -0
- package/template/src/api/hooks/error.ts +198 -0
- package/template/src/api/hooks/index.ts +4 -0
- package/template/src/api/hooks/request.ts +99 -0
- package/template/src/api/hooks/requestId.ts +65 -0
- package/template/src/api/hooks/response.ts +22 -0
- package/template/src/api/hooks/types.ts +20 -0
- package/template/src/api/idempotency/index.ts +1 -0
- package/template/src/api/idempotency/key.ts +23 -0
- package/template/src/api/index.ts +14 -0
- package/template/src/api/metadata/MetadataProvider.tsx +37 -0
- package/template/src/api/metadata/index.ts +2 -0
- package/template/src/api/metadata/types.ts +30 -0
- package/template/src/api/parameters/GlobalParameterProvider.tsx +210 -0
- package/template/src/api/parameters/access.ts +117 -0
- package/template/src/api/parameters/catalog.ts +170 -0
- package/template/src/api/parameters/errors.ts +21 -0
- package/template/src/api/parameters/index.ts +53 -0
- package/template/src/api/parameters/query.ts +84 -0
- package/template/src/api/parameters/scope.ts +58 -0
- package/template/src/api/parameters/types.ts +214 -0
- package/template/src/api/query/index.ts +13 -0
- package/template/src/api/query/keys.ts +155 -0
- package/template/src/api/query/mutation.ts +48 -0
- package/template/src/api/query/react.ts +36 -0
- package/template/src/api/query/scope.ts +38 -0
- package/template/src/api/query/types.ts +147 -0
- package/template/src/api/types.ts +144 -0
- package/template/src/application/types.ts +52 -0
- package/template/src/auditLogs/errors.ts +17 -0
- package/template/src/auditLogs/export.ts +85 -0
- package/template/src/auditLogs/index.ts +54 -0
- package/template/src/auditLogs/model.ts +526 -0
- package/template/src/auditLogs/query.ts +113 -0
- package/template/src/auditLogs/react.ts +36 -0
- package/template/src/auditLogs/source.ts +51 -0
- package/template/src/auditLogs/types.ts +357 -0
- package/template/src/authentication/controller.ts +351 -0
- package/template/src/authentication/index.ts +8 -0
- package/template/src/authentication/redirect.ts +72 -0
- package/template/src/authentication/types.ts +300 -0
- package/template/src/bootstrap.tsx +96 -0
- package/template/src/components/AppDataTable/AppDataTable.tsx +74 -0
- package/template/src/components/AppDataTable/index.ts +2 -0
- package/template/src/components/AppDataTable/types.ts +27 -0
- package/template/src/components/AppDialog/AppConfirmDialog.tsx +44 -0
- package/template/src/components/AppDialog/AppDialog.tsx +113 -0
- package/template/src/components/AppDialog/index.ts +3 -0
- package/template/src/components/AppDialog/messages.tsx +22 -0
- package/template/src/components/AppDialog/types.ts +53 -0
- package/template/src/components/AppPageForm/AppPageForm.tsx +21 -0
- package/template/src/components/AppPageForm/PageForm.tsx +765 -0
- package/template/src/components/AppPageForm/SOURCE.md +26 -0
- package/template/src/components/AppPageForm/config.ts +253 -0
- package/template/src/components/AppPageForm/controller.ts +580 -0
- package/template/src/components/AppPageForm/index.ts +2 -0
- package/template/src/components/AppPageForm/messages.ts +90 -0
- package/template/src/components/AppPageForm/optionUtils.ts +91 -0
- package/template/src/components/AppPageForm/options.ts +397 -0
- package/template/src/components/AppPageForm/query.ts +44 -0
- package/template/src/components/AppPageForm/style.css +119 -0
- package/template/src/components/AppPageForm/types.ts +632 -0
- package/template/src/components/AppPageForm/validation.ts +233 -0
- package/template/src/components/AppTable/AppTable.tsx +26 -0
- package/template/src/components/AppTable/SOURCE.md +72 -0
- package/template/src/components/AppTable/cell/customCell/TableCellLayer.tsx +73 -0
- package/template/src/components/AppTable/cell/customCell/actions/ActionDropdownCell.tsx +104 -0
- package/template/src/components/AppTable/cell/customCell/cellLayer.ts +358 -0
- package/template/src/components/AppTable/cell/customCell/componentProps.ts +30 -0
- package/template/src/components/AppTable/cell/customCell/date/TemporalPickerEditor.tsx +54 -0
- package/template/src/components/AppTable/cell/customCell/index.ts +2 -0
- package/template/src/components/AppTable/cell/customCell/select/SelectCellEditor.tsx +225 -0
- package/template/src/components/AppTable/cell/customCell/tableCellLayer.css +20 -0
- package/template/src/components/AppTable/cell/customCell/tooltip/TooltipCell.tsx +45 -0
- package/template/src/components/AppTable/cell/customCell/types.ts +63 -0
- package/template/src/components/AppTable/cell/customCell/useCellLayerLifecycle.ts +111 -0
- package/template/src/components/AppTable/cell/frameworkCell/TableCellComponentLayer.tsx +40 -0
- package/template/src/components/AppTable/cell/frameworkCell/cellComponentSession.ts +203 -0
- package/template/src/components/AppTable/cell/frameworkCell/index.ts +3 -0
- package/template/src/components/AppTable/cell/index.ts +2 -0
- package/template/src/components/AppTable/columns/TableColumnEditor.tsx +257 -0
- package/template/src/components/AppTable/columns/index.ts +1 -0
- package/template/src/components/AppTable/columns/useTableColumnPreferenceActions.ts +85 -0
- package/template/src/components/AppTable/config/defaults.ts +46 -0
- package/template/src/components/AppTable/config/index.ts +2 -0
- package/template/src/components/AppTable/config/license.ts +39 -0
- package/template/src/components/AppTable/config/resolver.ts +25 -0
- package/template/src/components/AppTable/config/types.ts +377 -0
- package/template/src/components/AppTable/engine/bottom/index.ts +1 -0
- package/template/src/components/AppTable/engine/bottom/types.ts +14 -0
- package/template/src/components/AppTable/engine/cell/constants.ts +32 -0
- package/template/src/components/AppTable/engine/cell/customCell/actions/index.ts +1 -0
- package/template/src/components/AppTable/engine/cell/customCell/actions/renderer.ts +162 -0
- package/template/src/components/AppTable/engine/cell/customCell/date/index.ts +1 -0
- package/template/src/components/AppTable/engine/cell/customCell/date/renderer.ts +116 -0
- package/template/src/components/AppTable/engine/cell/customCell/editors/editorBounds.ts +57 -0
- package/template/src/components/AppTable/engine/cell/customCell/editors/editorTrigger.ts +46 -0
- package/template/src/components/AppTable/engine/cell/customCell/editors/index.ts +3 -0
- package/template/src/components/AppTable/engine/cell/customCell/editors/layerEditor.ts +244 -0
- package/template/src/components/AppTable/engine/cell/customCell/index.ts +7 -0
- package/template/src/components/AppTable/engine/cell/customCell/renderers/columnRenderer.ts +245 -0
- package/template/src/components/AppTable/engine/cell/customCell/renderers/confirmInput.ts +57 -0
- package/template/src/components/AppTable/engine/cell/customCell/renderers/display.ts +78 -0
- package/template/src/components/AppTable/engine/cell/customCell/renderers/index.ts +3 -0
- package/template/src/components/AppTable/engine/cell/customCell/renderers/itemList.ts +60 -0
- package/template/src/components/AppTable/engine/cell/customCell/renderers/links.ts +131 -0
- package/template/src/components/AppTable/engine/cell/customCell/renderers/selection.ts +41 -0
- package/template/src/components/AppTable/engine/cell/customCell/renderers/shared.ts +71 -0
- package/template/src/components/AppTable/engine/cell/customCell/renderers/step.ts +37 -0
- package/template/src/components/AppTable/engine/cell/customCell/renderers/switch.ts +45 -0
- package/template/src/components/AppTable/engine/cell/customCell/select/index.ts +1 -0
- package/template/src/components/AppTable/engine/cell/customCell/select/renderer.ts +33 -0
- package/template/src/components/AppTable/engine/cell/customCell/tooltip/index.ts +1 -0
- package/template/src/components/AppTable/engine/cell/customCell/tooltip/tooltip.ts +94 -0
- package/template/src/components/AppTable/engine/cell/customCell/types.ts +82 -0
- package/template/src/components/AppTable/engine/cell/formatting.ts +355 -0
- package/template/src/components/AppTable/engine/cell/formula.ts +145 -0
- package/template/src/components/AppTable/engine/cell/index.ts +7 -0
- package/template/src/components/AppTable/engine/cell/multiSelect.ts +96 -0
- package/template/src/components/AppTable/engine/cell/options.ts +339 -0
- package/template/src/components/AppTable/engine/cell/types.ts +53 -0
- package/template/src/components/AppTable/engine/columns/column.ts +430 -0
- package/template/src/components/AppTable/engine/columns/config/columns.ts +33 -0
- package/template/src/components/AppTable/engine/columns/config/index.ts +4 -0
- package/template/src/components/AppTable/engine/columns/config/mutation.ts +138 -0
- package/template/src/components/AppTable/engine/columns/config/temporal.ts +11 -0
- package/template/src/components/AppTable/engine/columns/config/validation.ts +106 -0
- package/template/src/components/AppTable/engine/columns/constants.ts +6 -0
- package/template/src/components/AppTable/engine/columns/gridColumns.ts +332 -0
- package/template/src/components/AppTable/engine/columns/index.ts +4 -0
- package/template/src/components/AppTable/engine/columns/rendererPolicies.ts +129 -0
- package/template/src/components/AppTable/engine/component/resolver.ts +272 -0
- package/template/src/components/AppTable/engine/component/types.ts +384 -0
- package/template/src/components/AppTable/engine/config/constants.ts +33 -0
- package/template/src/components/AppTable/engine/config/grid/compiler.ts +65 -0
- package/template/src/components/AppTable/engine/config/grid/defaults.ts +82 -0
- package/template/src/components/AppTable/engine/config/grid/ownership.ts +35 -0
- package/template/src/components/AppTable/engine/config/grid/runtimeDelta.ts +34 -0
- package/template/src/components/AppTable/engine/config/grid/types.ts +30 -0
- package/template/src/components/AppTable/engine/pagination/config.ts +75 -0
- package/template/src/components/AppTable/engine/pagination/constants.ts +5 -0
- package/template/src/components/AppTable/engine/pagination/index.ts +3 -0
- package/template/src/components/AppTable/engine/pagination/types.ts +70 -0
- package/template/src/components/AppTable/engine/preference/index.ts +2 -0
- package/template/src/components/AppTable/engine/preference/preference.ts +535 -0
- package/template/src/components/AppTable/engine/preference/types.ts +28 -0
- package/template/src/components/AppTable/engine/right/index.ts +1 -0
- package/template/src/components/AppTable/engine/right/types.ts +18 -0
- package/template/src/components/AppTable/engine/search/config.ts +64 -0
- package/template/src/components/AppTable/engine/search/constants.ts +8 -0
- package/template/src/components/AppTable/engine/search/index.ts +7 -0
- package/template/src/components/AppTable/engine/search/localQuery.ts +145 -0
- package/template/src/components/AppTable/engine/search/query.ts +203 -0
- package/template/src/components/AppTable/engine/search/remoteQuery.ts +99 -0
- package/template/src/components/AppTable/engine/search/searchInteraction.ts +46 -0
- package/template/src/components/AppTable/engine/search/types.ts +155 -0
- package/template/src/components/AppTable/engine/selection/config.ts +13 -0
- package/template/src/components/AppTable/engine/selection/index.ts +4 -0
- package/template/src/components/AppTable/engine/selection/selection.ts +357 -0
- package/template/src/components/AppTable/engine/selection/selectionHeader.ts +88 -0
- package/template/src/components/AppTable/engine/selection/types.ts +66 -0
- package/template/src/components/AppTable/engine/shared/action.ts +11 -0
- package/template/src/components/AppTable/engine/shared/constants.ts +2 -0
- package/template/src/components/AppTable/engine/shared/decimal.ts +114 -0
- package/template/src/components/AppTable/engine/shared/feedback.ts +62 -0
- package/template/src/components/AppTable/engine/shared/index.ts +13 -0
- package/template/src/components/AppTable/engine/shared/interaction.ts +55 -0
- package/template/src/components/AppTable/engine/shared/messages.ts +161 -0
- package/template/src/components/AppTable/engine/shared/row.ts +32 -0
- package/template/src/components/AppTable/engine/shared/scheduler.ts +17 -0
- package/template/src/components/AppTable/engine/shared/tableKey.ts +31 -0
- package/template/src/components/AppTable/engine/shared/theme.ts +196 -0
- package/template/src/components/AppTable/engine/shared/treeRows.ts +155 -0
- package/template/src/components/AppTable/engine/shared/types.ts +58 -0
- package/template/src/components/AppTable/engine/shared/valueSnapshot.ts +46 -0
- package/template/src/components/AppTable/engine/summary/config/export.ts +117 -0
- package/template/src/components/AppTable/engine/summary/config/index.ts +3 -0
- package/template/src/components/AppTable/engine/summary/config/summary.ts +62 -0
- package/template/src/components/AppTable/engine/summary/config/types.ts +93 -0
- package/template/src/components/AppTable/engine/summary/constants.ts +13 -0
- package/template/src/components/AppTable/engine/summary/excelJs.ts +133 -0
- package/template/src/components/AppTable/engine/summary/export.ts +311 -0
- package/template/src/components/AppTable/engine/summary/index.ts +6 -0
- package/template/src/components/AppTable/engine/summary/selectionSum.ts +92 -0
- package/template/src/components/AppTable/engine/summary/summary.ts +457 -0
- package/template/src/components/AppTable/engine/table/clipboard/index.ts +1 -0
- package/template/src/components/AppTable/engine/table/clipboard/transfer.ts +9 -0
- package/template/src/components/AppTable/engine/table/controller/TableController.ts +802 -0
- package/template/src/components/AppTable/engine/table/controller/errors.ts +106 -0
- package/template/src/components/AppTable/engine/table/controller/index.ts +4 -0
- package/template/src/components/AppTable/engine/table/controller/latestAbortableTask.ts +33 -0
- package/template/src/components/AppTable/engine/table/controller/tableDataReplacement.ts +60 -0
- package/template/src/components/AppTable/engine/table/controller/tableDomainConfiguration.ts +94 -0
- package/template/src/components/AppTable/engine/table/controller/tableEditingCommands.ts +163 -0
- package/template/src/components/AppTable/engine/table/controller/tableGridHost.ts +324 -0
- package/template/src/components/AppTable/engine/table/controller/tableIdentity.ts +68 -0
- package/template/src/components/AppTable/engine/table/controller/tableMutationPipeline.ts +79 -0
- package/template/src/components/AppTable/engine/table/controller/tableQueryCoordinator.ts +187 -0
- package/template/src/components/AppTable/engine/table/controller/tableReportingCoordinator.ts +143 -0
- package/template/src/components/AppTable/engine/table/controller/tableSaveCoordinator.ts +227 -0
- package/template/src/components/AppTable/engine/table/controller/tableSaveValidation.ts +29 -0
- package/template/src/components/AppTable/engine/table/controller/tableSnapshot.ts +58 -0
- package/template/src/components/AppTable/engine/table/controller/types.ts +202 -0
- package/template/src/components/AppTable/engine/table/editing/baselineStore.ts +134 -0
- package/template/src/components/AppTable/engine/table/editing/changeSet.ts +492 -0
- package/template/src/components/AppTable/engine/table/editing/changeSetSettlement.ts +633 -0
- package/template/src/components/AppTable/engine/table/editing/commitResultIndex.ts +75 -0
- package/template/src/components/AppTable/engine/table/editing/constants.ts +15 -0
- package/template/src/components/AppTable/engine/table/editing/dirtyCellIndex.ts +96 -0
- package/template/src/components/AppTable/engine/table/editing/index.ts +6 -0
- package/template/src/components/AppTable/engine/table/editing/mutation.ts +173 -0
- package/template/src/components/AppTable/engine/table/editing/rowKey.ts +10 -0
- package/template/src/components/AppTable/engine/table/editing/types.ts +404 -0
- package/template/src/components/AppTable/engine/table/editing/validation.ts +452 -0
- package/template/src/components/AppTable/engine/table/grid/cellMeta.ts +90 -0
- package/template/src/components/AppTable/engine/table/grid/handsontable.ts +25 -0
- package/template/src/components/AppTable/engine/table/grid/handsontableExtensions.d.ts +26 -0
- package/template/src/components/AppTable/engine/table/grid/index.ts +5 -0
- package/template/src/components/AppTable/engine/table/grid/moduleRegistry.ts +39 -0
- package/template/src/components/AppTable/engine/table/grid/runtime.ts +31 -0
- package/template/src/components/AppTable/engine/table/grid/types.ts +25 -0
- package/template/src/components/AppTable/engine/table/hooks/fixedEndHooks.ts +44 -0
- package/template/src/components/AppTable/engine/table/hooks/gridHooks.ts +108 -0
- package/template/src/components/AppTable/engine/table/hooks/headerHooks.ts +103 -0
- package/template/src/components/AppTable/engine/table/hooks/index.ts +3 -0
- package/template/src/components/AppTable/engine/table/index.ts +6 -0
- package/template/src/components/AppTable/engine/table/layout/constants.ts +2 -0
- package/template/src/components/AppTable/engine/table/layout/dropdownMenu.ts +89 -0
- package/template/src/components/AppTable/engine/table/layout/fixedColumns.ts +44 -0
- package/template/src/components/AppTable/engine/table/layout/fixedEndOverlay.ts +90 -0
- package/template/src/components/AppTable/engine/table/layout/fixedEndOverlayAccessibility.ts +104 -0
- package/template/src/components/AppTable/engine/table/layout/fixedEndOverlayRenderer.ts +690 -0
- package/template/src/components/AppTable/engine/table/layout/fixedEndOverlaySignature.ts +58 -0
- package/template/src/components/AppTable/engine/table/layout/fixedEndRuntime.ts +137 -0
- package/template/src/components/AppTable/engine/table/layout/handsontableDomAdapter.ts +40 -0
- package/template/src/components/AppTable/engine/table/layout/height.ts +72 -0
- package/template/src/components/AppTable/engine/table/layout/index.ts +14 -0
- package/template/src/components/AppTable/engine/table/layout/layoutScheduler.ts +60 -0
- package/template/src/components/AppTable/engine/table/layout/mergeCells.ts +146 -0
- package/template/src/components/AppTable/engine/table/layout/nestedHeaders.ts +271 -0
- package/template/src/components/AppTable/engine/table/layout/types.ts +10 -0
- package/template/src/components/AppTable/engine/toolbar/index.ts +1 -0
- package/template/src/components/AppTable/engine/toolbar/types.ts +56 -0
- package/template/src/components/AppTable/index.ts +11 -0
- package/template/src/components/AppTable/messages.ts +256 -0
- package/template/src/components/AppTable/pagination/TablePaginationBar.tsx +193 -0
- package/template/src/components/AppTable/pagination/index.ts +1 -0
- package/template/src/components/AppTable/pagination/paginationItems.ts +56 -0
- package/template/src/components/AppTable/preference/index.ts +1 -0
- package/template/src/components/AppTable/preference/useTablePreference.ts +208 -0
- package/template/src/components/AppTable/reporting/index.ts +1 -0
- package/template/src/components/AppTable/reporting/useTableReporting.ts +342 -0
- package/template/src/components/AppTable/search/TableSearchBar.tsx +301 -0
- package/template/src/components/AppTable/search/TableSearchConditionEditor.tsx +254 -0
- package/template/src/components/AppTable/search/TableSearchField.tsx +338 -0
- package/template/src/components/AppTable/search/TableSearchFields.tsx +65 -0
- package/template/src/components/AppTable/search/constants.ts +9 -0
- package/template/src/components/AppTable/search/index.ts +3 -0
- package/template/src/components/AppTable/search/tableSearchBar.css +164 -0
- package/template/src/components/AppTable/search/types.ts +7 -0
- package/template/src/components/AppTable/search/useTableQuery.ts +373 -0
- package/template/src/components/AppTable/selection/index.ts +1 -0
- package/template/src/components/AppTable/selection/useTableSelection.ts +188 -0
- package/template/src/components/AppTable/sensitiveData.tsx +41 -0
- package/template/src/components/AppTable/shared/styles.ts +2 -0
- package/template/src/components/AppTable/styles/index.css +6 -0
- package/template/src/components/AppTable/styles/tableComponent.css +297 -0
- package/template/src/components/AppTable/styles/theme.css +133 -0
- package/template/src/components/AppTable/table/components/TableComponent.tsx +567 -0
- package/template/src/components/AppTable/table/components/TableErrorFeedback.tsx +36 -0
- package/template/src/components/AppTable/table/components/TableGridViewport.tsx +85 -0
- package/template/src/components/AppTable/table/components/index.ts +2 -0
- package/template/src/components/AppTable/table/components/types.ts +90 -0
- package/template/src/components/AppTable/table/controller/configuration.ts +89 -0
- package/template/src/components/AppTable/table/controller/index.ts +2 -0
- package/template/src/components/AppTable/table/controller/useTableController.ts +155 -0
- package/template/src/components/AppTable/table/controller/useTableLifecycle.ts +97 -0
- package/template/src/components/AppTable/table/grid/index.ts +1 -0
- package/template/src/components/AppTable/table/grid/useTableGrid.ts +857 -0
- package/template/src/components/AppTable/table/grid/useTableGridRuntimeSettings.ts +49 -0
- package/template/src/components/AppTable/table/index.ts +4 -0
- package/template/src/components/AppTable/table/layout/TablePanels.tsx +389 -0
- package/template/src/components/AppTable/table/layout/index.ts +7 -0
- package/template/src/components/AppTable/table/layout/types.ts +3 -0
- package/template/src/components/AppTable/table/layout/useResizablePanel.ts +213 -0
- package/template/src/components/AppTable/table/layout/useTableAdaptiveHeight.ts +238 -0
- package/template/src/components/AppTable/table/layout/useTablePanels.ts +329 -0
- package/template/src/components/AppTable/table/layout/useTableTheme.ts +123 -0
- package/template/src/components/AppTable/toolbar/TableToolbar.tsx +336 -0
- package/template/src/components/AppTable/toolbar/index.ts +1 -0
- package/template/src/components/BrandLogo/BrandLogo.tsx +41 -0
- package/template/src/components/BrandLogo/index.ts +1 -0
- package/template/src/components/Can/Can.tsx +19 -0
- package/template/src/components/Can/index.ts +7 -0
- package/template/src/components/Can/types.ts +41 -0
- package/template/src/components/EnumBadge/EnumBadge.tsx +44 -0
- package/template/src/components/EnumBadge/index.ts +2 -0
- package/template/src/components/EnumBadge/types.ts +16 -0
- package/template/src/components/EnumText/EnumText.tsx +33 -0
- package/template/src/components/EnumText/index.ts +2 -0
- package/template/src/components/EnumText/types.ts +13 -0
- package/template/src/components/FilePreview/FilePreview.tsx +120 -0
- package/template/src/components/FilePreview/index.ts +11 -0
- package/template/src/components/FilePreview/preview.ts +88 -0
- package/template/src/components/FilePreview/types.ts +91 -0
- package/template/src/components/FileUpload/FileUpload.tsx +172 -0
- package/template/src/components/FileUpload/index.ts +2 -0
- package/template/src/components/FileUpload/types.ts +32 -0
- package/template/src/components/JsonEditor/JsonEditor.tsx +103 -0
- package/template/src/components/JsonEditor/index.ts +1 -0
- package/template/src/components/JsonEditor/types.ts +14 -0
- package/template/src/components/PageFeedback/PageFeedback.tsx +194 -0
- package/template/src/components/PageFeedback/index.ts +10 -0
- package/template/src/components/PageFeedback/types.ts +31 -0
- package/template/src/components/PasswordInput/PasswordInput.tsx +50 -0
- package/template/src/components/PasswordInput/index.ts +1 -0
- package/template/src/components/RouteDialog/RouteDialog.tsx +20 -0
- package/template/src/components/RouteDialog/index.ts +2 -0
- package/template/src/components/RouteDialog/types.ts +8 -0
- package/template/src/components/RouteDialog/useRouteDialogNavigation.ts +30 -0
- package/template/src/components/SensitiveData/SensitiveData.tsx +337 -0
- package/template/src/components/SensitiveData/index.ts +2 -0
- package/template/src/components/SensitiveData/types.ts +31 -0
- package/template/src/components/StatusBadge/StatusBadge.tsx +28 -0
- package/template/src/components/StatusBadge/index.ts +2 -0
- package/template/src/components/StatusBadge/statusBadgeStyles.ts +30 -0
- package/template/src/components/StatusBadge/types.ts +7 -0
- package/template/src/components/layout/AppHeader/AppHeader.tsx +57 -0
- package/template/src/components/layout/AppHeader/HeaderSearch.tsx +160 -0
- package/template/src/components/layout/AppHeader/HeaderUserMenu.tsx +59 -0
- package/template/src/components/layout/AppHeader/ThemeControls.tsx +44 -0
- package/template/src/components/layout/AppHeader/index.ts +1 -0
- package/template/src/components/layout/AppHeader/themeOptions.ts +13 -0
- package/template/src/components/layout/AppSidebar.tsx +268 -0
- package/template/src/components/layout/PageContainer.tsx +16 -0
- package/template/src/components/ui/avatar.tsx +108 -0
- package/template/src/components/ui/badge.tsx +47 -0
- package/template/src/components/ui/button.tsx +63 -0
- package/template/src/components/ui/card.tsx +60 -0
- package/template/src/components/ui/checkbox.tsx +31 -0
- package/template/src/components/ui/collapsible.tsx +33 -0
- package/template/src/components/ui/command.tsx +181 -0
- package/template/src/components/ui/dialog.tsx +157 -0
- package/template/src/components/ui/dropdown-menu.tsx +254 -0
- package/template/src/components/ui/form.tsx +141 -0
- package/template/src/components/ui/input.tsx +20 -0
- package/template/src/components/ui/label.tsx +23 -0
- package/template/src/components/ui/pagination.tsx +127 -0
- package/template/src/components/ui/popover.tsx +41 -0
- package/template/src/components/ui/select.tsx +187 -0
- package/template/src/components/ui/separator.tsx +25 -0
- package/template/src/components/ui/sheet.tsx +142 -0
- package/template/src/components/ui/sidebar.tsx +878 -0
- package/template/src/components/ui/skeleton.tsx +13 -0
- package/template/src/components/ui/sonner.tsx +33 -0
- package/template/src/components/ui/tooltip.tsx +54 -0
- package/template/src/config/RuntimeConfigErrorPage.tsx +48 -0
- package/template/src/config/appConfig.ts +126 -0
- package/template/src/config/buildInfo.ts +8 -0
- package/template/src/config/observabilityAdapter.ts +8 -0
- package/template/src/config/runtimeConfig.ts +360 -0
- package/template/src/config/types.ts +195 -0
- package/template/src/context/ThemeProvider.tsx +84 -0
- package/template/src/context/UnsavedChangesProvider.tsx +123 -0
- package/template/src/context/applicationScope.ts +39 -0
- package/template/src/context/types.ts +41 -0
- package/template/src/dataMasking/index.ts +14 -0
- package/template/src/dataMasking/masking.ts +139 -0
- package/template/src/dataMasking/types.ts +144 -0
- package/template/src/featureFlags/FeatureFlagProvider.tsx +143 -0
- package/template/src/featureFlags/FeatureGate.tsx +12 -0
- package/template/src/featureFlags/catalog.ts +140 -0
- package/template/src/featureFlags/errors.ts +17 -0
- package/template/src/featureFlags/index.ts +43 -0
- package/template/src/featureFlags/query.ts +103 -0
- package/template/src/featureFlags/registry.ts +149 -0
- package/template/src/featureFlags/scope.ts +27 -0
- package/template/src/featureFlags/types.ts +241 -0
- package/template/src/features/auth/AuthLayout.tsx +17 -0
- package/template/src/features/auth/index.ts +2 -0
- package/template/src/features/auth/signIn/components/UserAuthForm.tsx +121 -0
- package/template/src/features/auth/signIn/index.tsx +71 -0
- package/template/src/features/auth/signIn/messages.ts +37 -0
- package/template/src/features/auth/signIn/types.ts +4 -0
- package/template/src/features/errors/ForbiddenError.tsx +34 -0
- package/template/src/features/errors/GeneralError.tsx +46 -0
- package/template/src/features/errors/MaintenanceError.tsx +31 -0
- package/template/src/features/errors/NotFoundError.tsx +34 -0
- package/template/src/features/errors/RouteError.tsx +72 -0
- package/template/src/features/errors/UnauthorizedError.tsx +34 -0
- package/template/src/features/errors/index.ts +6 -0
- package/template/src/features/errors/messages.ts +56 -0
- package/template/src/features/home/index.tsx +107 -0
- package/template/src/features/home/messages.ts +59 -0
- package/template/src/features/showcase/AccessShowcasePage.tsx +284 -0
- package/template/src/features/showcase/AdvancedTableDemo.tsx +120 -0
- package/template/src/features/showcase/FeedbackShowcasePage.tsx +142 -0
- package/template/src/features/showcase/FileShowcasePage.tsx +110 -0
- package/template/src/features/showcase/FormShowcasePage.tsx +156 -0
- package/template/src/features/showcase/MetadataShowcasePage.tsx +241 -0
- package/template/src/features/showcase/ShowcasePageHeader.tsx +24 -0
- package/template/src/features/showcase/TableShowcasePage.tsx +436 -0
- package/template/src/features/showcase/accessMessages.ts +67 -0
- package/template/src/features/showcase/index.ts +6 -0
- package/template/src/features/showcase/messages.ts +192 -0
- package/template/src/files/download.ts +82 -0
- package/template/src/files/errors.ts +15 -0
- package/template/src/files/filename.ts +61 -0
- package/template/src/files/index.ts +38 -0
- package/template/src/files/types.ts +299 -0
- package/template/src/files/useFileTask.ts +153 -0
- package/template/src/files/useFileUpload.ts +117 -0
- package/template/src/files/validation.ts +109 -0
- package/template/src/layouts/AppLayout.tsx +37 -0
- package/template/src/lib/accessControl.ts +42 -0
- package/template/src/lib/navigationRedirect.ts +26 -0
- package/template/src/lib/utils.ts +6 -0
- package/template/src/locale/LocaleProvider.tsx +37 -0
- package/template/src/locale/context.ts +15 -0
- package/template/src/locale/formatters.ts +123 -0
- package/template/src/locale/hooks.ts +35 -0
- package/template/src/locale/index.ts +17 -0
- package/template/src/locale/messages.ts +151 -0
- package/template/src/locale/types.ts +167 -0
- package/template/src/main.tsx +5 -0
- package/template/src/observability/browser.ts +37 -0
- package/template/src/observability/consoleAdapter.ts +18 -0
- package/template/src/observability/index.ts +26 -0
- package/template/src/observability/observer.ts +118 -0
- package/template/src/observability/redaction.ts +85 -0
- package/template/src/observability/types.ts +119 -0
- package/template/src/optionalEditors/controller.ts +327 -0
- package/template/src/optionalEditors/errors.ts +21 -0
- package/template/src/optionalEditors/index.ts +35 -0
- package/template/src/optionalEditors/model.ts +253 -0
- package/template/src/optionalEditors/react.ts +89 -0
- package/template/src/optionalEditors/types.ts +254 -0
- package/template/src/permissions/index.ts +3 -0
- package/template/src/permissions/types.ts +5 -0
- package/template/src/permissions/usePermission.ts +16 -0
- package/template/src/realtimeCollaboration/controller.ts +355 -0
- package/template/src/realtimeCollaboration/errors.ts +20 -0
- package/template/src/realtimeCollaboration/index.ts +39 -0
- package/template/src/realtimeCollaboration/model.ts +212 -0
- package/template/src/realtimeCollaboration/react.ts +72 -0
- package/template/src/realtimeCollaboration/types.ts +251 -0
- package/template/src/reporting/errors.ts +21 -0
- package/template/src/reporting/generation.ts +87 -0
- package/template/src/reporting/index.ts +42 -0
- package/template/src/reporting/model.ts +373 -0
- package/template/src/reporting/print.ts +16 -0
- package/template/src/reporting/query.ts +50 -0
- package/template/src/reporting/react.ts +17 -0
- package/template/src/reporting/source.ts +13 -0
- package/template/src/reporting/types.ts +219 -0
- package/template/src/router/RootRouteLayout.tsx +11 -0
- package/template/src/router/authLifecycle.ts +39 -0
- package/template/src/router/config.ts +293 -0
- package/template/src/router/interceptors.ts +48 -0
- package/template/src/router/lazyRouteComponents.ts +78 -0
- package/template/src/router/messages.ts +48 -0
- package/template/src/router/navigation.ts +167 -0
- package/template/src/router/router.ts +66 -0
- package/template/src/router/searchSchemas.ts +9 -0
- package/template/src/router/types.ts +76 -0
- package/template/src/stores/authSessionStorage.ts +27 -0
- package/template/src/stores/authStore.ts +165 -0
- package/template/src/stores/types.ts +36 -0
- package/template/src/stores/uiPreferenceStore.ts +34 -0
- package/template/src/styles/index.css +141 -0
- package/template/src/styles/theme.css +213 -0
- package/template/src/tenantWorkspace/TenantWorkspaceProvider.tsx +102 -0
- package/template/src/tenantWorkspace/index.ts +33 -0
- package/template/src/tenantWorkspace/store.ts +184 -0
- package/template/src/tenantWorkspace/switch.ts +206 -0
- package/template/src/tenantWorkspace/types.ts +155 -0
- package/template/src/vite-env.d.ts +20 -0
- package/template/stylelint.config.js +28 -0
- package/template/tests/integration/Application.test.tsx +269 -0
- package/template/tests/integration/layout/AppHeader.test.tsx +182 -0
- package/template/tests/integration/layout/AppSidebar.test.tsx +121 -0
- package/template/tests/integration/layout/__screenshots__/AppHeader.test.tsx/AppHeader-command-search-hides-the-duplicate-header-trigger-when-the-desktop-sidebar-collapses-1.png +0 -0
- package/template/tests/integration/router/__screenshots__/config.test.ts/route-tree-authentication-boundaries-exposes-only-scaffold-navigation-metadata-1.png +0 -0
- package/template/tests/integration/router/config.test.ts +123 -0
- package/template/tests/integration/router/interceptors.test.ts +100 -0
- package/template/tests/setup/accessibility.ts +25 -0
- package/template/tests/setup/runtimeConfig.ts +3 -0
- package/template/tests/unit/api/ApiError.test.ts +25 -0
- package/template/tests/unit/api/__screenshots__/authSession.test.ts/administrator-authentication-clears-the-session-if-a-refresh-identity-loses-administrator-access-1.png +0 -0
- package/template/tests/unit/api/__screenshots__/authSession.test.ts/administrator-authentication-creates-a-session-from-the-generated-login-response-for-an-admin-1.png +0 -0
- package/template/tests/unit/api/__screenshots__/authSession.test.ts/administrator-authentication-rejects-and-revokes-the-generated-login-result-for-an-ordinary-user-1.png +0 -0
- package/template/tests/unit/api/activity/ActivityProvider.test.tsx +131 -0
- package/template/tests/unit/api/activity/__screenshots__/transports.test.ts/activity-transport-adapters-polls-sequentially-and-advances-the-last-event-ID-1.png +0 -0
- package/template/tests/unit/api/activity/modelAndQuery.test.ts +144 -0
- package/template/tests/unit/api/activity/subscription.test.ts +103 -0
- package/template/tests/unit/api/activity/transports.test.ts +145 -0
- package/template/tests/unit/api/authClient.test.ts +110 -0
- package/template/tests/unit/api/authSession.test.ts +289 -0
- package/template/tests/unit/api/clients/configureApiClient.test.ts +198 -0
- package/template/tests/unit/api/demoAuthClient.test.ts +47 -0
- package/template/tests/unit/api/enums/access.test.ts +107 -0
- package/template/tests/unit/api/enums/catalog.test.ts +200 -0
- package/template/tests/unit/api/enums/query.test.ts +110 -0
- package/template/tests/unit/api/enums/useEnum.test.tsx +98 -0
- package/template/tests/unit/api/enums/useEnumCatalog.test.tsx +68 -0
- package/template/tests/unit/api/hooks/error.test.ts +168 -0
- package/template/tests/unit/api/hooks/request.test.ts +170 -0
- package/template/tests/unit/api/hooks/response.test.ts +46 -0
- package/template/tests/unit/api/metadata/MetadataProvider.test.tsx +102 -0
- package/template/tests/unit/api/parameters/catalog.test.ts +147 -0
- package/template/tests/unit/api/parameters/query.test.ts +78 -0
- package/template/tests/unit/api/parameters/useGlobalParameter.test.tsx +89 -0
- package/template/tests/unit/api/query/queryPolicy.test.ts +245 -0
- package/template/tests/unit/api/query/useAppQueryScope.test.tsx +74 -0
- package/template/tests/unit/auditLogs/auditLogHooks.test.tsx +194 -0
- package/template/tests/unit/auditLogs/auditLogs.test.ts +199 -0
- package/template/tests/unit/authentication/__screenshots__/authentication.test.ts/authentication-controller-completes-Step-up-callbacks-without-creating-a-second-login-result-1.png +0 -0
- package/template/tests/unit/authentication/__screenshots__/authentication.test.ts/authentication-controller-moves-from-challenge-to-completion-without-retaining-tokens-in-snapshot-1.png +0 -0
- package/template/tests/unit/authentication/authentication.test.ts +376 -0
- package/template/tests/unit/components/AppDialog.test.tsx +225 -0
- package/template/tests/unit/components/AppTable.test.tsx +129 -0
- package/template/tests/unit/components/AppTableLayoutTransition.test.ts +118 -0
- package/template/tests/unit/components/AppTableLocalization.test.ts +58 -0
- package/template/tests/unit/components/AppTableSensitiveData.test.ts +35 -0
- package/template/tests/unit/components/AppTableUpgrade.test.tsx +179 -0
- package/template/tests/unit/components/AppTableUpgradeCore.test.ts +258 -0
- package/template/tests/unit/components/BrandLogo.test.tsx +24 -0
- package/template/tests/unit/components/Can.test.tsx +80 -0
- package/template/tests/unit/components/Dialog.test.tsx +56 -0
- package/template/tests/unit/components/EnumPresentation.test.tsx +64 -0
- package/template/tests/unit/components/FilePreviewEngine.test.ts +51 -0
- package/template/tests/unit/components/JsonEditor.test.tsx +47 -0
- package/template/tests/unit/components/LocalizedSharedComponents.test.tsx +36 -0
- package/template/tests/unit/components/OverlayLayer.test.tsx +151 -0
- package/template/tests/unit/components/PageFeedback.test.tsx +143 -0
- package/template/tests/unit/components/PageForm.test.tsx +272 -0
- package/template/tests/unit/components/PageFormCore.test.ts +74 -0
- package/template/tests/unit/components/PasswordInput.test.tsx +105 -0
- package/template/tests/unit/components/ScaffoldComponents.test.tsx +64 -0
- package/template/tests/unit/components/SensitiveData.test.tsx +151 -0
- package/template/tests/unit/components/StatusBadge.test.tsx +36 -0
- package/template/tests/unit/components/TableComponent.test.tsx +644 -0
- package/template/tests/unit/components/TableCore.test.ts +145 -0
- package/template/tests/unit/components/ThemeAccessibility.test.tsx +27 -0
- package/template/tests/unit/components/__screenshots__/BatchOperationDialog.test.tsx/confirms-a-batch-action-and-presents-partial-failure-details-1.png +0 -0
- package/template/tests/unit/components/__screenshots__/PageForm.test.tsx/PageForm-writes-uploaded-values-through-the-public-file-field-and-resets-dirty-state-1.png +0 -0
- package/template/tests/unit/components/__screenshots__/PasswordInput.test.tsx/PasswordInput-toggles-the-password-visibility-when-the-show-password-button-is-clicked-1.png +0 -0
- package/template/tests/unit/components/__screenshots__/TableComponent.test.tsx/TableComponent-pins-trailing-action-columns-and-removes-their-header-menu-by-default-1.png +0 -0
- package/template/tests/unit/components/__screenshots__/TableComponent.test.tsx/TableComponent-renders-shadcn-components-through-cellComponent-1.png +0 -0
- package/template/tests/unit/components/__screenshots__/TableComponent.test.tsx/TableComponent-renders-the-toolbar-without-a-bottom-divider-1.png +0 -0
- package/template/tests/unit/components/__screenshots__/TableComponent.test.tsx/TableComponent-resyncs-adaptive-height-after-a-column-resize-changes-wrapped-row-height-1.png +0 -0
- package/template/tests/unit/config/RuntimeConfigErrorPage.test.tsx +23 -0
- package/template/tests/unit/config/appConfig.test.ts +98 -0
- package/template/tests/unit/config/appTableContracts.test.mjs +120 -0
- package/template/tests/unit/config/bundleBudget.test.mjs +190 -0
- package/template/tests/unit/config/componentGovernance.test.mjs +156 -0
- package/template/tests/unit/config/deployConfig.test.mjs +211 -0
- package/template/tests/unit/config/eslintConfig.test.mjs +101 -0
- package/template/tests/unit/config/featureBoundaries.test.mjs +126 -0
- package/template/tests/unit/config/npmPackage.test.mjs +37 -0
- package/template/tests/unit/config/releaseArtifact.test.mjs +105 -0
- package/template/tests/unit/config/runtimeConfig.test.ts +225 -0
- package/template/tests/unit/config/scaffoldCheck.test.mjs +53 -0
- package/template/tests/unit/config/scaffoldFeature.test.mjs +177 -0
- package/template/tests/unit/config/scaffoldInit.test.mjs +218 -0
- package/template/tests/unit/config/scaffoldProject.test.mjs +378 -0
- package/template/tests/unit/config/scaffoldTransaction.test.mjs +77 -0
- package/template/tests/unit/config/viteConfig.test.mjs +371 -0
- package/template/tests/unit/context/ThemeProvider.test.tsx +108 -0
- package/template/tests/unit/context/UnsavedChangesProvider.test.tsx +94 -0
- package/template/tests/unit/context/__screenshots__/ThemeProvider.test.tsx/ThemeProvider-uses-the-neutral-black-palette-for-the-app-and-scoped-table-theme-1.png +0 -0
- package/template/tests/unit/context/applicationScope.test.ts +62 -0
- package/template/tests/unit/dataMasking/dataMasking.test.ts +95 -0
- package/template/tests/unit/featureFlags/featureFlags.test.ts +169 -0
- package/template/tests/unit/featureFlags/useFeatureFlag.test.tsx +108 -0
- package/template/tests/unit/features/FeatureLocalization.test.tsx +54 -0
- package/template/tests/unit/features/RouteError.test.tsx +40 -0
- package/template/tests/unit/features/auth/signIn/UserAuthForm.test.tsx +79 -0
- package/template/tests/unit/features/auth/signIn/__screenshots__/UserAuthForm.test.tsx/UserAuthForm-passes-validated-values-to-onSubmit-1.png +0 -0
- package/template/tests/unit/features/auth/signIn/__screenshots__/UserAuthForm.test.tsx/UserAuthForm-shows-validation-messages-when-submitting-an-empty-form-1.png +0 -0
- package/template/tests/unit/files/fileHooks.test.tsx +130 -0
- package/template/tests/unit/files/files.test.ts +112 -0
- package/template/tests/unit/lib/accessControl.test.ts +69 -0
- package/template/tests/unit/locale/locale.test.tsx +90 -0
- package/template/tests/unit/observability/browser.test.ts +48 -0
- package/template/tests/unit/observability/observer.test.ts +115 -0
- package/template/tests/unit/optionalEditors/__screenshots__/useOptionalEditor.test.tsx/useOptionalEditor-fails-permission-precheck-before-loading-the-project-SDK-1.png +0 -0
- package/template/tests/unit/optionalEditors/__screenshots__/useOptionalEditor.test.tsx/useOptionalEditor-mounts-a-route-scoped-SDK-into-the-dedicated-host-with-permission-1.png +0 -0
- package/template/tests/unit/optionalEditors/optionalEditors.test.ts +313 -0
- package/template/tests/unit/optionalEditors/useOptionalEditor.test.tsx +141 -0
- package/template/tests/unit/realtimeCollaboration/collaboration.test.ts +240 -0
- package/template/tests/unit/realtimeCollaboration/useRealtimeCollaboration.test.tsx +115 -0
- package/template/tests/unit/reporting/reporting.test.ts +195 -0
- package/template/tests/unit/reporting/reportingHooks.test.tsx +203 -0
- package/template/tests/unit/router/authLifecycle.test.ts +55 -0
- package/template/tests/unit/router/navigation.test.ts +55 -0
- package/template/tests/unit/router/redirects.test.ts +22 -0
- package/template/tests/unit/scaffoldFeatureTemplate/featureTemplate.test.ts +42 -0
- package/template/tests/unit/scaffoldFeatureTemplate/publicContract.test.ts +28 -0
- package/template/tests/unit/scaffoldFeatureTemplate/queries.test.tsx +289 -0
- package/template/tests/unit/stores/authStore.test.ts +128 -0
- package/template/tests/unit/stores/uiPreferenceStore.test.ts +56 -0
- package/template/tests/unit/tenantWorkspace/tenantWorkspace.test.tsx +261 -0
- package/template/tools/bundle/budgets.json +48 -0
- package/template/tools/bundle/check.mjs +307 -0
- package/template/tools/component-governance/check.mjs +703 -0
- package/template/tools/component-governance/manifest.json +112 -0
- package/template/tools/deployment/browser-smoke.mjs +76 -0
- package/template/tools/deployment/browser-smoke.sh +141 -0
- package/template/tools/openapi/generate.mjs +268 -0
- package/template/tools/openapi/templates/README.md +14 -0
- package/template/tools/openapi/templates/base/README.md +7 -0
- package/template/tools/openapi/templates/base/data-contracts.eta +44 -0
- package/template/tools/openapi/templates/base/http-client.eta +3 -0
- package/template/tools/openapi/templates/base/http-clients/axios-http-client.eta +132 -0
- package/template/tools/openapi/templates/base/http-clients/fetch-http-client.eta +220 -0
- package/template/tools/openapi/templates/base/route-docs.eta +31 -0
- package/template/tools/openapi/templates/base/route-name.eta +43 -0
- package/template/tools/openapi/templates/base/route-type.eta +22 -0
- package/template/tools/openapi/templates/default/README.md +7 -0
- package/template/tools/openapi/templates/default/api.eta +67 -0
- package/template/tools/openapi/templates/default/http-client.eta +137 -0
- package/template/tools/openapi/templates/default/procedure-call.eta +99 -0
- package/template/tools/openapi/templates/default/route-docs.eta +40 -0
- package/template/tools/openapi/templates/default/route-types.eta +28 -0
- package/template/tools/openapi/templates/modular/README.md +7 -0
- package/template/tools/openapi/templates/modular/api.eta +28 -0
- package/template/tools/openapi/templates/modular/procedure-call.eta +99 -0
- package/template/tools/openapi/templates/modular/route-types.eta +18 -0
- package/template/tools/release/artifact.mjs +258 -0
- package/template/tools/scaffold/add-capability.mjs +409 -0
- package/template/tools/scaffold/capability-catalog.json +163 -0
- package/template/tools/scaffold/check.mjs +326 -0
- package/template/tools/scaffold/create-feature.mjs +444 -0
- package/template/tools/scaffold/create-project.mjs +482 -0
- package/template/tools/scaffold/init.example.json +64 -0
- package/template/tools/scaffold/init.mjs +419 -0
- package/template/tools/scaffold/lockfile.mjs +193 -0
- package/template/tools/scaffold/templates/feature/index.ts +19 -0
- package/template/tools/scaffold/templates/feature/model.ts +142 -0
- package/template/tools/scaffold/templates/feature/queries.ts +154 -0
- package/template/tools/scaffold/templates/feature/repository.ts +206 -0
- package/template/tools/scaffold/templates/feature/types.ts +168 -0
- package/template/tools/scaffold/workspace-transaction.mjs +111 -0
- package/template/tsconfig.app.json +31 -0
- package/template/tsconfig.json +12 -0
- package/template/tsconfig.node.json +24 -0
- package/template/vite.config.ts +121 -0
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
# React 管理后台脚手架指南
|
|
2
|
+
|
|
3
|
+
这个仓库提供可直接扩展的管理后台壳层,不附带产品业务域。新项目应在独立 Feature 中
|
|
4
|
+
实现业务,并通过路由公开页面入口,不要把产品规则写入 `components`、`router` 或
|
|
5
|
+
`stores` 等共享基础设施。
|
|
6
|
+
|
|
7
|
+
模板维护仓库保留完整能力源;实际项目先生成 `core` 或 `full` 档位。日常项目开发不应
|
|
8
|
+
直接复制整个维护仓库后再人工判断哪些目录可以删除。
|
|
9
|
+
|
|
10
|
+
## 开箱验收
|
|
11
|
+
|
|
12
|
+
1. 执行 `pnpm create react-admin-template@latest <项目目录>` 生成默认 core 项目;
|
|
13
|
+
维护者也可以在模板仓库执行 `pnpm scaffold:create --target <项目目录>`。
|
|
14
|
+
2. 进入目标项目,复制并填写 `tools/scaffold/init.example.json`,先预览再显式写入配置。
|
|
15
|
+
3. 执行 `pnpm scaffold:check`,确认脚手架基础配置可运行。
|
|
16
|
+
4. 接入真实后端时,在 `.env.local` 配置可访问的 `VITE_API_BASE_URL`。
|
|
17
|
+
5. 执行 `pnpm api` 后生成的客户端通过类型检查。
|
|
18
|
+
6. 执行 `pnpm dev` 后可以登录并进入 `/dashboard`。
|
|
19
|
+
7. 首次交付前执行 `pnpm scaffold:check --strict`,处理全部项目化提醒。
|
|
20
|
+
8. 执行 `pnpm verify` 通过完整质量门禁。
|
|
21
|
+
|
|
22
|
+
### 生成档位与可选能力
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm create react-admin-template@latest my-admin
|
|
26
|
+
pnpm create react-admin-template@latest my-admin-full --profile full
|
|
27
|
+
pnpm scaffold:create --target ../my-admin
|
|
28
|
+
pnpm scaffold:create --target ../my-admin-full --profile full
|
|
29
|
+
pnpm scaffold:add --target ../my-admin --capability advancedTable
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`core` 保留壳层、账号密码登录与会话刷新、路由权限、OpenAPI、Query、枚举与参数、文件、
|
|
33
|
+
Locale、PageForm、AppDataTable、Dialog 和工程门禁。`full` 额外包含高级认证编排、活动
|
|
34
|
+
状态、Feature Flag、高级表格、审计、报表、实时协作、租户/工作空间和可选编辑器。能力
|
|
35
|
+
添加命令必须从完整模板仓库执行,目标项目最终得到普通本地源码,不存在运行时插件加载
|
|
36
|
+
或内部 Node 包依赖。生成器保留同版本锁文件中的依赖快照,避免首次安装升级工具链;
|
|
37
|
+
`.scaffold-state.json` 应提交到目标项目,用于校验模板版本和已启用能力。
|
|
38
|
+
|
|
39
|
+
### 初始化命令
|
|
40
|
+
|
|
41
|
+
初始化清单一次性声明项目包名、应用初始版本、公开运行时配置和 OpenAPI 服务。先复制
|
|
42
|
+
示例并填写真实公开值:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
cp tools/scaffold/init.example.json scaffold.init.json
|
|
46
|
+
pnpm scaffold:init --config scaffold.init.json
|
|
47
|
+
pnpm scaffold:init --config scaffold.init.json --write
|
|
48
|
+
pnpm scaffold:check --strict
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
不带 `--write` 时只输出 `UPDATE`、`UNCHANGED` 和将变化的字段路径,不修改文件。写入前会
|
|
52
|
+
完成全部校验,并通过临时文件、备份和失败回滚更新以下三个稳定目标:
|
|
53
|
+
|
|
54
|
+
| 初始化清单字段 | 写入目标 | 所有权 |
|
|
55
|
+
| --------------- | ------------------------------ | -------------------------------------------- |
|
|
56
|
+
| `package` | `package.json` | 更新名称、描述和声明的版本,保留脚本和依赖 |
|
|
57
|
+
| `runtimeConfig` | `public/runtime-config.json` | 复用浏览器启动时的同一份 Zod 契约 |
|
|
58
|
+
| `apiServices` | `src/api/config/services.json` | 供 `swagger-typescript-api` 按服务生成客户端 |
|
|
59
|
+
|
|
60
|
+
清单是严格且带版本的 JSON 契约:未知字段、重复服务名、非法环境变量名、错误运行时字段都会在
|
|
61
|
+
写入前以 `SCAFFOLD_INIT_CONFIG_INVALID` 拒绝。同一清单重复写入不会产生额外 Diff,团队可以
|
|
62
|
+
提交不含密钥的 `scaffold.init.json` 作为初始化记录。
|
|
63
|
+
|
|
64
|
+
初始化命令不会替换 Logo/Favicon,不会修改认证 Adapter、路由、业务 Feature、`.env` 或生成
|
|
65
|
+
客户端,也不会访问后端。运行时配置和所有 `VITE_*` 值对浏览器公开,初始化清单中禁止
|
|
66
|
+
保存密码、Token、Client Secret 或其他密钥。
|
|
67
|
+
|
|
68
|
+
应用版本与模板版本是两条独立版本线。`package.json#version` 属于项目发布,
|
|
69
|
+
`scaffold.template.json#strAppliedVersion` 记录项目已经完整应用并验证的模板版本。当前
|
|
70
|
+
没有第二个模板版本,因此不预置升级引擎;完整人工评审与可回滚流程见
|
|
71
|
+
[`template-versioning.md`](template-versioning.md)。
|
|
72
|
+
|
|
73
|
+
### 初始化检查命令
|
|
74
|
+
|
|
75
|
+
`pnpm scaffold:check` 是只读预检,不修改文件、不访问后端、不生成 API 客户端,也不执行
|
|
76
|
+
完整生产构建。它检查:
|
|
77
|
+
|
|
78
|
+
- 当前 Node 是否满足 `package.json#engines.node`,pnpm 和 `.nvmrc` 是否声明完整;
|
|
79
|
+
- development/production 的 Vite 配置能否真实加载,构建变量是否符合约束;
|
|
80
|
+
- `public/runtime-config.json` 能否通过浏览器启动时使用的同一份 Zod 契约;
|
|
81
|
+
- `src/api/config/services.json` 是否具备 swagger-typescript-api 所需的服务定义;
|
|
82
|
+
- 包名、品牌、存储命名空间、认证参数、demo 模式和 `backend` 服务名是否仍是脚手架占位值。
|
|
83
|
+
|
|
84
|
+
普通模式中,配置错误返回非零退出码,项目化提醒不阻止本地启动。严格模式会把提醒也视为
|
|
85
|
+
首次交付阻断项:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pnpm scaffold:check
|
|
89
|
+
pnpm scaffold:check --strict
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
常见诊断与处理方式:
|
|
93
|
+
|
|
94
|
+
| 稳定诊断码 | 含义 | 处理位置 |
|
|
95
|
+
| ------------------------------- | --------------------------------- | ------------------------------------ |
|
|
96
|
+
| `BUILD_CONFIG_INVALID` | Vite 变量缺失、格式或文件路径错误 | `.env.local`、`.env.<mode>.local` |
|
|
97
|
+
| `RUNTIME_CONFIG_INVALID` | 运行时 JSON 不符合 Zod 契约 | `public/runtime-config.json` |
|
|
98
|
+
| `OPENAPI_SERVICES_INVALID` | OpenAPI 服务清单无效 | `src/api/config/services.json` |
|
|
99
|
+
| `PACKAGE_NAME_PLACEHOLDER` | 包名仍是脚手架默认值 | `package.json` |
|
|
100
|
+
| `STORAGE_NAMESPACE_PLACEHOLDER` | 存储命名空间尚未项目化 | `runtime-config.json#app` |
|
|
101
|
+
| `AUTH_CONFIG_PLACEHOLDER` | 认证公开参数仍为默认值 | `runtime-config.json#auth` |
|
|
102
|
+
| `DEMO_MODE_ACTIVE` | 尚未连接真实认证和业务数据 | Runtime Config 与项目 Adapter 组合点 |
|
|
103
|
+
|
|
104
|
+
检查命令不会验证后端可达性、OpenAPI 文档正确性、商业许可证有效性或生产密钥注入。这些需要在
|
|
105
|
+
对应环境执行 `pnpm api`、`pnpm verify`、部署健康检查和供应商许可验收。
|
|
106
|
+
|
|
107
|
+
## 第一次定制
|
|
108
|
+
|
|
109
|
+
环境相关的公开应用配置位于 `public/runtime-config.json`,由
|
|
110
|
+
`src/config/runtimeConfig.ts` 在浏览器启动时校验:
|
|
111
|
+
|
|
112
|
+
| 配置 | 用途 |
|
|
113
|
+
| ------------------------------ | -------------------------------------- |
|
|
114
|
+
| `app.strTitle` | 浏览器标题、登录页和侧边栏品牌名 |
|
|
115
|
+
| `app.strDescription` | 页面描述和侧边栏副标题 |
|
|
116
|
+
| `app.strBrandId` | 稳定白标标识,不参与租户授权 |
|
|
117
|
+
| `app.strLogoPath` | `public/` 下的 Logo 路径或公开图片地址 |
|
|
118
|
+
| `app.strDarkLogoPath` | 深色主题 Logo;可与浅色 Logo 相同 |
|
|
119
|
+
| `app.strFaviconPath` | 浏览器页签图标 |
|
|
120
|
+
| `app.objTheme` | 受限明暗品牌色与浏览器主题色 |
|
|
121
|
+
| `app.strStorageNamespace` | 认证、主题和 UI 偏好的浏览器存储前缀 |
|
|
122
|
+
| `app.strMode` | 演示或真实后端接入模式 |
|
|
123
|
+
| `api.strBaseUrl` | 浏览器运行时 API 基础地址 |
|
|
124
|
+
| `auth` | Audience、Client ID、Scope 和认证端点 |
|
|
125
|
+
| `auth.strSessionStorage` | `memory` 或当前标签页的 `session` |
|
|
126
|
+
| `observability.bEnabled` | 是否允许发送脱敏诊断事件 |
|
|
127
|
+
| `observability.strEnvironment` | 当前部署环境名称 |
|
|
128
|
+
| `locale.strLocale` | 共享文案、Intl 和后端元数据语言 |
|
|
129
|
+
| `locale.strTimeZone` | 日期时间统一使用的 IANA 时区 |
|
|
130
|
+
| `navigation`(`appConfig.ts`) | 登录成功与根路由进入的默认页面 |
|
|
131
|
+
|
|
132
|
+
`app.strStorageNamespace` 变更后,旧命名空间中的浏览器会话不会自动迁移。应在首次发布前
|
|
133
|
+
确定该值。运行时 JSON 和 `VITE_*` 变量都会暴露给浏览器,不能保存任何密钥。
|
|
134
|
+
|
|
135
|
+
同一构建产物可以按部署注入不同品牌名称、明暗 Logo、Favicon 和经过 WCAG AA 校验的语义
|
|
136
|
+
色,不需要复制源码。任意 CSS、字体和脚本不属于运行时契约;完整字段、资产降级和回滚方式
|
|
137
|
+
见 [`white-label.md`](white-label.md)。
|
|
138
|
+
|
|
139
|
+
推荐初始化顺序:
|
|
140
|
+
|
|
141
|
+
1. 使用 `scaffold:init` 统一写入包名、运行时公开配置和 OpenAPI 服务清单。
|
|
142
|
+
2. 替换 `public/logo.svg` 与 `public/favicon.ico`。
|
|
143
|
+
3. 按项目需要补充 `package.json` 的仓库元数据。
|
|
144
|
+
4. 在 `.env.local` 配置本地可访问的 OpenAPI 服务地址。
|
|
145
|
+
5. 根据后端协议调整 `src/api/authClient.ts` 和 `src/api/authSession.ts` 的认证适配。
|
|
146
|
+
6. 创建第一个业务 Feature 并注册路由。
|
|
147
|
+
7. 需要线上监控时,在 `src/config/observabilityAdapter.ts` 接入供应商 Adapter。
|
|
148
|
+
8. 更新部署配置和许可证,然后运行 `pnpm verify`。
|
|
149
|
+
9. 执行 `pnpm scaffold:check --strict`,确认没有遗留脚手架占位配置。
|
|
150
|
+
|
|
151
|
+
## 模块边界
|
|
152
|
+
|
|
153
|
+
```text
|
|
154
|
+
src/
|
|
155
|
+
config/ 应用品牌、入口和持久化契约
|
|
156
|
+
router/ 路由组合、守卫和回跳策略
|
|
157
|
+
api/ OpenAPI、请求生命周期、枚举、参数和元数据编排
|
|
158
|
+
files/ 上传、下载、预览和导入导出任务契约
|
|
159
|
+
locale/ 统一语言、时区、Intl 格式化和共享文案
|
|
160
|
+
permissions/ 响应式操作权限 Hook 与纯权限契约
|
|
161
|
+
features/ 页面级能力,内部拥有自己的 UI、规则、状态和请求
|
|
162
|
+
components/ 不包含产品策略的共享组件
|
|
163
|
+
context/ 全局 React Provider
|
|
164
|
+
stores/ 跨 Feature 且确有持久化需求的客户端状态
|
|
165
|
+
observability/ 结构化事件、脱敏策略和监控 Adapter 契约
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Feature 之间不应互相引用内部文件。跨 Feature 工作流由路由页或更高层组合;只有语义、
|
|
169
|
+
生命周期和维护责任都稳定的能力才能进入共享目录。
|
|
170
|
+
|
|
171
|
+
边界门禁遵循以下导入契约:
|
|
172
|
+
|
|
173
|
+
- 每个 `src/features/<featureName>` 都必须存在 `index.ts` 或 `index.tsx`。
|
|
174
|
+
- Feature 外部和其他 Feature 只能导入 `@/features/<featureName>`,不能拼接内部路径。
|
|
175
|
+
- Feature 不得导入 `@/router`、`@/layouts`、`@/Application` 或 `@/main`;共享策略下沉到
|
|
176
|
+
`api/`、`config/`、`lib/` 等基础层,上层编排则通过参数或组件属性注入。
|
|
177
|
+
- Feature 内部使用相对路径,白盒测试可以直接测试内部文件,但不得因此增加公共导出。
|
|
178
|
+
|
|
179
|
+
静态导入、动态 `import()` 和再导出都会由 ESLint 检查;新增一级 Feature 缺少公共入口
|
|
180
|
+
会由 `pnpm test:config` 阻断。
|
|
181
|
+
|
|
182
|
+
## 新增业务页面
|
|
183
|
+
|
|
184
|
+
1. 先执行 `pnpm scaffold:feature --name <featureName> --model <ModelName> --resource
|
|
185
|
+
<resource>` 预览,再追加 `--write` 生成 Feature 数据边界和契约测试。
|
|
186
|
+
2. 用真实 Swagger DTO、Repository Adapter、权限码和领域规则替换生成的中性记录语义。
|
|
187
|
+
3. 只在 Feature 根 `index.ts(x)` 暴露路由需要的页面,再从
|
|
188
|
+
`src/router/lazyRouteComponents.ts` 懒加载 `@/features/<featureName>`。
|
|
189
|
+
4. 在 `src/router/config.ts` 注册路由,通过 `staticData` 声明标题、图标和菜单排序。
|
|
190
|
+
5. 需要登录的页面挂在 `_app` 路由下;访客页面挂在 `_guest` 路由下。
|
|
191
|
+
6. 根据真实用户行为更新生成的测试,并补充需要的集成测试。
|
|
192
|
+
|
|
193
|
+
业务请求必须使用 `src/api/generated` 中的客户端,不能绕过统一认证、刷新和错误处理。
|
|
194
|
+
生成参数、冲突保护、生成客户端接线和双模式示例见
|
|
195
|
+
[`feature-data-template.md`](feature-data-template.md)。模板自身不注册路由,也不会进入默认
|
|
196
|
+
`src/features`、菜单或首屏包;其源码只作为生成器资产保存在 `tools/scaffold/templates`。
|
|
197
|
+
|
|
198
|
+
## 保留的基础设施
|
|
199
|
+
|
|
200
|
+
- 认证、会话续期和受保护路由
|
|
201
|
+
- 错误页、响应式布局、主题与菜单搜索
|
|
202
|
+
- 页面首次加载、成功空态、请求错误、请求 ID 与手动重试反馈
|
|
203
|
+
- 后端驱动的全局枚举与参数目录、作用域缓存、运行时校验与统一失效
|
|
204
|
+
- 路由、操作、表格和请求共用的权限判断与授权快照刷新
|
|
205
|
+
- shadcn/ui 以及通用表单、表格、弹窗、日期和 JSON 编辑组件
|
|
206
|
+
- OpenAPI 生成脚本、`ApiError`、请求关联 ID 和统一请求 Hook
|
|
207
|
+
- 用户、认证租户、语言和会话隔离的 Query Key,以及显式工作空间作用域与 Mutation 约定
|
|
208
|
+
- 文件上传、下载、图片/PDF 预览和同步/异步任务 Adapter
|
|
209
|
+
- Locale Provider、统一 Intl 格式化和 Feature 自有语言包入口
|
|
210
|
+
- 可按需加入的租户/工作空间上下文、后端确认切换、缓存隔离和失败恢复
|
|
211
|
+
- 通知未读数、近期任务状态、轮询/SSE/WebSocket Adapter 和断线恢复
|
|
212
|
+
- Mutation 幂等键、防重复激活、结果未知恢复和后端确认控制器
|
|
213
|
+
- AppTable 查询、排序、分页、字段偏好、显式/跨页选择和工具栏回调
|
|
214
|
+
- Feature 组合权限、幂等 Mutation、批量后端接口和 AppDialog
|
|
215
|
+
- PageForm/AppTable dirty 状态与统一路由、刷新、关闭保护
|
|
216
|
+
- 供应商无关可观测性 Adapter、默认拒绝脱敏策略和发布版本上下文
|
|
217
|
+
- 可独立关闭的 Web Vitals 采集、CSP 契约测试和依赖漏洞审计
|
|
218
|
+
- ESLint、Prettier、Stylelint、Knip、Vitest Browser、Playwright 与 CI
|
|
219
|
+
|
|
220
|
+
### 组件能力清单
|
|
221
|
+
|
|
222
|
+
`src/components/ui` 只保留当前壳层或内建能力实际使用的全局 shadcn primitives。新项目
|
|
223
|
+
需要其他 primitive 时通过 shadcn CLI 加入,禁止在业务能力中复制第二份。项目自有组件
|
|
224
|
+
按下表管理:
|
|
225
|
+
|
|
226
|
+
| 能力类型 | 内建组件 | 使用约束 |
|
|
227
|
+
| ------------ | ------------------------------------------------------ | ------------------------------------- |
|
|
228
|
+
| 数据交互 | `AppDataTable`、`AppPageForm` | core 默认内建,Feature 从根入口导入 |
|
|
229
|
+
| 高级数据交互 | `AppTable` | `advancedTable` 能力按需加入 |
|
|
230
|
+
| 文件交互 | `FileUpload`、`FilePreview` | 生成客户端和外部服务通过 Adapter 注入 |
|
|
231
|
+
| 页面反馈 | `PageLoadingState`、`PageEmptyState`、`PageErrorState` | 页面拥有请求状态,组件只负责展示 |
|
|
232
|
+
| 弹窗反馈 | `AppDialog`、`RouteDialog`、`StatusBadge` | 不得内置产品文案、权限或业务枚举 |
|
|
233
|
+
| 操作权限 | `Can`、`usePermission` | 权限码由 Feature 声明,后端最终授权 |
|
|
234
|
+
| 日期输入 | `DateRangePicker`、`DateTimePicker` | 统一使用全局日期与表单 primitives |
|
|
235
|
+
| 内容编辑 | `JsonEditor` | `optionalEditors` 能力按需加入 |
|
|
236
|
+
|
|
237
|
+
`StatusBadge` 仅为少量通用状态提供默认色调。业务状态必须显式传入 `strTone`,避免共享
|
|
238
|
+
组件暗含某个产品的状态语义。新增或移除脚手架能力时,应同步维护本清单和对应公共契约
|
|
239
|
+
测试。
|
|
240
|
+
|
|
241
|
+
文件能力的生成客户端适配、取消、Blob 内存上限、预览 Origin 和服务端职责见
|
|
242
|
+
[`file-capabilities.md`](file-capabilities.md)。
|
|
243
|
+
|
|
244
|
+
语言、时区、格式化、共享文案覆盖和 Feature 语言包边界见
|
|
245
|
+
[`locale-and-i18n.md`](locale-and-i18n.md)。
|
|
246
|
+
|
|
247
|
+
Feature 的 Query Key 层级、失效矩阵、乐观更新回滚和同资源 Mutation 并发策略见
|
|
248
|
+
[`query-data-conventions.md`](query-data-conventions.md)。
|
|
249
|
+
|
|
250
|
+
租户/工作空间 Adapter、切换顺序、React/非 React 入口和缓存边界见
|
|
251
|
+
[`tenant-workspace-context.md`](tenant-workspace-context.md)。
|
|
252
|
+
|
|
253
|
+
活动快照、未读数、任务状态、三种传输方式和安全重连接入见
|
|
254
|
+
[`activity-status.md`](activity-status.md)。
|
|
255
|
+
|
|
256
|
+
幂等 Mutation、生成客户端请求头、按钮状态和超时结果确认见
|
|
257
|
+
[`mutation-idempotency.md`](mutation-idempotency.md)。
|
|
258
|
+
|
|
259
|
+
AppTable 已统一查询、排序、分页、偏好、显式/跨页选择和工具栏回调。业务 Feature
|
|
260
|
+
直接消费这些回调,并用 generated 批量接口、权限、幂等 Mutation 与 `AppDialog` 组合流程;
|
|
261
|
+
不要再建立一套平行的页面筛选或批量操作状态机。
|
|
262
|
+
|
|
263
|
+
页面加载、空态、错误恢复以及页面内反馈和全局 Toast 的归属规则见
|
|
264
|
+
[`page-feedback.md`](page-feedback.md)。
|
|
265
|
+
|
|
266
|
+
共享组件不应包含某个产品的文案、状态枚举或接口类型。新增依赖前应先确认浏览器或现有
|
|
267
|
+
组件不能满足需求,并为依赖建立明确的消费边界。
|
|
268
|
+
|
|
269
|
+
## 操作与请求权限
|
|
270
|
+
|
|
271
|
+
认证会话中的 `objUser.arrPermissions` 是前端唯一权限源。路由元数据、菜单、命令搜索、
|
|
272
|
+
`usePermission`、`Can` 和请求守卫都读取这份身份快照;不要为按钮再建立权限 Context 或
|
|
273
|
+
Zustand Store。单个权限码直接传字符串,多权限可传数组并用 `all` 或 `any` 指定匹配方式:
|
|
274
|
+
|
|
275
|
+
```tsx
|
|
276
|
+
const bCanWrite = usePermission('inventory:item:write')
|
|
277
|
+
|
|
278
|
+
<Can objRequirement='inventory:item:write'>
|
|
279
|
+
<Button>编辑</Button>
|
|
280
|
+
</Can>
|
|
281
|
+
|
|
282
|
+
<Can
|
|
283
|
+
objRequirement='inventory:item:write'
|
|
284
|
+
strDeniedBehavior='disable'
|
|
285
|
+
>
|
|
286
|
+
{({ bIsDisabled }) => <Button disabled={bIsDisabled}>编辑</Button>}
|
|
287
|
+
</Can>
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
默认使用隐藏策略;需要向用户解释“功能存在但不可用”时才保留禁用态。禁用模式使用
|
|
291
|
+
Render Props,由调用方把 `bIsDisabled` 写到真实交互元素,避免只给外层容器加样式却
|
|
292
|
+
仍可触发操作。`AppTable` 不内置业务权限码,Feature 通过同一个结果设置现有工具栏按钮
|
|
293
|
+
的 `hidden` 或 `disabled`:
|
|
294
|
+
|
|
295
|
+
```tsx
|
|
296
|
+
const bCanExport = usePermission('inventory:item:export')
|
|
297
|
+
|
|
298
|
+
const arrButtons = [
|
|
299
|
+
{
|
|
300
|
+
key: 'export',
|
|
301
|
+
label: '导出',
|
|
302
|
+
hidden: !bCanExport,
|
|
303
|
+
onClick: fnExport,
|
|
304
|
+
},
|
|
305
|
+
]
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
可见性不能替代服务端授权。TanStack Query 和 Mutation 直接调用生成客户端:
|
|
309
|
+
|
|
310
|
+
```tsx
|
|
311
|
+
const objScope = useAppQueryScope()
|
|
312
|
+
const objKeys = fnCreateAppQueryKeys('inventory', objScope)
|
|
313
|
+
|
|
314
|
+
useQuery({
|
|
315
|
+
queryKey: objKeys.fnLists('items'),
|
|
316
|
+
queryFn: ({ signal: objSignal }) =>
|
|
317
|
+
objInventoryApi.api.inventoryItemsList({ signal: objSignal }),
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
useMutation({
|
|
321
|
+
mutationFn: (objInput) =>
|
|
322
|
+
objInventoryApi.api.inventoryItemsCreate(objInput),
|
|
323
|
+
})
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
后端必须对每个请求重新授权,并通过统一 `401/403 ApiError` 返回拒绝结果。前端不在
|
|
327
|
+
数据层重复维护一套权限判定,避免权限刷新不同步时产生与后端相反的结果。
|
|
328
|
+
刷新接口可以在 `objUser` 中返回最新权限、角色和租户;授权上下文变化后脚手架会提升
|
|
329
|
+
会话版本、清理旧 Query/枚举数据、重新校验当前路由并自动刷新可见操作。
|
|
330
|
+
|
|
331
|
+
## 全局参数与元数据初始化
|
|
332
|
+
|
|
333
|
+
全局参数用于后端集中维护、跨 Feature 读取的公开业务配置,例如导出行数上限、支持
|
|
334
|
+
文案或某项通用交互是否开放。它不等同于 `runtime-config.json`:运行时配置决定应用在
|
|
335
|
+
哪个环境以及如何连接服务;全局参数是登录后按租户、会话代次和语言加载的服务端数据。
|
|
336
|
+
参数接口禁止返回密码、Token、私钥或其他客户端不应持有的秘密,也不能替代后端权限和
|
|
337
|
+
Feature Flag 的服务端决策。
|
|
338
|
+
|
|
339
|
+
推荐接口为 `/api/v1/meta/parameters`,响应 `data` 使用以下结构;项目也可以通过 Adapter
|
|
340
|
+
映射不同的后端 DTO:
|
|
341
|
+
|
|
342
|
+
```json
|
|
343
|
+
{
|
|
344
|
+
"version": "2026.08.26",
|
|
345
|
+
"locale": "zh-CN",
|
|
346
|
+
"parameters": {
|
|
347
|
+
"application.allowExport": {
|
|
348
|
+
"type": "boolean",
|
|
349
|
+
"value": true,
|
|
350
|
+
"description": "是否展示通用导出入口"
|
|
351
|
+
},
|
|
352
|
+
"application.maxExportRows": {
|
|
353
|
+
"type": "number",
|
|
354
|
+
"value": 5000
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
支持 `boolean`、有限 `number`、`string` 和 JSON 数组/对象/`null`。目录在进入 Query
|
|
361
|
+
缓存前校验类型、语言、版本和 JSON 有效性,并深度冻结复合值;调用方读取的预期类型与
|
|
362
|
+
后端声明不一致时抛出带稳定错误码的 `GlobalParameterError`,不会静默转换字符串和数字。
|
|
363
|
+
|
|
364
|
+
使用 `swagger-typescript-api` 生成客户端后,在应用组合点创建数据源:
|
|
365
|
+
|
|
366
|
+
```tsx
|
|
367
|
+
const objGlobalParameterSource = fnCreateGlobalParameterSource(
|
|
368
|
+
async ({ objScope, objSignal, strLocale }) => {
|
|
369
|
+
const objResponse = await objMetadataApi.api.apiV1MetaParametersGet(
|
|
370
|
+
{
|
|
371
|
+
locale: strLocale,
|
|
372
|
+
tenantId: objScope.strTenantId,
|
|
373
|
+
},
|
|
374
|
+
{ signal: objSignal }
|
|
375
|
+
)
|
|
376
|
+
return objResponse.data
|
|
377
|
+
}
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
objRoot.render(
|
|
381
|
+
<Application
|
|
382
|
+
objMetadata={{
|
|
383
|
+
objGlobalParameters: { objSource: objGlobalParameterSource },
|
|
384
|
+
}}
|
|
385
|
+
/>
|
|
386
|
+
)
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
React Feature 使用准确类型 Hook;完整目录和通用值可分别读取:
|
|
390
|
+
|
|
391
|
+
```tsx
|
|
392
|
+
const objAllowExport = useBooleanGlobalParameter(
|
|
393
|
+
'application.allowExport'
|
|
394
|
+
)
|
|
395
|
+
const objMaxRows = useNumberGlobalParameter(
|
|
396
|
+
'application.maxExportRows'
|
|
397
|
+
)
|
|
398
|
+
const objCatalog = useGlobalParameterCatalog()
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
React 外部使用 `fnEnsureGlobalParameters` 预加载、
|
|
402
|
+
`fnGetCachedGlobalParameters` 同步读取 Query 缓存,再配合
|
|
403
|
+
`fnGetBooleanGlobalParameter`、`fnGetNumberGlobalParameter`、
|
|
404
|
+
`fnGetStringGlobalParameter`、`fnGetJsonGlobalParameter`、
|
|
405
|
+
`fnGetGlobalParameterKeys` 和 `fnGetGlobalParameterValue`。参数维护成功后调用
|
|
406
|
+
`fnInvalidateGlobalParameters`,不能把服务端值复制进 Zustand 或在 Feature 中永久缓存。
|
|
407
|
+
|
|
408
|
+
`MetadataProvider` 是应用层编排边界:未登录时默认不请求;登录后枚举与参数并行加载;
|
|
409
|
+
租户、会话代次或语言变化会切换隔离后的 Query Key。任何一个资源失败都不会替换或隐藏
|
|
410
|
+
应用子树,相关 Feature 分别通过 `useEnumCatalog()` 或
|
|
411
|
+
`useGlobalParameterCatalog()` 的错误状态与 `fnRefetch()` 展示降级和重试。当前两个目录没有
|
|
412
|
+
互相依赖,不再维护重复的聚合状态,也禁止为了“统一初始化”人为制造串行请求瀑布。
|
|
413
|
+
|
|
414
|
+
## 无障碍与核心旅程测试
|
|
415
|
+
|
|
416
|
+
浏览器测试运行在 Playwright Chromium 中,不使用 DOM 模拟器声明真实焦点行为。
|
|
417
|
+
`tests/setup/accessibility.ts` 提供 axe 断言,应用集成测试至少覆盖:
|
|
418
|
+
|
|
419
|
+
- 浅色和深色登录壳层的语义、标签与颜色对比度。
|
|
420
|
+
- 登录后的应用壳层,无严重或关键 axe 违规。
|
|
421
|
+
- 纯键盘登录、受保护首页到达、用户菜单退出和会话回到登录页。
|
|
422
|
+
- 表单校验后焦点进入首个错误字段;Dialog 等复合控件继续由所属组件测试焦点进入、
|
|
423
|
+
Escape 和恢复行为。
|
|
424
|
+
|
|
425
|
+
axe 只扫描当前 React 测试容器,避免把 Vitest Browser 自己的界面计入结果。发现违规时
|
|
426
|
+
应修复语义、交互或全局主题令牌,不得通过关闭规则维持绿灯。自动扫描不能证明完整
|
|
427
|
+
无障碍,新 Feature 仍需用真实键盘验证操作顺序、可见焦点、动态反馈和适用的焦点恢复。
|
|
428
|
+
|
|
429
|
+
## 交付约束
|
|
430
|
+
|
|
431
|
+
- 支持版本以 `package.json#engines`、`.nvmrc` 和 `packageManager` 为准。
|
|
432
|
+
- `pnpm api` 的生成结果不提交,但 `src/api/generated` 是生成器拥有的工作目录,不得作为
|
|
433
|
+
冗余内容手工清理;生成模板、服务清单与原子替换流程都属于脚手架契约。
|
|
434
|
+
- `pnpm verify` 是提交和合并前的统一门禁。
|
|
435
|
+
- 模板升级只通过独立 Git 分支、Changelog、人工冲突处理和 `pnpm verify` 落地;规则见
|
|
436
|
+
[`template-versioning.md`](template-versioning.md)。
|
|
437
|
+
- `pnpm build` 会基于 Vite Manifest 校验入口、登录、中性首页和全局 CSS 的 gzip 预算;
|
|
438
|
+
阈值、Owner 与调整规则见 [`bundle-budgets.md`](bundle-budgets.md)。
|
|
439
|
+
- CI 在门禁通过后执行 `pnpm release:prepare`;后续镜像和部署只能消费带文件摘要与 Commit
|
|
440
|
+
身份的 `.artifacts/release`,不得再次构建前端。
|
|
441
|
+
- `runtime-config.json` 是环境配置,不进入不可变发布目录;部署按镜像 Digest 拉取后注入。
|
|
442
|
+
- `dist/`、`.artifacts/`、本地缓存、环境私有配置和凭据不得提交。
|
|
443
|
+
- 对外分发前必须确认仓库许可证和 Handsontable 商业授权。
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# 模板变更记录
|
|
2
|
+
|
|
3
|
+
本文件记录脚手架公共契约对派生项目的影响,不记录普通业务 Feature 的内部提交。应用自身
|
|
4
|
+
版本继续使用 `package.json#version`;项目已应用的模板版本记录在
|
|
5
|
+
`scaffold.template.json`,两者独立演进。
|
|
6
|
+
|
|
7
|
+
## 0.1.0 - 2026-08-28
|
|
8
|
+
|
|
9
|
+
首个受治理的模板基线,包含:
|
|
10
|
+
|
|
11
|
+
- React 19、TypeScript、Vite、路由、认证和运行时配置壳层;
|
|
12
|
+
- 源码内置的 PageForm、Table、反馈、文件、枚举和全局参数等企业通用能力;
|
|
13
|
+
- Swagger/OpenAPI 生成器、Feature 生成器、初始化检查、架构边界、浏览器测试、构建体积
|
|
14
|
+
预算和不可变发布产物门禁。
|
|
15
|
+
|
|
16
|
+
这是初始版本,不需要从旧模板执行迁移。
|
|
17
|
+
|
|
18
|
+
## 维护规则
|
|
19
|
+
|
|
20
|
+
每次模板发布必须同步完成:
|
|
21
|
+
|
|
22
|
+
1. 在本文件中先写派生项目能观察到的变化,再写迁移步骤、验证方式和废弃周期;不能只列
|
|
23
|
+
内部 Commit。
|
|
24
|
+
2. 将 `scaffold.template.json#strAppliedVersion` 更新为新版本,使新创建项目记录准确基线。
|
|
25
|
+
3. 在至少两个派生项目验证迁移步骤,并运行 `pnpm verify`。
|
|
26
|
+
4. 模板升级必须作为独立 Git 提交或合并请求落地。回滚恢复整个升级提交,不允许只降低
|
|
27
|
+
`strAppliedVersion` 掩盖已经进入源码和配置的变化。
|
|
28
|
+
|
|
29
|
+
SemVer 按派生项目影响解释:删除或改变公共入口、类型、初始化契约、CSS/交互行为以及更
|
|
30
|
+
严格且会拒绝旧配置的校验都可能是破坏性变更;仅修改模板内部实现不能自动视为兼容。
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# 模板版本与升级策略
|
|
2
|
+
|
|
3
|
+
脚手架和派生项目有两条独立版本线。项目应用版本来自 `package.json#version`;已经应用的
|
|
4
|
+
模板版本来自 `scaffold.template.json#strAppliedVersion`。两者不能互相替代。
|
|
5
|
+
|
|
6
|
+
当前模板只有 `0.1.0` 一个已发布基线,没有真实的跨版本迁移消费者,因此不维护模板目录、
|
|
7
|
+
连续路径算法或自动覆盖工具。提前建设升级引擎只会增加规则和维护成本,不能证明真实项目的
|
|
8
|
+
认证、路由、主题与业务定制能够自动合并。
|
|
9
|
+
|
|
10
|
+
## 当前升级流程
|
|
11
|
+
|
|
12
|
+
1. 模板维护者在 [`template-changelog.md`](template-changelog.md) 记录派生项目可观察的变化。
|
|
13
|
+
2. 项目团队为模板同步创建独立 Git 分支,保持业务改动与模板改动分离。
|
|
14
|
+
3. 按 Changelog 通过合并、Cherry-pick 或明确补丁应用变化,人工处理项目定制冲突。
|
|
15
|
+
4. 运行 `pnpm components:diff`、相关回归测试和 `pnpm verify`。
|
|
16
|
+
5. 源码、配置和 `scaffold.template.json` 在同一提交或合并请求中更新。
|
|
17
|
+
6. 出现回归时恢复完整升级提交,不能只降低模板版本字段。
|
|
18
|
+
|
|
19
|
+
## 何时再建设迁移工具
|
|
20
|
+
|
|
21
|
+
只有出现第二个稳定模板版本,并且至少两个派生项目需要执行相同、可机械化、可幂等的迁移
|
|
22
|
+
时,才为该次具体变化建设窄范围 Codemod 或升级检查。工具必须有真实输入样本、失败诊断、
|
|
23
|
+
重复执行测试和完整 Git 回滚方案,不能演变成通用源码合并器。
|
|
24
|
+
|
|
25
|
+
模板 SemVer 按消费者影响解释:公共入口、类型、初始化契约、CSS/交互行为或更严格的输入
|
|
26
|
+
拒绝都可能构成破坏性变化。应用自己的 Changelog、发布节奏和版本号不受模板版本牵制。
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# 租户与工作空间上下文
|
|
2
|
+
|
|
3
|
+
这套能力统一管理“当前请求属于哪个租户和工作空间”,不提供租户列表、成员管理或切换
|
|
4
|
+
页面。租户/工作空间列表仍是服务端数据,应由具体项目的 Feature 通过生成客户端和
|
|
5
|
+
TanStack Query 加载;前端上下文只保存后端已经确认过的稳定 ID。
|
|
6
|
+
|
|
7
|
+
它不进入默认 `core`。先从完整模板仓库按需复制,公共入口统一从
|
|
8
|
+
`@/tenantWorkspace` 导入:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
pnpm scaffold:add --target ../my-admin --capability tenantWorkspace
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
能力不会偷偷修改应用根。项目需要在组合点显式挂载 Provider,并决定切换前取消哪些请求、
|
|
15
|
+
切换后重新校验哪些路由。
|
|
16
|
+
|
|
17
|
+
## 状态所有权
|
|
18
|
+
|
|
19
|
+
| 状态 | 唯一所有者 | 持久化与隔离 |
|
|
20
|
+
| ---------------------- | ------------------------------ | ----------------------------------------------------- |
|
|
21
|
+
| 当前租户 ID | 认证会话 `objUser.strTenantId` | 跟随会话;变化会提升会话版本并清空 QueryClient |
|
|
22
|
+
| 当前工作空间 ID | `tenantWorkspace` 上下文 | 只保存经后端确认的 ID,并绑定当前 `userId + tenantId` |
|
|
23
|
+
| 租户/工作空间列表 | 所属 Feature 的 TanStack Query | 不复制进全局 Store |
|
|
24
|
+
| 切换中、失败和重试目标 | `tenantWorkspace` 切换事务 | 仅保留在内存,刷新后不恢复未完成事务 |
|
|
25
|
+
| Token、角色和权限 | 认证会话 | 跨租户切换必须由后端返回完整新会话 |
|
|
26
|
+
|
|
27
|
+
工作空间选择使用带应用命名空间的 Local Storage Key。持久化值不被当作授权凭证:当前认证
|
|
28
|
+
用户或租户不匹配时不会生效,并由 Provider 清理;每个后端请求仍必须重新校验成员关系和权限。
|
|
29
|
+
|
|
30
|
+
## 切换顺序
|
|
31
|
+
|
|
32
|
+
`fnSwitchTenantWorkspace()` 和 `useTenantWorkspace().fnSwitch()` 使用相同事务:
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
标准化稳定目标 ID
|
|
36
|
+
↓
|
|
37
|
+
取消更早的切换请求
|
|
38
|
+
↓
|
|
39
|
+
项目 Adapter 调用后端并校验成员关系
|
|
40
|
+
↓
|
|
41
|
+
校验返回目标;跨租户必须带新认证会话
|
|
42
|
+
↓
|
|
43
|
+
取消旧上下文仍在运行的 Query
|
|
44
|
+
↓
|
|
45
|
+
提交新会话 → 提交工作空间 → 重新校验当前路由
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
后端确认前旧上下文始终生效。Adapter 失败、结果不一致、缺少跨租户会话或提交前取消时,
|
|
49
|
+
旧租户、工作空间和缓存身份都不改变。用户连续切换时采用“最后一次请求生效”;旧 Adapter
|
|
50
|
+
收到 `AbortSignal`,即使它忽略取消并稍后返回,也不能覆盖较新的选择。
|
|
51
|
+
|
|
52
|
+
## 接入 Swagger 生成客户端
|
|
53
|
+
|
|
54
|
+
项目在组合点实现 `ITenantWorkspaceAdapter`,不要在基础设施中写死接口路径或生成 DTO。
|
|
55
|
+
下面的接口名只是接线形状,实际字段由项目后端契约决定:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { Application } from '@/Application'
|
|
59
|
+
import { objQueryClient, objRouter } from '@/router/router'
|
|
60
|
+
import {
|
|
61
|
+
TenantWorkspaceProvider,
|
|
62
|
+
type ITenantWorkspaceAdapter,
|
|
63
|
+
} from '@/tenantWorkspace'
|
|
64
|
+
|
|
65
|
+
const objTenantWorkspaceAdapter: ITenantWorkspaceAdapter = {
|
|
66
|
+
fnSwitch: async ({ objSignal, objTarget }) => {
|
|
67
|
+
const objResponse = await objGeneratedApi.api.switchContext(
|
|
68
|
+
{
|
|
69
|
+
tenantId: objTarget.strTenantId,
|
|
70
|
+
workspaceId: objTarget.strWorkspaceId,
|
|
71
|
+
},
|
|
72
|
+
{ signal: objSignal }
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
strTenantId: objResponse.data.tenantId,
|
|
77
|
+
strWorkspaceId: objResponse.data.workspaceId,
|
|
78
|
+
// 跨租户时在项目 Adapter 中把后端 DTO 映射为完整 IAuthSession。
|
|
79
|
+
objSession: fnMapContextSession(objResponse.data.session),
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
objRoot.render(
|
|
85
|
+
<TenantWorkspaceProvider
|
|
86
|
+
fnAfterCommit={() => void objRouter.invalidate()}
|
|
87
|
+
fnBeforeCommit={() => objQueryClient.cancelQueries()}
|
|
88
|
+
objAdapter={objTenantWorkspaceAdapter}
|
|
89
|
+
>
|
|
90
|
+
<Application />
|
|
91
|
+
</TenantWorkspaceProvider>
|
|
92
|
+
)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
同租户工作空间切换在 Token 和权限不变时可以不返回 `objSession`。如果权限或 Token 随
|
|
96
|
+
工作空间变化,也应返回完整会话,让现有认证生命周期统一提升会话版本、清缓存和刷新
|
|
97
|
+
路由。禁止只在客户端修改租户 ID,或从旧会话拼接一个“看起来属于新租户”的用户对象。
|
|
98
|
+
|
|
99
|
+
## React 与非 React 使用
|
|
100
|
+
|
|
101
|
+
普通组件读取当前上下文并发起切换:
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
const {
|
|
105
|
+
fnCancel,
|
|
106
|
+
fnClearError,
|
|
107
|
+
fnRetry,
|
|
108
|
+
fnSwitch,
|
|
109
|
+
objCurrent,
|
|
110
|
+
objTransition,
|
|
111
|
+
} = useTenantWorkspace()
|
|
112
|
+
|
|
113
|
+
await fnSwitch({
|
|
114
|
+
strTenantId: objTenant.strId,
|
|
115
|
+
strWorkspaceId: objWorkspace.strId,
|
|
116
|
+
})
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`objTransition` 是 `idle | switching | error` 可判别联合。失败状态保留 `objTarget` 和带稳定
|
|
120
|
+
`strCode` 的 `TenantWorkspaceError`,页面可以展示旧上下文、提供重试或清除错误。组件卸载
|
|
121
|
+
或用户主动停止时调用 `fnCancel()`。
|
|
122
|
+
|
|
123
|
+
路由 Loader、命令处理器等 React 外代码使用 `fnGetTenantWorkspaceCurrent()` 或
|
|
124
|
+
`fnGetTenantWorkspaceSnapshot()`。需要在 React 外切换时,显式把 Adapter 和生命周期依赖
|
|
125
|
+
传给 `fnSwitchTenantWorkspace()`,避免隐藏的全局 API 注册表。
|
|
126
|
+
|
|
127
|
+
## Query、枚举和参数隔离
|
|
128
|
+
|
|
129
|
+
- 默认 `useAppQueryScope()` 只从认证会话读取用户和租户,不依赖该可选能力。
|
|
130
|
+
- 启用后,所属 Feature 从 `useTenantWorkspace()` 读取 `objCurrent.strWorkspaceId`,并显式传给
|
|
131
|
+
`useAppQueryScope({ strWorkspaceId })`;跨空间管理页也按同样方式传入自己的目标空间。
|
|
132
|
+
- 工作空间变化会产生新的 Query Key;切换提交前取消旧作用域的活动请求,旧缓存不能被
|
|
133
|
+
新 Key 读取。
|
|
134
|
+
- 租户变化必须提交新认证会话,现有认证生命周期会清空全部服务端查询缓存。
|
|
135
|
+
- 枚举与全局参数默认按认证租户隔离。确实存在工作空间级元数据时,由项目组合层把当前
|
|
136
|
+
`strWorkspaceId` 显式传入 `objMetadata` 的对应 `objScope`;失败不替换旧作用域事实。
|
|
137
|
+
|
|
138
|
+
工作空间 ID 只负责缓存身份,不能替代请求参数或后端授权。若接口需要工作空间字段,
|
|
139
|
+
Repository 仍应把当前 ID 明确传给生成客户端。
|
|
140
|
+
|
|
141
|
+
## 不支持范围
|
|
142
|
+
|
|
143
|
+
- 不内置租户选择器、工作空间树、成员管理、套餐或计费页面。
|
|
144
|
+
- 不保存租户/工作空间名称、列表、权限或其他服务端事实。
|
|
145
|
+
- 不用 Local Storage 选择替代后端成员关系校验。
|
|
146
|
+
- 不为不同项目假定“租户”和“组织/项目”的层级关系。
|
|
147
|
+
- 不允许切换失败后自动回退到 Demo 数据或另一个猜测的工作空间。
|