@nocobase/client-v2 2.1.0-alpha.40 → 2.1.0-alpha.46
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/es/Application.d.ts +7 -0
- package/es/BaseApplication.d.ts +13 -0
- package/es/RouterManager.d.ts +1 -0
- package/es/authRedirect.d.ts +12 -0
- package/es/collection-field-interface/CollectionFieldInterface.d.ts +51 -15
- package/es/collection-field-interface/CollectionFieldInterfaceManager.d.ts +82 -3
- package/es/collection-manager/field-configure.d.ts +80 -0
- package/es/collection-manager/field-validation.d.ts +43 -0
- package/es/collection-manager/filter-operators/index.d.ts +46 -0
- package/es/collection-manager/filter-operators/operators.d.ts +30 -0
- package/es/collection-manager/interfaces/checkbox.d.ts +1 -41
- package/es/collection-manager/interfaces/checkboxGroup.d.ts +12 -44
- package/es/collection-manager/interfaces/collection.d.ts +12 -51
- package/es/collection-manager/interfaces/color.d.ts +1 -16
- package/es/collection-manager/interfaces/createdAt.d.ts +1 -44
- package/es/collection-manager/interfaces/createdBy.d.ts +0 -4
- package/es/collection-manager/interfaces/dateOnly.d.ts +7 -44
- package/es/collection-manager/interfaces/datetime.d.ts +1 -44
- package/es/collection-manager/interfaces/datetimeNoTz.d.ts +1 -44
- package/es/collection-manager/interfaces/email.d.ts +1 -29
- package/es/collection-manager/interfaces/id.d.ts +1 -16
- package/es/collection-manager/interfaces/index.d.ts +2 -3
- package/es/collection-manager/interfaces/input.d.ts +1 -102
- package/es/collection-manager/interfaces/integer.d.ts +1 -95
- package/es/collection-manager/interfaces/json.d.ts +16 -7
- package/es/collection-manager/interfaces/m2m.d.ts +11 -19
- package/es/collection-manager/interfaces/m2o.d.ts +11 -19
- package/es/collection-manager/interfaces/markdown.d.ts +1 -63
- package/es/collection-manager/interfaces/multipleSelect.d.ts +12 -44
- package/es/collection-manager/interfaces/nanoid.d.ts +1 -34
- package/es/collection-manager/interfaces/number.d.ts +1 -87
- package/es/collection-manager/interfaces/o2m.d.ts +12 -24
- package/es/collection-manager/interfaces/obo.d.ts +207 -0
- package/es/collection-manager/interfaces/oho.d.ts +207 -0
- package/es/collection-manager/interfaces/password.d.ts +1 -56
- package/es/collection-manager/interfaces/percent.d.ts +1 -84
- package/es/collection-manager/interfaces/phone.d.ts +1 -25
- package/es/collection-manager/interfaces/properties/index.d.ts +0 -28
- package/es/collection-manager/interfaces/radioGroup.d.ts +1 -29
- package/es/collection-manager/interfaces/richText.d.ts +1 -63
- package/es/collection-manager/interfaces/select.d.ts +12 -44
- package/es/collection-manager/interfaces/snowflake-id.d.ts +1 -34
- package/es/collection-manager/interfaces/tableoid.d.ts +1 -10
- package/es/collection-manager/interfaces/textarea.d.ts +1 -51
- package/es/collection-manager/interfaces/time.d.ts +1 -16
- package/es/collection-manager/interfaces/types.d.ts +3 -12
- package/es/collection-manager/interfaces/unixTimestamp.d.ts +1 -44
- package/es/collection-manager/interfaces/updatedAt.d.ts +1 -44
- package/es/collection-manager/interfaces/updatedBy.d.ts +0 -4
- package/es/collection-manager/interfaces/url.d.ts +1 -20
- package/es/collection-manager/interfaces/uuid.d.ts +1 -34
- package/es/collection-manager/template-fields.d.ts +53 -0
- package/es/components/KeepAlive.d.ts +22 -0
- package/es/components/RouterBridge.d.ts +9 -0
- package/es/components/form/DialogFormLayout.d.ts +5 -29
- package/es/components/form/TypedVariableInput.d.ts +75 -0
- package/es/components/form/VariableInput.d.ts +53 -2
- package/es/components/form/filter/CollectionFilter.d.ts +49 -0
- package/es/components/form/filter/CollectionFilterItem.d.ts +49 -0
- package/es/components/form/filter/DateFilterDynamicComponent.d.ts +57 -0
- package/es/components/form/filter/FilterValueInput.d.ts +29 -0
- package/es/components/form/filter/index.d.ts +11 -0
- package/es/components/form/filter/useFilterActionProps.d.ts +96 -0
- package/es/components/form/index.d.ts +2 -0
- package/es/data-source/ExtendCollectionsProvider.d.ts +50 -0
- package/es/data-source/index.d.ts +9 -0
- package/es/flow/FlowPage.d.ts +2 -1
- package/es/flow/admin-shell/AdminLayoutRouteCoordinator.d.ts +8 -40
- package/es/flow/admin-shell/BaseLayoutModel.d.ts +89 -0
- package/es/flow/admin-shell/BaseLayoutRouteCoordinator.d.ts +74 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.d.ts +12 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuModels.d.ts +1 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutModel.d.ts +7 -92
- package/es/flow/admin-shell/admin-layout/AppListRender.d.ts +11 -0
- package/es/flow/admin-shell/admin-layout/index.d.ts +3 -0
- package/es/flow/admin-shell/admin-layout/useApplications.d.ts +3 -2
- package/es/flow/admin-shell/useAdminLayoutRoutePage.d.ts +2 -2
- package/es/flow/admin-shell/useLayoutRoutePage.d.ts +23 -0
- package/es/flow/components/ConditionBuilder.d.ts +1 -0
- package/es/flow/components/FieldAssignRulesEditor.d.ts +3 -1
- package/es/flow/components/FieldAssignValueInput.d.ts +1 -0
- package/es/flow/components/FlowRoute.d.ts +10 -1
- package/es/flow/components/fieldAssignOptions.d.ts +10 -0
- package/es/flow/components/filter/LinkageFilterItem.d.ts +1 -0
- package/es/flow/components/filter/VariableFilterItem.d.ts +1 -0
- package/es/flow/components/filter/index.d.ts +2 -0
- package/es/flow/components/filter/metaTreeAssociationDepth.d.ts +13 -0
- package/es/flow/components/filter/useFilterOptions.d.ts +66 -0
- package/es/flow/index.d.ts +4 -0
- package/es/flow/models/base/AssociationFieldGroupModel.d.ts +2 -33
- package/es/flow/models/base/PageModel/PageModel.d.ts +3 -1
- package/es/flow/models/blocks/assign-form/assignFieldValuesFlow.d.ts +92 -0
- package/es/flow/models/blocks/assign-form/index.d.ts +1 -0
- package/es/flow/models/blocks/form/FormActionGroupModel.d.ts +1 -0
- package/es/flow/models/blocks/form/FormActionModel.d.ts +9 -2
- package/es/flow/models/blocks/table/TableBlockModel.d.ts +10 -0
- package/es/flow/models/blocks/table/TableColumnModel.d.ts +2 -0
- package/es/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.d.ts +1 -1
- package/es/flow-compat/passwordUtils.d.ts +1 -1
- package/es/index.d.ts +6 -0
- package/es/index.mjs +552 -459
- package/es/layout-manager/LayoutContentRoute.d.ts +14 -0
- package/es/layout-manager/LayoutManager.d.ts +22 -0
- package/es/layout-manager/LayoutRoute.d.ts +14 -0
- package/es/layout-manager/index.d.ts +13 -0
- package/es/layout-manager/types.d.ts +20 -0
- package/es/layout-manager/utils.d.ts +14 -0
- package/es/nocobase-buildin-plugin/index.d.ts +3 -10
- package/es/settings-center/index.d.ts +1 -1
- package/es/settings-center/plugin-manager/BulkEnableButton.d.ts +15 -0
- package/es/settings-center/plugin-manager/PluginCard.d.ts +15 -0
- package/es/settings-center/plugin-manager/PluginDetail.d.ts +16 -0
- package/es/settings-center/{PluginManagerPage.d.ts → plugin-manager/index.d.ts} +1 -7
- package/es/settings-center/plugin-manager/types.d.ts +34 -0
- package/lib/index.js +552 -459
- package/package.json +8 -7
- package/src/Application.tsx +51 -12
- package/src/BaseApplication.tsx +32 -0
- package/src/PluginSettingsManager.ts +1 -1
- package/src/RouterManager.tsx +17 -1
- package/src/__tests__/PluginSettingsManager.test.ts +41 -2
- package/src/__tests__/app.test.tsx +17 -1
- package/src/__tests__/globalDeps.test.ts +1 -0
- package/src/__tests__/nocobase-buildin-plugin-auth.test.tsx +50 -2
- package/src/__tests__/plugin-manager.test.tsx +177 -0
- package/src/__tests__/settings-center.test.tsx +24 -2
- package/src/authRedirect.ts +43 -0
- package/src/collection-field-interface/CollectionFieldInterface.ts +71 -77
- package/src/collection-field-interface/CollectionFieldInterfaceManager.ts +201 -4
- package/src/collection-manager/field-configure.ts +548 -0
- package/src/collection-manager/field-validation.ts +195 -0
- package/src/collection-manager/filter-operators/index.ts +176 -0
- package/src/collection-manager/{interfaces/properties → filter-operators}/operators.ts +24 -13
- package/src/collection-manager/interfaces/checkbox.ts +2 -9
- package/src/collection-manager/interfaces/checkboxGroup.ts +2 -10
- package/src/collection-manager/interfaces/collection.ts +2 -15
- package/src/collection-manager/interfaces/color.ts +2 -2
- package/src/collection-manager/interfaces/createdAt.ts +2 -2
- package/src/collection-manager/interfaces/createdBy.ts +1 -12
- package/src/collection-manager/interfaces/dateOnly.ts +8 -2
- package/src/collection-manager/interfaces/datetime.ts +2 -2
- package/src/collection-manager/interfaces/datetimeNoTz.ts +2 -2
- package/src/collection-manager/interfaces/email.ts +2 -9
- package/src/collection-manager/interfaces/id.ts +1 -2
- package/src/collection-manager/interfaces/index.ts +2 -3
- package/src/collection-manager/interfaces/input.ts +2 -133
- package/src/collection-manager/interfaces/integer.ts +2 -71
- package/src/collection-manager/interfaces/json.tsx +17 -11
- package/src/collection-manager/interfaces/m2m.tsx +0 -21
- package/src/collection-manager/interfaces/m2o.tsx +0 -22
- package/src/collection-manager/interfaces/markdown.ts +2 -51
- package/src/collection-manager/interfaces/multipleSelect.ts +2 -14
- package/src/collection-manager/interfaces/nanoid.ts +2 -2
- package/src/collection-manager/interfaces/number.ts +2 -85
- package/src/collection-manager/interfaces/o2m.tsx +1 -22
- package/src/collection-manager/interfaces/obo.tsx +145 -0
- package/src/collection-manager/interfaces/oho.tsx +145 -0
- package/src/collection-manager/interfaces/password.ts +2 -44
- package/src/collection-manager/interfaces/percent.ts +2 -74
- package/src/collection-manager/interfaces/phone.ts +2 -2
- package/src/collection-manager/interfaces/properties/index.ts +0 -133
- package/src/collection-manager/interfaces/radioGroup.ts +2 -2
- package/src/collection-manager/interfaces/richText.ts +2 -51
- package/src/collection-manager/interfaces/select.ts +2 -14
- package/src/collection-manager/interfaces/snowflake-id.ts +2 -2
- package/src/collection-manager/interfaces/tableoid.ts +1 -2
- package/src/collection-manager/interfaces/textarea.ts +2 -51
- package/src/collection-manager/interfaces/time.ts +2 -2
- package/src/collection-manager/interfaces/types.ts +4 -12
- package/src/collection-manager/interfaces/unixTimestamp.tsx +2 -2
- package/src/collection-manager/interfaces/updatedAt.ts +2 -2
- package/src/collection-manager/interfaces/updatedBy.ts +1 -12
- package/src/collection-manager/interfaces/url.ts +2 -4
- package/src/collection-manager/interfaces/uuid.ts +2 -2
- package/src/collection-manager/template-fields.ts +109 -0
- package/src/components/KeepAlive.tsx +131 -0
- package/src/components/README.md +138 -6
- package/src/components/README.zh-CN.md +138 -7
- package/src/components/RouterBridge.tsx +28 -4
- package/src/components/__tests__/KeepAlive.test.tsx +63 -0
- package/src/components/__tests__/RouterBridge.test.tsx +27 -0
- package/src/components/form/DialogFormLayout.tsx +5 -29
- package/src/components/form/TypedVariableInput.tsx +441 -0
- package/src/components/form/VariableInput.tsx +101 -28
- package/src/components/form/__tests__/TypedVariableInput.test.tsx +152 -0
- package/src/components/form/__tests__/VariableInput.test.ts +85 -0
- package/src/components/form/filter/CollectionFilter.tsx +111 -0
- package/src/components/form/filter/CollectionFilterItem.tsx +184 -0
- package/src/components/form/filter/DateFilterDynamicComponent.tsx +283 -0
- package/src/components/form/filter/FilterValueInput.tsx +198 -0
- package/src/components/form/filter/__tests__/CollectionFilterItem.test.tsx +247 -0
- package/src/components/form/filter/__tests__/DateFilterDynamicComponent.test.tsx +148 -0
- package/src/components/form/filter/__tests__/FilterValueInput.test.tsx +243 -0
- package/src/components/form/filter/__tests__/compileFilterGroup.test.ts +146 -0
- package/src/components/form/filter/index.ts +13 -0
- package/src/components/form/filter/useFilterActionProps.ts +203 -0
- package/src/components/form/index.tsx +2 -0
- package/src/data-source/ExtendCollectionsProvider.tsx +144 -0
- package/src/data-source/__tests__/ExtendCollectionsProvider.test.tsx +264 -0
- package/src/data-source/index.ts +10 -0
- package/src/flow/FlowPage.tsx +35 -7
- package/src/flow/__tests__/FlowPage.test.tsx +79 -0
- package/src/flow/__tests__/FlowRoute.test.tsx +537 -3
- package/src/flow/actions/__tests__/linkageRules.hiddenSync.restore.test.ts +100 -0
- package/src/flow/actions/__tests__/linkageRules.subFormSetFieldProps.test.ts +191 -0
- package/src/flow/actions/__tests__/linkageRulesRefresh.test.ts +23 -1
- package/src/flow/actions/__tests__/openView.subModelKey.test.tsx +33 -0
- package/src/flow/actions/aclCheck.tsx +4 -0
- package/src/flow/actions/aclCheckRefresh.tsx +4 -0
- package/src/flow/actions/dataScope.tsx +8 -1
- package/src/flow/actions/dateTimeFormat.tsx +12 -8
- package/src/flow/actions/linkageRules.tsx +127 -2
- package/src/flow/actions/linkageRulesRefresh.tsx +2 -3
- package/src/flow/actions/openView.tsx +28 -4
- package/src/flow/actions/setTargetDataScope.tsx +1 -1
- package/src/flow/admin-shell/AdminLayoutRouteCoordinator.ts +11 -329
- package/src/flow/admin-shell/BaseLayoutModel.tsx +455 -0
- package/src/flow/admin-shell/BaseLayoutRouteCoordinator.ts +502 -0
- package/src/flow/admin-shell/__tests__/AdminLayoutRouteCoordinator.test.ts +547 -3
- package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +35 -7
- package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.tsx +160 -0
- package/src/flow/admin-shell/admin-layout/AdminLayoutMenuModels.tsx +15 -13
- package/src/flow/admin-shell/admin-layout/AdminLayoutModel.tsx +28 -201
- package/src/flow/admin-shell/admin-layout/AdminLayoutSlotModels.tsx +11 -2
- package/src/flow/admin-shell/admin-layout/AppListRender.tsx +139 -0
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutMenuModels.test.ts +76 -27
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutModel.test.tsx +149 -27
- package/src/flow/admin-shell/admin-layout/index.ts +3 -0
- package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.test.ts +11 -0
- package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.ts +2 -4
- package/src/flow/admin-shell/admin-layout/useApplications.tsx +34 -1
- package/src/flow/admin-shell/useAdminLayoutRoutePage.ts +10 -26
- package/src/flow/admin-shell/useLayoutRoutePage.ts +61 -0
- package/src/flow/common/Markdown/Edit.tsx +32 -4
- package/src/flow/components/AdminLayout.tsx +4 -154
- package/src/flow/components/ConditionBuilder.tsx +12 -2
- package/src/flow/components/FieldAssignRulesEditor.tsx +37 -46
- package/src/flow/components/FieldAssignValueInput.tsx +8 -4
- package/src/flow/components/FlowRoute.tsx +105 -15
- package/src/flow/components/__tests__/FieldAssignRulesEditor.test.tsx +112 -1
- package/src/flow/components/__tests__/fieldAssignOptions.test.ts +71 -1
- package/src/flow/components/code-editor/__tests__/runjsCompletions.test.ts +272 -27
- package/src/flow/components/code-editor/runjsCompletions.ts +490 -9
- package/src/flow/components/fieldAssignOptions.ts +23 -6
- package/src/flow/components/filter/LinkageFilterItem.tsx +22 -9
- package/src/flow/components/filter/VariableFilterItem.tsx +27 -9
- package/src/flow/components/filter/__tests__/fieldsToOptions.test.ts +48 -0
- package/src/flow/components/filter/__tests__/metaTreeAssociationDepth.test.ts +60 -0
- package/src/flow/components/filter/fieldsToOptions.ts +9 -4
- package/src/flow/components/filter/index.ts +3 -0
- package/src/flow/components/filter/metaTreeAssociationDepth.ts +69 -0
- package/src/flow/components/filter/useFilterOptions.ts +102 -0
- package/src/flow/index.ts +4 -0
- package/src/flow/models/actions/FilterActionModel.tsx +15 -3
- package/src/flow/models/actions/UpdateRecordActionModel.tsx +14 -95
- package/src/flow/models/actions/UpdateRecordActionUtils.ts +4 -7
- package/src/flow/models/actions/__tests__/AssignFormRefill.test.ts +116 -1
- package/src/flow/models/base/ActionModel.tsx +8 -1
- package/src/flow/models/base/AssociationFieldGroupModel.tsx +20 -3
- package/src/flow/models/base/GridModel.tsx +1 -1
- package/src/flow/models/base/PageModel/ChildPageModel.tsx +5 -1
- package/src/flow/models/base/PageModel/PageModel.tsx +51 -18
- package/src/flow/models/base/PageModel/RootPageModel.tsx +6 -13
- package/src/flow/models/base/PageModel/__tests__/ChildPageModel.test.ts +12 -0
- package/src/flow/models/base/PageModel/__tests__/PageModel.test.ts +102 -1
- package/src/flow/models/base/RouteModel.tsx +1 -1
- package/src/flow/models/base/__tests__/AssociationFieldGroupModel.test.ts +86 -0
- package/src/flow/models/base/__tests__/GridModel.render.test.tsx +53 -0
- package/src/flow/models/blocks/assign-form/AssignFormGridModel.tsx +12 -3
- package/src/flow/models/blocks/assign-form/AssignFormItemModel.tsx +77 -6
- package/src/flow/models/blocks/assign-form/__tests__/assignFieldValuesFlow.editor.test.tsx +216 -0
- package/src/flow/models/blocks/assign-form/assignFieldValuesFlow.tsx +308 -0
- package/src/flow/models/blocks/assign-form/index.ts +1 -0
- package/src/flow/models/blocks/filter-form/FilterFormItemModel.tsx +1 -1
- package/src/flow/models/blocks/filter-form/__tests__/FilterFormItemModel.defineChildren.test.ts +6 -1
- package/src/flow/models/blocks/filter-manager/flow-actions/connectFields.tsx +48 -6
- package/src/flow/models/blocks/form/FormActionGroupModel.tsx +14 -0
- package/src/flow/models/blocks/form/FormActionModel.tsx +30 -3
- package/src/flow/models/blocks/form/FormAssociationItemModel.tsx +9 -0
- package/src/flow/models/blocks/form/FormItemModel.tsx +17 -1
- package/src/flow/models/blocks/form/__tests__/FormActionGroupModel.test.ts +46 -0
- package/src/flow/models/blocks/form/__tests__/FormBlockModel.test.tsx +17 -0
- package/src/flow/models/blocks/form/__tests__/FormItemModel.defineChildren.test.ts +27 -2
- package/src/flow/models/blocks/form/__tests__/submitHandler.test.ts +71 -0
- package/src/flow/models/blocks/form/submitHandler.ts +8 -1
- package/src/flow/models/blocks/form/submitValues.ts +4 -1
- package/src/flow/models/blocks/form/value-runtime/__tests__/runtime.test.ts +29 -0
- package/src/flow/models/blocks/form/value-runtime/runtime.ts +5 -1
- package/src/flow/models/blocks/table/TableBlockModel.tsx +118 -16
- package/src/flow/models/blocks/table/TableColumnModel.tsx +15 -5
- package/src/flow/models/blocks/table/TableCustomColumnModel.tsx +2 -2
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.rowSelection.test.tsx +114 -0
- package/src/flow/models/blocks/table/__tests__/TableColumnModel.test.tsx +18 -0
- package/src/flow/models/fields/AssociationFieldModel/SubFormFieldModel.tsx +7 -1
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableColumnModel.tsx +6 -7
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableField.tsx +1 -1
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.tsx +6 -5
- package/src/flow/models/fields/ClickableFieldModel.tsx +9 -1
- package/src/flow/models/fields/CollectionSelectorFieldModel.tsx +8 -2
- package/src/flow/models/fields/DisplayEnumFieldModel.tsx +8 -2
- package/src/flow/models/fields/DisplayTimeFieldModel.tsx +1 -1
- package/src/flow/models/fields/TimeFieldModel.tsx +1 -1
- package/src/flow/models/fields/__tests__/TimeFieldModel.test.tsx +61 -0
- package/src/flow/models/fields/mobile-components/MobileDatePicker.tsx +19 -3
- package/src/flow/models/fields/mobile-components/MobileLazySelect.tsx +5 -3
- package/src/flow/models/fields/mobile-components/__tests__/MobileDatePicker.test.tsx +94 -0
- package/src/flow/models/fields/mobile-components/__tests__/MobileSelect.test.tsx +70 -0
- package/src/flow/models/topbar/TopbarActionModel.tsx +1 -1
- package/src/flow/utils/__tests__/dateTimeFormat.test.ts +91 -0
- package/src/index.ts +6 -0
- package/src/layout-manager/LayoutContentRoute.tsx +90 -0
- package/src/layout-manager/LayoutManager.tsx +185 -0
- package/src/layout-manager/LayoutRoute.tsx +138 -0
- package/src/layout-manager/__tests__/LayoutManager.test.tsx +335 -0
- package/src/layout-manager/__tests__/LayoutRoute.test.tsx +473 -0
- package/src/layout-manager/index.ts +14 -0
- package/src/layout-manager/types.ts +22 -0
- package/src/layout-manager/utils.ts +37 -0
- package/src/nocobase-buildin-plugin/index.tsx +69 -67
- package/src/nocobase-buildin-plugin/plugins/LocalePlugin.ts +1 -0
- package/src/settings-center/index.ts +1 -1
- package/src/settings-center/plugin-manager/BulkEnableButton.tsx +111 -0
- package/src/settings-center/plugin-manager/PluginCard.tsx +270 -0
- package/src/settings-center/plugin-manager/PluginDetail.tsx +195 -0
- package/src/settings-center/plugin-manager/index.tsx +254 -0
- package/src/settings-center/plugin-manager/types.ts +35 -0
- package/src/settings-center/utils.tsx +8 -1
- package/src/theme/__tests__/globalStyles.test.ts +24 -0
- package/src/theme/globalStyles.ts +10 -0
- package/src/utils/globalDeps.ts +2 -0
- package/es/collection-manager/interfaces/linkTo.d.ts +0 -90
- package/es/collection-manager/interfaces/o2o.d.ts +0 -621
- package/es/collection-manager/interfaces/properties/operators.d.ts +0 -294
- package/es/collection-manager/interfaces/subTable.d.ts +0 -172
- package/src/collection-manager/interfaces/linkTo.ts +0 -120
- package/src/collection-manager/interfaces/o2o.tsx +0 -561
- package/src/collection-manager/interfaces/subTable.ts +0 -218
- package/src/settings-center/PluginManagerPage.tsx +0 -162
|
@@ -7,161 +7,11 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
import { getAdminLayoutModel, AdminLayoutModel } from '..';
|
|
13
|
-
import { useApp } from '../../hooks/useApp';
|
|
14
|
-
import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
|
15
|
-
import { NocoBaseDesktopRouteType } from '../../flow-compat';
|
|
16
|
-
import {
|
|
17
|
-
findFirstV2LandingRoute,
|
|
18
|
-
resolveAdminRouteRuntimeTarget,
|
|
19
|
-
toRouterNavigationPath,
|
|
20
|
-
} from '../admin-shell/admin-layout/resolveAdminRouteRuntimeTarget';
|
|
10
|
+
import React, { type FC } from 'react';
|
|
11
|
+
import { LayoutRoute } from '../../layout-manager/LayoutRoute';
|
|
21
12
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
const app = useApp();
|
|
25
|
-
const navigate = useNavigate();
|
|
26
|
-
const location = useLocation();
|
|
27
|
-
const params = useParams();
|
|
28
|
-
const [ready, setReady] = useState(false);
|
|
29
|
-
const replaceTriggeredRef = useRef(false);
|
|
30
|
-
const routeRepository = flowEngine.context.routeRepository;
|
|
31
|
-
const isAdminRoot = useMemo(() => {
|
|
32
|
-
const pathname = toRouterNavigationPath(location.pathname, app.router.getBasename());
|
|
33
|
-
return pathname === '/admin';
|
|
34
|
-
}, [app, location.pathname]);
|
|
35
|
-
|
|
36
|
-
useEffect(() => {
|
|
37
|
-
replaceTriggeredRef.current = false;
|
|
38
|
-
}, [location.pathname, location.search, location.hash, params.name]);
|
|
39
|
-
|
|
40
|
-
useEffect(() => {
|
|
41
|
-
let active = true;
|
|
42
|
-
|
|
43
|
-
const run = async () => {
|
|
44
|
-
setReady(false);
|
|
45
|
-
|
|
46
|
-
if (!isAdminRoot && !params.name) {
|
|
47
|
-
if (active) {
|
|
48
|
-
setReady(true);
|
|
49
|
-
}
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (!routeRepository?.isAccessibleLoaded?.()) {
|
|
54
|
-
try {
|
|
55
|
-
await routeRepository?.ensureAccessibleLoaded?.();
|
|
56
|
-
} catch (_error) {
|
|
57
|
-
if (active) {
|
|
58
|
-
setReady(true);
|
|
59
|
-
}
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (!active || replaceTriggeredRef.current) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (params.name) {
|
|
69
|
-
const currentRoute = routeRepository?.getRouteBySchemaUid?.(params.name);
|
|
70
|
-
if (currentRoute?.type === NocoBaseDesktopRouteType.page) {
|
|
71
|
-
const target = resolveAdminRouteRuntimeTarget({
|
|
72
|
-
app,
|
|
73
|
-
route: currentRoute,
|
|
74
|
-
location: {
|
|
75
|
-
pathname: window.location.pathname,
|
|
76
|
-
search: window.location.search,
|
|
77
|
-
hash: window.location.hash,
|
|
78
|
-
},
|
|
79
|
-
preserveLocationState: true,
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
if (target.navigationMode === 'document' && target.runtimePath) {
|
|
83
|
-
replaceTriggeredRef.current = true;
|
|
84
|
-
window.location.replace(target.runtimePath);
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (active) {
|
|
90
|
-
setReady(true);
|
|
91
|
-
}
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const firstAccessibleRoute = findFirstV2LandingRoute(routeRepository?.listAccessible?.() || []);
|
|
96
|
-
if (!firstAccessibleRoute) {
|
|
97
|
-
if (active) {
|
|
98
|
-
setReady(true);
|
|
99
|
-
}
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const target = resolveAdminRouteRuntimeTarget({
|
|
104
|
-
app,
|
|
105
|
-
route: firstAccessibleRoute,
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
if (!target.runtimePath) {
|
|
109
|
-
if (active) {
|
|
110
|
-
setReady(true);
|
|
111
|
-
}
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
replaceTriggeredRef.current = true;
|
|
116
|
-
if (target.navigationMode === 'document') {
|
|
117
|
-
window.location.replace(target.runtimePath);
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
navigate(toRouterNavigationPath(target.runtimePath, app.router.getBasename()), { replace: true });
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
void run();
|
|
125
|
-
|
|
126
|
-
return () => {
|
|
127
|
-
active = false;
|
|
128
|
-
};
|
|
129
|
-
}, [
|
|
130
|
-
app,
|
|
131
|
-
flowEngine,
|
|
132
|
-
isAdminRoot,
|
|
133
|
-
location.hash,
|
|
134
|
-
location.pathname,
|
|
135
|
-
location.search,
|
|
136
|
-
navigate,
|
|
137
|
-
params.name,
|
|
138
|
-
routeRepository,
|
|
139
|
-
]);
|
|
140
|
-
|
|
141
|
-
if (!ready) {
|
|
142
|
-
return null;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return <>{children}</>;
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const AdminLayout: FC = (props) => {
|
|
149
|
-
const flowEngine = useFlowEngine();
|
|
150
|
-
const model = getAdminLayoutModel(flowEngine, {
|
|
151
|
-
create: true,
|
|
152
|
-
props,
|
|
153
|
-
use: AdminLayoutModel,
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
if (!model) {
|
|
157
|
-
throw new Error('[NocoBase] Failed to create admin-layout-model.');
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return (
|
|
161
|
-
<AdminLayoutEntryGuard>
|
|
162
|
-
<FlowModelRenderer model={model} />
|
|
163
|
-
</AdminLayoutEntryGuard>
|
|
164
|
-
);
|
|
13
|
+
const AdminLayout: FC = () => {
|
|
14
|
+
return <LayoutRoute layoutRouteName="admin" />;
|
|
165
15
|
};
|
|
166
16
|
|
|
167
17
|
export default AdminLayout;
|
|
@@ -13,14 +13,24 @@ import { FilterGroup, LinkageFilterItem } from './filter';
|
|
|
13
13
|
import { evaluateConditions, FilterGroupType, removeInvalidFilterItems } from '@nocobase/utils/client';
|
|
14
14
|
|
|
15
15
|
export const ConditionBuilder = observer(
|
|
16
|
-
(props: {
|
|
16
|
+
(props: {
|
|
17
|
+
value: FilterGroupType;
|
|
18
|
+
onChange: (value: FilterGroupType) => void;
|
|
19
|
+
extraMetaTree?: MetaTreeNode[];
|
|
20
|
+
maxAssociationFieldDepth?: number;
|
|
21
|
+
}) => {
|
|
17
22
|
const ctx = useFlowContext();
|
|
18
23
|
|
|
19
24
|
return (
|
|
20
25
|
<FilterGroup
|
|
21
26
|
value={props.value || { logic: '$and', items: [] }}
|
|
22
27
|
FilterItem={(itemProps) => (
|
|
23
|
-
<LinkageFilterItem
|
|
28
|
+
<LinkageFilterItem
|
|
29
|
+
model={ctx.model}
|
|
30
|
+
value={itemProps.value}
|
|
31
|
+
extraMetaTree={props.extraMetaTree}
|
|
32
|
+
maxAssociationFieldDepth={props.maxAssociationFieldDepth}
|
|
33
|
+
/>
|
|
24
34
|
)}
|
|
25
35
|
onChange={props.onChange}
|
|
26
36
|
/>
|
|
@@ -24,7 +24,7 @@ import type { CascaderProps, CollapseProps } from 'antd';
|
|
|
24
24
|
import React from 'react';
|
|
25
25
|
import { ConditionBuilder } from './ConditionBuilder';
|
|
26
26
|
import { FieldAssignValueInput } from './FieldAssignValueInput';
|
|
27
|
-
import type
|
|
27
|
+
import { buildFieldAssignCascaderOptionsFromCollection, type FieldAssignCascaderOption } from './fieldAssignOptions';
|
|
28
28
|
import { isRunJSValue, isVariableExpression, type MetaTreeNode } from '@nocobase/flow-engine';
|
|
29
29
|
import { isToManyAssociationField } from '../internal/utils/modelUtils';
|
|
30
30
|
|
|
@@ -36,6 +36,7 @@ type CollectionFieldLike = {
|
|
|
36
36
|
type?: unknown;
|
|
37
37
|
interface?: unknown;
|
|
38
38
|
uiSchema?: unknown;
|
|
39
|
+
target?: unknown;
|
|
39
40
|
targetKey?: unknown;
|
|
40
41
|
targetCollectionTitleFieldName?: unknown;
|
|
41
42
|
targetCollection?: any;
|
|
@@ -105,6 +106,7 @@ export interface FieldAssignRulesEditorProps {
|
|
|
105
106
|
onSyncAssociationTitleField?: (params: SyncAssociationTitleFieldParams) => Promise<void> | void;
|
|
106
107
|
/** 在日期字段下启用“日期变量替换 Constant 位”。 */
|
|
107
108
|
enableDateVariableAsConstant?: boolean;
|
|
109
|
+
maxAssociationFieldDepth?: number;
|
|
108
110
|
}
|
|
109
111
|
|
|
110
112
|
export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (props) => {
|
|
@@ -123,9 +125,10 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
123
125
|
isTitleFieldCandidate,
|
|
124
126
|
onSyncAssociationTitleField,
|
|
125
127
|
enableDateVariableAsConstant = false,
|
|
128
|
+
maxAssociationFieldDepth = 2,
|
|
126
129
|
} = props;
|
|
127
130
|
|
|
128
|
-
const value = Array.isArray(rawValue) ? rawValue : [];
|
|
131
|
+
const value = React.useMemo(() => (Array.isArray(rawValue) ? rawValue : []), [rawValue]);
|
|
129
132
|
const [cascaderOptions, setCascaderOptions] = React.useState<FieldAssignCascaderOption[]>(() =>
|
|
130
133
|
Array.isArray(fieldOptions) ? (fieldOptions as FieldAssignCascaderOption[]) : [],
|
|
131
134
|
);
|
|
@@ -171,6 +174,19 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
171
174
|
}
|
|
172
175
|
}, [getRuleKey, syncingRuleKey, value]);
|
|
173
176
|
|
|
177
|
+
const parseTargetPathToSegments = React.useCallback((targetPath?: string): string[] => {
|
|
178
|
+
const raw = String(targetPath || '');
|
|
179
|
+
if (!raw) return [];
|
|
180
|
+
return raw
|
|
181
|
+
.split('.')
|
|
182
|
+
.map((s) => s.trim())
|
|
183
|
+
.filter(Boolean);
|
|
184
|
+
}, []);
|
|
185
|
+
|
|
186
|
+
const isAssociationFieldLike = React.useCallback((field?: CollectionFieldLike | null) => {
|
|
187
|
+
return !!(field?.isAssociationField?.() || field?.target || field?.targetCollection);
|
|
188
|
+
}, []);
|
|
189
|
+
|
|
174
190
|
const buildCollectionMetaTreeNodes = React.useCallback(
|
|
175
191
|
(collection: any, basePaths: string[], visited: Set<any>): MetaTreeNode[] => {
|
|
176
192
|
if (!collection?.getFields) return [];
|
|
@@ -199,7 +215,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
199
215
|
paths: [...basePaths, name],
|
|
200
216
|
};
|
|
201
217
|
|
|
202
|
-
const isAssoc =
|
|
218
|
+
const isAssoc = isAssociationFieldLike(f);
|
|
203
219
|
const isToMany = isToManyAssociationField(f);
|
|
204
220
|
if (isAssoc && !isToMany && f.targetCollection) {
|
|
205
221
|
node.children = async () =>
|
|
@@ -211,7 +227,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
211
227
|
|
|
212
228
|
return nodes;
|
|
213
229
|
},
|
|
214
|
-
[t],
|
|
230
|
+
[isAssociationFieldLike, t],
|
|
215
231
|
);
|
|
216
232
|
|
|
217
233
|
const buildItemMetaTree = React.useCallback(
|
|
@@ -226,7 +242,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
226
242
|
for (let i = 0; i < segs.length; i++) {
|
|
227
243
|
const seg = segs[i] as string;
|
|
228
244
|
const field = current?.getField?.(seg);
|
|
229
|
-
if (!field
|
|
245
|
+
if (!isAssociationFieldLike(field)) break;
|
|
230
246
|
const toMany = isToManyAssociationField(field);
|
|
231
247
|
const nextCollection = field?.targetCollection;
|
|
232
248
|
if (!nextCollection) break;
|
|
@@ -291,7 +307,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
291
307
|
|
|
292
308
|
return [buildObjectNode(levels.length - 1, ['item'], 'item', 'Current item')];
|
|
293
309
|
},
|
|
294
|
-
[buildCollectionMetaTreeNodes, rootCollection, t],
|
|
310
|
+
[buildCollectionMetaTreeNodes, isAssociationFieldLike, parseTargetPathToSegments, rootCollection, t],
|
|
295
311
|
);
|
|
296
312
|
|
|
297
313
|
const patchItem = (index: number, patch: Partial<FieldAssignRuleItem>) => {
|
|
@@ -381,15 +397,6 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
381
397
|
[t],
|
|
382
398
|
);
|
|
383
399
|
|
|
384
|
-
const parseTargetPathToSegments = React.useCallback((targetPath?: string): string[] => {
|
|
385
|
-
const raw = String(targetPath || '');
|
|
386
|
-
if (!raw) return [];
|
|
387
|
-
return raw
|
|
388
|
-
.split('.')
|
|
389
|
-
.map((s) => s.trim())
|
|
390
|
-
.filter(Boolean);
|
|
391
|
-
}, []);
|
|
392
|
-
|
|
393
400
|
const getFieldLabel = (targetPath?: string) => {
|
|
394
401
|
const segs = parseTargetPathToSegments(targetPath);
|
|
395
402
|
if (!segs.length) return undefined;
|
|
@@ -413,7 +420,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
413
420
|
: seg,
|
|
414
421
|
),
|
|
415
422
|
);
|
|
416
|
-
if (field
|
|
423
|
+
if (isAssociationFieldLike(field as CollectionFieldLike) && field?.targetCollection) {
|
|
417
424
|
collection = field.targetCollection;
|
|
418
425
|
}
|
|
419
426
|
}
|
|
@@ -435,7 +442,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
435
442
|
|
|
436
443
|
const isLast = i === segs.length - 1;
|
|
437
444
|
if (isLast) {
|
|
438
|
-
if (!field
|
|
445
|
+
if (!isAssociationFieldLike(field) || !field?.targetCollection) return null;
|
|
439
446
|
|
|
440
447
|
const targetCollection = field.targetCollection;
|
|
441
448
|
const targetFields =
|
|
@@ -502,7 +509,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
502
509
|
};
|
|
503
510
|
}
|
|
504
511
|
|
|
505
|
-
if (!field
|
|
512
|
+
if (!isAssociationFieldLike(field) || !field?.targetCollection) {
|
|
506
513
|
return null;
|
|
507
514
|
}
|
|
508
515
|
collection = field.targetCollection;
|
|
@@ -510,7 +517,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
510
517
|
|
|
511
518
|
return null;
|
|
512
519
|
},
|
|
513
|
-
[isTitleFieldCandidate, parseTargetPathToSegments, rootCollection, t],
|
|
520
|
+
[isAssociationFieldLike, isTitleFieldCandidate, parseTargetPathToSegments, rootCollection, t],
|
|
514
521
|
);
|
|
515
522
|
|
|
516
523
|
const resolveTargetCollectionBySegments = React.useCallback(
|
|
@@ -519,42 +526,24 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
519
526
|
let collection = rootCollection;
|
|
520
527
|
for (const seg of segments) {
|
|
521
528
|
const field = collection?.getField?.(seg);
|
|
522
|
-
if (!field
|
|
529
|
+
if (!isAssociationFieldLike(field) || !field?.targetCollection) {
|
|
523
530
|
return null;
|
|
524
531
|
}
|
|
525
532
|
collection = field.targetCollection;
|
|
526
533
|
}
|
|
527
534
|
return collection || null;
|
|
528
535
|
},
|
|
529
|
-
[rootCollection],
|
|
536
|
+
[isAssociationFieldLike, rootCollection],
|
|
530
537
|
);
|
|
531
538
|
|
|
532
539
|
const buildChildrenFromCollection = React.useCallback(
|
|
533
|
-
(collection: any): FieldAssignCascaderOption[] => {
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
const f = rawField as CollectionFieldLike;
|
|
539
|
-
const fieldInterface = typeof f.interface === 'string' ? f.interface : undefined;
|
|
540
|
-
if (!fieldInterface) continue;
|
|
541
|
-
if (fieldInterface === 'formula') continue;
|
|
542
|
-
|
|
543
|
-
const name = String(f.name || '');
|
|
544
|
-
if (!name) continue;
|
|
545
|
-
|
|
546
|
-
const title = t(typeof f.title === 'string' ? f.title : name);
|
|
547
|
-
const isAssoc = !!f.isAssociationField?.();
|
|
548
|
-
const hasTarget = !!f.targetCollection;
|
|
549
|
-
out.push({
|
|
550
|
-
label: title,
|
|
551
|
-
value: name,
|
|
552
|
-
isLeaf: !(isAssoc && hasTarget),
|
|
553
|
-
});
|
|
554
|
-
}
|
|
555
|
-
return out;
|
|
540
|
+
(collection: any, associationDepth: number): FieldAssignCascaderOption[] => {
|
|
541
|
+
return buildFieldAssignCascaderOptionsFromCollection(collection, t, {
|
|
542
|
+
associationDepth,
|
|
543
|
+
maxAssociationFieldDepth,
|
|
544
|
+
});
|
|
556
545
|
},
|
|
557
|
-
[t],
|
|
546
|
+
[maxAssociationFieldDepth, t],
|
|
558
547
|
);
|
|
559
548
|
|
|
560
549
|
const loadCascaderData = React.useCallback<NonNullable<CascaderProps<FieldAssignCascaderOption>['loadData']>>(
|
|
@@ -573,7 +562,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
573
562
|
return;
|
|
574
563
|
}
|
|
575
564
|
|
|
576
|
-
const children = buildChildrenFromCollection(targetCollection);
|
|
565
|
+
const children = buildChildrenFromCollection(targetCollection, segments.length);
|
|
577
566
|
if (!children.length) {
|
|
578
567
|
target.isLeaf = true;
|
|
579
568
|
} else {
|
|
@@ -889,6 +878,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
889
878
|
value={item.value}
|
|
890
879
|
onChange={(v) => patchItem(index, { value: v })}
|
|
891
880
|
extraMetaTree={extraMetaTree}
|
|
881
|
+
maxAssociationFieldDepth={maxAssociationFieldDepth}
|
|
892
882
|
{...(getValueInputProps?.(item, index) || {})}
|
|
893
883
|
enableDateVariableAsConstant={enableDateVariableAsConstant}
|
|
894
884
|
associationFieldNamesOverride={
|
|
@@ -959,6 +949,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
959
949
|
value={item.condition || { logic: '$and', items: [] }}
|
|
960
950
|
onChange={(condition) => patchItem(index, { condition })}
|
|
961
951
|
extraMetaTree={extraMetaTree}
|
|
952
|
+
maxAssociationFieldDepth={2}
|
|
962
953
|
/>
|
|
963
954
|
</div>
|
|
964
955
|
)}
|
|
@@ -40,6 +40,7 @@ import { resolveOperatorComponent } from '../internal/utils/operatorSchemaHelper
|
|
|
40
40
|
import { InputFieldModel } from '../models/fields/InputFieldModel';
|
|
41
41
|
import { normalizeFilterValueByOperator } from '../models/blocks/filter-form/valueNormalization';
|
|
42
42
|
import { FieldAssignExactDatePicker, type ExactDatePickerMode } from './FieldAssignExactDatePicker';
|
|
43
|
+
import { limitAssociationMetaTree } from './filter/metaTreeAssociationDepth';
|
|
43
44
|
|
|
44
45
|
const DATE_FIELD_INTERFACES = new Set(['date', 'datetime', 'datetimeNoTz', 'createdAt', 'updatedAt', 'unixTimestamp']);
|
|
45
46
|
|
|
@@ -340,6 +341,7 @@ interface Props {
|
|
|
340
341
|
* 默认 false,保持历史行为。
|
|
341
342
|
*/
|
|
342
343
|
enableDateVariableAsConstant?: boolean;
|
|
344
|
+
maxAssociationFieldDepth?: number;
|
|
343
345
|
}
|
|
344
346
|
|
|
345
347
|
type ResolvedFieldContext = {
|
|
@@ -718,6 +720,7 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
718
720
|
preferFormItemFieldModel,
|
|
719
721
|
associationFieldNamesOverride,
|
|
720
722
|
enableDateVariableAsConstant = false,
|
|
723
|
+
maxAssociationFieldDepth = 2,
|
|
721
724
|
}) => {
|
|
722
725
|
const flowCtx = useFlowContext<FlowModelContext>();
|
|
723
726
|
const normalizeEventValue = React.useCallback((eventOrValue: unknown) => {
|
|
@@ -859,7 +862,7 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
859
862
|
fieldName,
|
|
860
863
|
collectionField: nested.collectionField || null,
|
|
861
864
|
};
|
|
862
|
-
}, [flowCtx
|
|
865
|
+
}, [flowCtx, itemModel, resolveNestedAssociationField, targetPath]);
|
|
863
866
|
|
|
864
867
|
const { collection, dataSource, blockModel, fieldPath, fieldName, collectionField: cf } = resolved;
|
|
865
868
|
const itemCollectionField = (resolved?.itemModel as any)?.context?.collectionField;
|
|
@@ -1232,7 +1235,7 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1232
1235
|
);
|
|
1233
1236
|
};
|
|
1234
1237
|
return C;
|
|
1235
|
-
}, [placeholder, tempRoot, coerceEmptyValueForRenderer, normalizeEventValue]);
|
|
1238
|
+
}, [placeholder, tempRoot, coerceEmptyValueForRenderer, normalizeEventValue, operator]);
|
|
1236
1239
|
|
|
1237
1240
|
const DateVariableConstantEditor = React.useMemo(() => {
|
|
1238
1241
|
const C: React.FC<any> = (inputProps) => {
|
|
@@ -1408,6 +1411,7 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1408
1411
|
const extra = extraMetaTreeRef.current;
|
|
1409
1412
|
const extraTree = Array.isArray(extra) ? extra : [];
|
|
1410
1413
|
const mergedBase = mergeItemMetaTreeForAssignValue(base as MetaTreeNode[], extraTree as MetaTreeNode[]);
|
|
1414
|
+
const limitedBase = limitAssociationMetaTree(mergedBase, { maxAssociationDepth: maxAssociationFieldDepth });
|
|
1411
1415
|
return [
|
|
1412
1416
|
{
|
|
1413
1417
|
title: tExpr('Constant'),
|
|
@@ -1418,10 +1422,10 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1418
1422
|
},
|
|
1419
1423
|
{ title: tExpr('Null'), name: 'null', type: 'object', paths: ['null'], render: NullComponent },
|
|
1420
1424
|
{ title: tExpr('RunJS'), name: 'runjs', type: 'object', paths: ['runjs'], render: RunJSComponent },
|
|
1421
|
-
...
|
|
1425
|
+
...limitedBase,
|
|
1422
1426
|
];
|
|
1423
1427
|
};
|
|
1424
|
-
}, [flowCtx, ConstantEditor, NullComponent, RunJSComponent]);
|
|
1428
|
+
}, [flowCtx, ConstantEditor, NullComponent, RunJSComponent, maxAssociationFieldDepth]);
|
|
1425
1429
|
|
|
1426
1430
|
const displayValue = React.useMemo(() => {
|
|
1427
1431
|
if (!useDateVariableConstant) {
|
|
@@ -7,15 +7,18 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { useFlowEngine } from '@nocobase/flow-engine';
|
|
10
|
+
import { type FlowEngine, useFlowContext, useFlowEngine } from '@nocobase/flow-engine';
|
|
11
11
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
12
12
|
import { deviceType } from 'react-device-detect';
|
|
13
|
-
import { useAdminLayoutRoutePage } from '../admin-shell/useAdminLayoutRoutePage';
|
|
14
13
|
import { useParams } from 'react-router-dom';
|
|
15
14
|
import { useApp } from '../../hooks/useApp';
|
|
16
15
|
import { NocoBaseDesktopRouteType } from '../../flow-compat';
|
|
17
16
|
import { resolveAdminRouteRuntimeTarget } from '../admin-shell/admin-layout/resolveAdminRouteRuntimeTarget';
|
|
17
|
+
import { getAdminLayoutModel, type AdminLayoutModel } from '../admin-shell/admin-layout/AdminLayoutModel';
|
|
18
|
+
import { getLayoutModel, type BaseLayoutModel } from '../admin-shell/BaseLayoutModel';
|
|
19
|
+
import { useLayoutRoutePage } from '../admin-shell/useLayoutRoutePage';
|
|
18
20
|
import { AppNotFound } from '../../components';
|
|
21
|
+
import { useKeepAlive } from '../../components/KeepAlive';
|
|
19
22
|
|
|
20
23
|
type FlowRouteGuardState = {
|
|
21
24
|
pending: boolean;
|
|
@@ -23,8 +26,66 @@ type FlowRouteGuardState = {
|
|
|
23
26
|
notFound: boolean;
|
|
24
27
|
};
|
|
25
28
|
|
|
26
|
-
|
|
29
|
+
export type LegacyPageBehavior = 'redirect' | 'notFound' | 'bridge';
|
|
30
|
+
|
|
31
|
+
export type FlowRouteProps = {
|
|
32
|
+
pageUid?: string;
|
|
33
|
+
active?: boolean;
|
|
34
|
+
getLayoutModel?: (flowEngine: FlowEngine) => BaseLayoutModel | undefined;
|
|
35
|
+
legacyPageBehavior?: LegacyPageBehavior;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const getDefaultAdminLayoutModel = (flowEngine: FlowEngine) =>
|
|
39
|
+
getAdminLayoutModel<AdminLayoutModel>(flowEngine, { required: true });
|
|
40
|
+
|
|
41
|
+
const getDefaultLayoutModel = (flowEngine: FlowEngine, contextLayout?: any) => {
|
|
42
|
+
const layout = contextLayout || flowEngine.context.layout;
|
|
43
|
+
|
|
44
|
+
if (layout?.uid) {
|
|
45
|
+
return getLayoutModel<BaseLayoutModel>(flowEngine, layout.uid, { required: true });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return getDefaultAdminLayoutModel(flowEngine);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const getDefaultLegacyPageBehavior = (flowEngine: FlowEngine, contextLayout?: any): LegacyPageBehavior => {
|
|
52
|
+
const layout = contextLayout || flowEngine.context.layout;
|
|
53
|
+
|
|
54
|
+
if (layout?.routeName && layout.routeName !== 'admin') {
|
|
55
|
+
return 'notFound';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return 'redirect';
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const hasFlowModel = async (flowEngine: FlowEngine, pageUid: string) => {
|
|
62
|
+
if (flowEngine.getModel(pageUid)) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const modelData = await flowEngine.modelRepository?.findOne({ uid: pageUid }).catch(() => null);
|
|
67
|
+
if (modelData?.uid) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const model = await flowEngine.loadModel({ uid: pageUid }).catch(() => null);
|
|
72
|
+
if (model && flowEngine.getModel(pageUid) === model) {
|
|
73
|
+
flowEngine.removeModelWithSubModels(pageUid);
|
|
74
|
+
}
|
|
75
|
+
return !!model;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const BridgeFlowRoute = ({
|
|
79
|
+
pageUid,
|
|
80
|
+
active,
|
|
81
|
+
getLayoutModel,
|
|
82
|
+
}: {
|
|
83
|
+
pageUid: string;
|
|
84
|
+
active?: boolean;
|
|
85
|
+
getLayoutModel: (flowEngine: FlowEngine) => BaseLayoutModel | undefined;
|
|
86
|
+
}) => {
|
|
27
87
|
const flowEngine = useFlowEngine();
|
|
88
|
+
const { active: keepAliveActive } = useKeepAlive();
|
|
28
89
|
const routeRepository = flowEngine.context.routeRepository;
|
|
29
90
|
const refreshDesktopRoutes = React.useMemo(
|
|
30
91
|
() => routeRepository?.refreshAccessible.bind(routeRepository),
|
|
@@ -60,11 +121,13 @@ const BridgeFlowRoute = ({ pageUid }: { pageUid: string }) => {
|
|
|
60
121
|
});
|
|
61
122
|
}, [flowEngine]);
|
|
62
123
|
|
|
63
|
-
|
|
124
|
+
useLayoutRoutePage({
|
|
64
125
|
flowEngine,
|
|
65
126
|
pageUid,
|
|
127
|
+
active: active ?? keepAliveActive,
|
|
66
128
|
refreshDesktopRoutes,
|
|
67
129
|
layoutContentRef,
|
|
130
|
+
getLayoutModel,
|
|
68
131
|
});
|
|
69
132
|
|
|
70
133
|
return <div ref={layoutContentRef} />;
|
|
@@ -84,12 +147,20 @@ const BridgeFlowRoute = ({ pageUid }: { pageUid: string }) => {
|
|
|
84
147
|
* @returns {JSX.Element} 当前动态页面的布局挂载节点
|
|
85
148
|
* @throws {Error} 当缺少 `route.params.name` 时抛出异常
|
|
86
149
|
*/
|
|
87
|
-
const FlowRoute = () => {
|
|
150
|
+
const FlowRoute = (props: FlowRouteProps = {}) => {
|
|
88
151
|
const flowEngine = useFlowEngine();
|
|
152
|
+
const flowContext = useFlowContext<any>();
|
|
153
|
+
const contextLayout = flowContext?.layout;
|
|
154
|
+
const getLayoutModel = useMemo(
|
|
155
|
+
() => props.getLayoutModel || ((engine: FlowEngine) => getDefaultLayoutModel(engine, contextLayout)),
|
|
156
|
+
[contextLayout, props.getLayoutModel],
|
|
157
|
+
);
|
|
158
|
+
const legacyPageBehavior = props.legacyPageBehavior || getDefaultLegacyPageBehavior(flowEngine, contextLayout);
|
|
89
159
|
const app = useApp();
|
|
90
160
|
const routeRepository = flowEngine.context.routeRepository;
|
|
91
161
|
const params = useParams();
|
|
92
|
-
const pageUid = params?.name;
|
|
162
|
+
const pageUid = props.pageUid || params?.name;
|
|
163
|
+
const skipRouteRepositoryCheck = !routeRepository;
|
|
93
164
|
const [guardState, setGuardState] = useState<FlowRouteGuardState>({
|
|
94
165
|
pending: true,
|
|
95
166
|
allowBridge: false,
|
|
@@ -99,7 +170,7 @@ const FlowRoute = () => {
|
|
|
99
170
|
const requestIdRef = useRef(0);
|
|
100
171
|
|
|
101
172
|
if (!pageUid) {
|
|
102
|
-
throw new Error('[NocoBase] FlowRoute requires route.params.name.');
|
|
173
|
+
throw new Error('[NocoBase] FlowRoute requires pageUid or route.params.name.');
|
|
103
174
|
}
|
|
104
175
|
|
|
105
176
|
useEffect(() => {
|
|
@@ -109,7 +180,7 @@ const FlowRoute = () => {
|
|
|
109
180
|
const run = async () => {
|
|
110
181
|
setGuardState({ pending: true, allowBridge: false, notFound: false });
|
|
111
182
|
|
|
112
|
-
if (!routeRepository?.isAccessibleLoaded?.()) {
|
|
183
|
+
if (!skipRouteRepositoryCheck && !routeRepository?.isAccessibleLoaded?.()) {
|
|
113
184
|
try {
|
|
114
185
|
await routeRepository?.ensureAccessibleLoaded?.();
|
|
115
186
|
} catch (_error) {
|
|
@@ -124,8 +195,26 @@ const FlowRoute = () => {
|
|
|
124
195
|
return;
|
|
125
196
|
}
|
|
126
197
|
|
|
127
|
-
const route = routeRepository?.getRouteBySchemaUid?.(pageUid);
|
|
198
|
+
const route = skipRouteRepositoryCheck ? undefined : routeRepository?.getRouteBySchemaUid?.(pageUid);
|
|
199
|
+
if (!route && legacyPageBehavior === 'notFound') {
|
|
200
|
+
const flowModelExists = await hasFlowModel(flowEngine, pageUid);
|
|
201
|
+
if (active && requestId === requestIdRef.current) {
|
|
202
|
+
setGuardState({ pending: false, allowBridge: flowModelExists, notFound: !flowModelExists });
|
|
203
|
+
}
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
128
207
|
if (route?.type === NocoBaseDesktopRouteType.page) {
|
|
208
|
+
if (legacyPageBehavior === 'notFound') {
|
|
209
|
+
setGuardState({ pending: false, allowBridge: false, notFound: true });
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (legacyPageBehavior === 'bridge') {
|
|
214
|
+
setGuardState({ pending: false, allowBridge: true, notFound: false });
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
|
|
129
218
|
const target = resolveAdminRouteRuntimeTarget({
|
|
130
219
|
app,
|
|
131
220
|
route,
|
|
@@ -161,22 +250,23 @@ const FlowRoute = () => {
|
|
|
161
250
|
return () => {
|
|
162
251
|
active = false;
|
|
163
252
|
};
|
|
164
|
-
}, [app, pageUid, routeRepository]);
|
|
253
|
+
}, [app, flowEngine, legacyPageBehavior, pageUid, routeRepository, skipRouteRepositoryCheck]);
|
|
165
254
|
|
|
166
255
|
const content = useMemo(() => {
|
|
167
256
|
if (guardState.pending) {
|
|
168
257
|
return null;
|
|
169
258
|
}
|
|
170
259
|
|
|
260
|
+
if (guardState.notFound) {
|
|
261
|
+
return <AppNotFound />;
|
|
262
|
+
}
|
|
263
|
+
|
|
171
264
|
if (!guardState.allowBridge) {
|
|
172
|
-
if (guardState.notFound) {
|
|
173
|
-
return <AppNotFound />;
|
|
174
|
-
}
|
|
175
265
|
return null;
|
|
176
266
|
}
|
|
177
267
|
|
|
178
|
-
return <BridgeFlowRoute pageUid={pageUid} />;
|
|
179
|
-
}, [guardState.allowBridge, guardState.notFound, guardState.pending, pageUid]);
|
|
268
|
+
return <BridgeFlowRoute pageUid={pageUid} active={props.active} getLayoutModel={getLayoutModel} />;
|
|
269
|
+
}, [getLayoutModel, guardState.allowBridge, guardState.notFound, guardState.pending, pageUid, props.active]);
|
|
180
270
|
|
|
181
271
|
return content;
|
|
182
272
|
};
|