@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
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { describe, expect, it } from 'vitest';
|
|
11
|
+
import { findDeepestLayoutMatch } from '../RouterBridge';
|
|
12
|
+
|
|
13
|
+
describe('RouterBridge', () => {
|
|
14
|
+
it('uses the deepest matched layout route as layout base pathname', () => {
|
|
15
|
+
const match = findDeepestLayoutMatch(
|
|
16
|
+
[{ routeName: 'admin' }, { routeName: 'admin.settings.publicForms' }],
|
|
17
|
+
[
|
|
18
|
+
{ id: 'admin', pathname: '/admin' },
|
|
19
|
+
{ id: 'admin.settings', pathname: '/admin/settings' },
|
|
20
|
+
{ id: 'admin.settings.publicForms', pathname: '/admin/settings/public-forms' },
|
|
21
|
+
{ id: 'admin.settings.publicForms.page.view', pathname: '/admin/settings/public-forms/form-1/view/popup' },
|
|
22
|
+
],
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
expect(match?.pathname).toBe('/admin/settings/public-forms');
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -16,17 +16,9 @@ export interface DialogFormLayoutProps {
|
|
|
16
16
|
title: React.ReactNode;
|
|
17
17
|
/** Form body — typically a `<Form>` wrapping `<Form.Item>` fields. */
|
|
18
18
|
children: React.ReactNode;
|
|
19
|
-
/**
|
|
20
|
-
* Called before the dialog is closed by the Cancel button or the
|
|
21
|
-
* top-right close (X) icon. Use for "discard changes" confirmations.
|
|
22
|
-
*/
|
|
19
|
+
/** Called before the dialog is closed by the Cancel button or the top-right close (X) icon. Use for "discard changes" confirmations. */
|
|
23
20
|
onCancel?: () => void | Promise<void>;
|
|
24
|
-
/**
|
|
25
|
-
* Called when the Submit button is clicked. Caller owns validation
|
|
26
|
-
* + the actual API call; the dialog is closed automatically when
|
|
27
|
-
* `onSubmit` resolves. Throw from `onSubmit` to keep the dialog open
|
|
28
|
-
* (e.g. on a validation error).
|
|
29
|
-
*/
|
|
21
|
+
/** Called when the Submit button is clicked. Caller owns validation + the actual API call; the dialog is closed automatically when `onSubmit` resolves. Throw from `onSubmit` to keep the dialog open (e.g. on a validation error). */
|
|
30
22
|
onSubmit?: () => void | Promise<void>;
|
|
31
23
|
/** Drives the Submit button's loading state. */
|
|
32
24
|
submitting?: boolean;
|
|
@@ -34,30 +26,14 @@ export interface DialogFormLayoutProps {
|
|
|
34
26
|
submitText?: React.ReactNode;
|
|
35
27
|
/** Override the Cancel button label. Defaults to "Cancel". */
|
|
36
28
|
cancelText?: React.ReactNode;
|
|
37
|
-
/**
|
|
38
|
-
* Full override of the footer content. When provided, the default
|
|
39
|
-
* Cancel + Submit buttons are replaced. Useful for forms that need
|
|
40
|
-
* extra actions (e.g. Preview, Save draft).
|
|
41
|
-
*/
|
|
29
|
+
/** Full override of the footer content. When provided, the default Cancel + Submit buttons are replaced. Useful for forms that need extra actions (e.g. Preview, Save draft). */
|
|
42
30
|
footer?: React.ReactNode;
|
|
43
31
|
}
|
|
44
32
|
|
|
45
33
|
/**
|
|
46
|
-
* Standard layout for dialog-hosted forms — the dialog counterpart of
|
|
47
|
-
* `DrawerFormLayout`. Title sits left-aligned in the dialog's native
|
|
48
|
-
* header (no inline close icon — the dialog provides its own X in the
|
|
49
|
-
* top-right when opened with `viewer.dialog({ closable: true, ... })`),
|
|
50
|
-
* the form body fills the middle, and a Cancel + Submit footer sits
|
|
51
|
-
* at the bottom.
|
|
34
|
+
* Standard layout for dialog-hosted forms — the dialog counterpart of `DrawerFormLayout`. Title sits left-aligned in the dialog's native header, the form body fills the middle, and a Cancel + Submit footer sits at the bottom. Neither this layout nor `DrawerFormLayout` renders a close icon — both rely on the caller passing `closable: true` at the `viewer.dialog` / `viewer.drawer` call site to surface antd Modal's native top-right X (Dialog) or antd Drawer's native left-side X (Drawer).
|
|
52
35
|
*
|
|
53
|
-
*
|
|
54
|
-
* `<CloseOutlined>` button next to the title — that's the drawer
|
|
55
|
-
* visual contract (close lives near the title in a side panel). In a
|
|
56
|
-
* centered dialog the native top-right close button is the expected
|
|
57
|
-
* affordance, so a separate layout keeps the visual contract clean.
|
|
58
|
-
*
|
|
59
|
-
* Callers own the `<Form>` instance, validation, and the actual API
|
|
60
|
-
* call. This component only handles the chrome and close behaviour.
|
|
36
|
+
* Callers own the `<Form>` instance, validation, and the actual API call. This component only handles the chrome and close behaviour.
|
|
61
37
|
*
|
|
62
38
|
* Example:
|
|
63
39
|
*
|
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { CloseCircleFilled } from '@ant-design/icons';
|
|
11
|
+
import {
|
|
12
|
+
buildContextSelectorItems,
|
|
13
|
+
useFlowContext,
|
|
14
|
+
type ContextSelectorItem,
|
|
15
|
+
type MetaTreeNode,
|
|
16
|
+
} from '@nocobase/flow-engine';
|
|
17
|
+
import { Button, Cascader, DatePicker, Input, InputNumber, Select, Space, Tag, theme, type CascaderProps } from 'antd';
|
|
18
|
+
import dayjs from 'dayjs';
|
|
19
|
+
import React, { useCallback, useMemo } from 'react';
|
|
20
|
+
import {
|
|
21
|
+
makeFormatVariablePath,
|
|
22
|
+
makeParseVariablePath,
|
|
23
|
+
useFilteredMetaTree,
|
|
24
|
+
type VariableDelimiters,
|
|
25
|
+
} from './VariableInput';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Constant types this input can edit. Subset of v1 `Variable.Input`
|
|
29
|
+
* `useTypedConstant` — drops `'object'` (no v2 JSON editor yet) and `'null'`
|
|
30
|
+
* (handled by the dedicated `nullable` prop).
|
|
31
|
+
*/
|
|
32
|
+
export type TypedConstantType = 'string' | 'number' | 'boolean' | 'date';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* One allowed constant type. Either a bare type name (`'number'`) or a
|
|
36
|
+
* `[type, editorProps]` pair (`['number', { min: 1, max: 65535 }]`) where
|
|
37
|
+
* `editorProps` is forwarded to the antd editor for that type — same
|
|
38
|
+
* shape as v1 `useTypedConstant`.
|
|
39
|
+
*/
|
|
40
|
+
export type TypedConstantSpec = TypedConstantType | [TypedConstantType, Record<string, unknown>];
|
|
41
|
+
|
|
42
|
+
export interface TypedVariableInputProps {
|
|
43
|
+
/**
|
|
44
|
+
* Stored value. A `{{ ... }}` string is treated as a variable reference;
|
|
45
|
+
* anything else is a constant of the inferred type.
|
|
46
|
+
*/
|
|
47
|
+
value?: unknown;
|
|
48
|
+
onChange?: (next: unknown) => void;
|
|
49
|
+
/**
|
|
50
|
+
* Allowed constant types. The `Constant` switcher entry always exposes a
|
|
51
|
+
* typed submenu (matching v1 `Variable.Input`) so users can see what type
|
|
52
|
+
* the constant is, even when only one type is permitted. Default: all four
|
|
53
|
+
* supported types.
|
|
54
|
+
*/
|
|
55
|
+
types?: TypedConstantSpec[];
|
|
56
|
+
/**
|
|
57
|
+
* Restrict the variable picker to specific top-level meta-tree namespaces
|
|
58
|
+
* (e.g. `['$env']`). When omitted, every registered top-level property is
|
|
59
|
+
* exposed — matching `VariableInput`'s default behaviour.
|
|
60
|
+
*/
|
|
61
|
+
namespaces?: string[];
|
|
62
|
+
/** Additional leaves appended to the picker after the namespace-filtered nodes. */
|
|
63
|
+
extraNodes?: MetaTreeNode[];
|
|
64
|
+
/**
|
|
65
|
+
* When true (default), the switcher exposes a `Null` option that resets the
|
|
66
|
+
* value to `null`. When false, the value is constrained to one of the
|
|
67
|
+
* allowed types or a variable reference.
|
|
68
|
+
*/
|
|
69
|
+
nullable?: boolean;
|
|
70
|
+
/** Variable-token delimiters. Default `['{{', '}}']` — see `VariableInput`. */
|
|
71
|
+
delimiters?: VariableDelimiters;
|
|
72
|
+
disabled?: boolean;
|
|
73
|
+
placeholder?: string;
|
|
74
|
+
style?: React.CSSProperties;
|
|
75
|
+
className?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const DEFAULT_TYPES: TypedConstantSpec[] = ['string', 'number', 'boolean', 'date'];
|
|
79
|
+
|
|
80
|
+
const TYPE_LABEL_KEYS: Record<TypedConstantType, string> = {
|
|
81
|
+
string: 'String',
|
|
82
|
+
number: 'Number',
|
|
83
|
+
boolean: 'Boolean',
|
|
84
|
+
date: 'Date',
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
type NormalizedType = { type: TypedConstantType; props: Record<string, unknown> };
|
|
88
|
+
|
|
89
|
+
function normalizeTypes(types: TypedConstantSpec[]): NormalizedType[] {
|
|
90
|
+
return types.map((spec) =>
|
|
91
|
+
Array.isArray(spec) ? { type: spec[0], props: spec[1] ?? {} } : { type: spec, props: {} },
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function defaultValueFor(type: TypedConstantType): unknown {
|
|
96
|
+
switch (type) {
|
|
97
|
+
case 'string':
|
|
98
|
+
return '';
|
|
99
|
+
case 'number':
|
|
100
|
+
return 0;
|
|
101
|
+
case 'boolean':
|
|
102
|
+
return false;
|
|
103
|
+
case 'date': {
|
|
104
|
+
const now = new Date();
|
|
105
|
+
return new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);
|
|
106
|
+
}
|
|
107
|
+
default:
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
type DetectedMode = { mode: 'null' | 'variable' | TypedConstantType; variablePath?: string[] };
|
|
113
|
+
|
|
114
|
+
function detectMode(value: unknown, parseVariablePath: (v?: string) => string[] | undefined): DetectedMode {
|
|
115
|
+
if (value == null) return { mode: 'null' };
|
|
116
|
+
if (typeof value === 'string') {
|
|
117
|
+
const path = parseVariablePath(value);
|
|
118
|
+
if (path && path.length > 0) return { mode: 'variable', variablePath: path };
|
|
119
|
+
return { mode: 'string' };
|
|
120
|
+
}
|
|
121
|
+
if (typeof value === 'number') return { mode: 'number' };
|
|
122
|
+
if (typeof value === 'boolean') return { mode: 'boolean' };
|
|
123
|
+
if (value instanceof Date) return { mode: 'date' };
|
|
124
|
+
return { mode: 'string' };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const NULL_KEY = '__null__';
|
|
128
|
+
const CONST_KEY = '__const__';
|
|
129
|
+
|
|
130
|
+
interface SwitcherOption {
|
|
131
|
+
value: string;
|
|
132
|
+
label: React.ReactNode;
|
|
133
|
+
isLeaf?: boolean;
|
|
134
|
+
children?: SwitcherOption[];
|
|
135
|
+
meta?: MetaTreeNode;
|
|
136
|
+
paths?: string[];
|
|
137
|
+
disabled?: boolean;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function fromContextItem(item: ContextSelectorItem): SwitcherOption {
|
|
141
|
+
return {
|
|
142
|
+
value: item.value,
|
|
143
|
+
label: item.label,
|
|
144
|
+
isLeaf: item.isLeaf,
|
|
145
|
+
meta: item.meta,
|
|
146
|
+
paths: item.paths,
|
|
147
|
+
disabled: item.disabled,
|
|
148
|
+
children: item.children?.map(fromContextItem),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function resolveVariableLabels(path: string[], metaTree: MetaTreeNode[]): string[] {
|
|
153
|
+
const labels: string[] = [];
|
|
154
|
+
let nodes: MetaTreeNode[] | undefined = metaTree;
|
|
155
|
+
for (const segment of path) {
|
|
156
|
+
if (!nodes) break;
|
|
157
|
+
const matched: MetaTreeNode | undefined = nodes.find((node) => node.name === segment);
|
|
158
|
+
if (!matched) {
|
|
159
|
+
labels.push(segment);
|
|
160
|
+
nodes = undefined;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
labels.push(typeof matched.title === 'string' && matched.title ? matched.title : matched.name);
|
|
164
|
+
nodes = Array.isArray(matched.children) ? matched.children : undefined;
|
|
165
|
+
}
|
|
166
|
+
return labels;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function renderConstantEditor(
|
|
170
|
+
type: TypedConstantType,
|
|
171
|
+
value: unknown,
|
|
172
|
+
onChange: ((next: unknown) => void) | undefined,
|
|
173
|
+
options: {
|
|
174
|
+
typedProps: Record<string, unknown>;
|
|
175
|
+
disabled?: boolean;
|
|
176
|
+
placeholder?: string;
|
|
177
|
+
t: (text: string) => string;
|
|
178
|
+
},
|
|
179
|
+
): React.ReactNode {
|
|
180
|
+
const { typedProps, disabled, placeholder, t } = options;
|
|
181
|
+
switch (type) {
|
|
182
|
+
case 'string':
|
|
183
|
+
return (
|
|
184
|
+
<Input
|
|
185
|
+
value={typeof value === 'string' ? value : ''}
|
|
186
|
+
onChange={(ev) => onChange?.(ev.target.value)}
|
|
187
|
+
disabled={disabled}
|
|
188
|
+
placeholder={placeholder}
|
|
189
|
+
{...typedProps}
|
|
190
|
+
/>
|
|
191
|
+
);
|
|
192
|
+
case 'number':
|
|
193
|
+
return (
|
|
194
|
+
<InputNumber
|
|
195
|
+
value={typeof value === 'number' ? value : null}
|
|
196
|
+
onChange={(next) => onChange?.(next)}
|
|
197
|
+
disabled={disabled}
|
|
198
|
+
placeholder={placeholder}
|
|
199
|
+
style={{ width: '100%' }}
|
|
200
|
+
{...typedProps}
|
|
201
|
+
/>
|
|
202
|
+
);
|
|
203
|
+
case 'boolean':
|
|
204
|
+
return (
|
|
205
|
+
<Select
|
|
206
|
+
value={typeof value === 'boolean' ? value : undefined}
|
|
207
|
+
onChange={(next) => onChange?.(next)}
|
|
208
|
+
disabled={disabled}
|
|
209
|
+
placeholder={placeholder ?? t('Select')}
|
|
210
|
+
options={[
|
|
211
|
+
{ value: true, label: t('True') },
|
|
212
|
+
{ value: false, label: t('False') },
|
|
213
|
+
]}
|
|
214
|
+
style={{ width: '100%' }}
|
|
215
|
+
{...typedProps}
|
|
216
|
+
/>
|
|
217
|
+
);
|
|
218
|
+
case 'date': {
|
|
219
|
+
const parsed = value instanceof Date ? dayjs(value) : null;
|
|
220
|
+
return (
|
|
221
|
+
<DatePicker
|
|
222
|
+
value={parsed}
|
|
223
|
+
onChange={(next) => onChange?.(next ? next.toDate() : null)}
|
|
224
|
+
disabled={disabled}
|
|
225
|
+
showTime
|
|
226
|
+
allowClear={false}
|
|
227
|
+
style={{ width: '100%' }}
|
|
228
|
+
{...typedProps}
|
|
229
|
+
/>
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
default:
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Constant-or-variable input. Port of v1 `Variable.Input` typed-constant
|
|
239
|
+
* Cascader pattern (the `[Null | Constant<type> | Variable<…namespaces>]`
|
|
240
|
+
* switcher). Use this when a field can accept either a typed literal
|
|
241
|
+
* (number, boolean, date, string) or a variable reference like
|
|
242
|
+
* `{{ $env.SMTP_PORT }}` — see `plugin-notification-email`'s port / secure
|
|
243
|
+
* fields for the canonical example.
|
|
244
|
+
*
|
|
245
|
+
* Pure literal fields should keep using the antd primitive
|
|
246
|
+
* (`InputNumber`, `Select`, `DatePicker`). Pure variable fields should keep
|
|
247
|
+
* using `EnvVariableInput` / `VariableInput`. This component carries the
|
|
248
|
+
* Cascader switcher overhead, so reach for it only when the field
|
|
249
|
+
* genuinely accepts both shapes.
|
|
250
|
+
*/
|
|
251
|
+
export function TypedVariableInput(props: TypedVariableInputProps) {
|
|
252
|
+
const {
|
|
253
|
+
value,
|
|
254
|
+
onChange,
|
|
255
|
+
types = DEFAULT_TYPES,
|
|
256
|
+
namespaces,
|
|
257
|
+
extraNodes,
|
|
258
|
+
nullable = true,
|
|
259
|
+
delimiters,
|
|
260
|
+
disabled,
|
|
261
|
+
placeholder,
|
|
262
|
+
style,
|
|
263
|
+
className,
|
|
264
|
+
} = props;
|
|
265
|
+
const ctx = useFlowContext();
|
|
266
|
+
const t = useCallback((text: string): string => (typeof ctx?.t === 'function' ? ctx.t(text) : text), [ctx]);
|
|
267
|
+
const { token } = theme.useToken();
|
|
268
|
+
|
|
269
|
+
const metaTree = useFilteredMetaTree({ namespaces, extraNodes });
|
|
270
|
+
|
|
271
|
+
const parseVariablePath = useMemo(() => makeParseVariablePath(delimiters), [delimiters]);
|
|
272
|
+
const formatVariablePath = useMemo(() => makeFormatVariablePath(delimiters), [delimiters]);
|
|
273
|
+
|
|
274
|
+
const normalizedTypes = useMemo(() => normalizeTypes(types), [types]);
|
|
275
|
+
const detected = useMemo(() => detectMode(value, parseVariablePath), [value, parseVariablePath]);
|
|
276
|
+
const variableItems = useMemo(() => buildContextSelectorItems(metaTree).map(fromContextItem), [metaTree]);
|
|
277
|
+
|
|
278
|
+
const switcherOptions = useMemo<SwitcherOption[]>(() => {
|
|
279
|
+
const items: SwitcherOption[] = [];
|
|
280
|
+
if (nullable) {
|
|
281
|
+
items.push({ value: NULL_KEY, label: t('Null'), isLeaf: true });
|
|
282
|
+
}
|
|
283
|
+
// Always render Constant with a typed submenu — even when only one type is
|
|
284
|
+
// allowed. Matches v1 `Variable.Input`, where clicking 常量 reveals 数字 /
|
|
285
|
+
// 逻辑值 / etc. so the user can see what type the constant actually is.
|
|
286
|
+
if (normalizedTypes.length > 0) {
|
|
287
|
+
items.push({
|
|
288
|
+
value: CONST_KEY,
|
|
289
|
+
label: t('Constant'),
|
|
290
|
+
children: normalizedTypes.map(({ type }) => ({
|
|
291
|
+
value: type,
|
|
292
|
+
label: t(TYPE_LABEL_KEYS[type]),
|
|
293
|
+
isLeaf: true,
|
|
294
|
+
})),
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
items.push(...variableItems);
|
|
298
|
+
return items;
|
|
299
|
+
}, [nullable, normalizedTypes, variableItems, t]);
|
|
300
|
+
|
|
301
|
+
const onSwitcherChange = useCallback<NonNullable<CascaderProps<SwitcherOption>['onChange']>>(
|
|
302
|
+
(path, selectedOptions) => {
|
|
303
|
+
const head = path?.[0];
|
|
304
|
+
if (head === NULL_KEY) {
|
|
305
|
+
onChange?.(null);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (head === CONST_KEY) {
|
|
309
|
+
// Cascader always emits the second segment now that we render typed
|
|
310
|
+
// children even for single-type configs. Fall back to the first
|
|
311
|
+
// allowed type so picking only the parent still does something
|
|
312
|
+
// sensible (`changeOnSelect` lets this fire).
|
|
313
|
+
const targetType = (path[1] as TypedConstantType | undefined) ?? normalizedTypes[0]?.type;
|
|
314
|
+
if (!targetType) return;
|
|
315
|
+
if (detected.mode === targetType) return;
|
|
316
|
+
onChange?.(defaultValueFor(targetType));
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
const leaf = selectedOptions?.[selectedOptions.length - 1] as SwitcherOption | undefined;
|
|
320
|
+
const meta = leaf?.meta;
|
|
321
|
+
if (!meta) return;
|
|
322
|
+
const formatted = formatVariablePath(meta);
|
|
323
|
+
if (formatted != null) onChange?.(formatted);
|
|
324
|
+
},
|
|
325
|
+
[onChange, normalizedTypes, detected.mode, formatVariablePath],
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
const onClearVariable = useCallback(() => {
|
|
329
|
+
if (nullable) {
|
|
330
|
+
onChange?.(null);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
const first = normalizedTypes[0];
|
|
334
|
+
if (first) onChange?.(defaultValueFor(first.type));
|
|
335
|
+
}, [nullable, normalizedTypes, onChange]);
|
|
336
|
+
|
|
337
|
+
const constantTypeForRendering: TypedConstantType = useMemo(() => {
|
|
338
|
+
const m = detected.mode;
|
|
339
|
+
if (m === 'string' || m === 'number' || m === 'boolean' || m === 'date') return m;
|
|
340
|
+
return normalizedTypes[0]?.type ?? 'string';
|
|
341
|
+
}, [detected.mode, normalizedTypes]);
|
|
342
|
+
|
|
343
|
+
const typedProps = useMemo(
|
|
344
|
+
() => normalizedTypes.find((nt) => nt.type === constantTypeForRendering)?.props ?? {},
|
|
345
|
+
[normalizedTypes, constantTypeForRendering],
|
|
346
|
+
);
|
|
347
|
+
|
|
348
|
+
const isVariable = detected.mode === 'variable';
|
|
349
|
+
const isNull = detected.mode === 'null';
|
|
350
|
+
|
|
351
|
+
const variableLabels = useMemo(
|
|
352
|
+
() => (isVariable && detected.variablePath ? resolveVariableLabels(detected.variablePath, metaTree) : []),
|
|
353
|
+
[isVariable, detected.variablePath, metaTree],
|
|
354
|
+
);
|
|
355
|
+
|
|
356
|
+
return (
|
|
357
|
+
<Space.Compact style={{ display: 'flex', width: '100%', ...style }} className={className}>
|
|
358
|
+
<div style={{ flex: 1, minWidth: 0, overflow: 'hidden' }}>
|
|
359
|
+
{isVariable ? (
|
|
360
|
+
<div
|
|
361
|
+
role="button"
|
|
362
|
+
aria-label="variable-tag"
|
|
363
|
+
style={{
|
|
364
|
+
display: 'flex',
|
|
365
|
+
alignItems: 'center',
|
|
366
|
+
gap: token.marginXXS,
|
|
367
|
+
padding: `0 ${token.paddingSM}px`,
|
|
368
|
+
minHeight: token.controlHeight,
|
|
369
|
+
border: `1px solid ${token.colorBorder}`,
|
|
370
|
+
borderRadius: token.borderRadius,
|
|
371
|
+
borderTopRightRadius: 0,
|
|
372
|
+
borderBottomRightRadius: 0,
|
|
373
|
+
background: disabled ? token.colorBgContainerDisabled : token.colorBgContainer,
|
|
374
|
+
overflow: 'hidden',
|
|
375
|
+
}}
|
|
376
|
+
>
|
|
377
|
+
<Tag
|
|
378
|
+
color="blue"
|
|
379
|
+
style={{
|
|
380
|
+
marginInlineEnd: 0,
|
|
381
|
+
maxWidth: '100%',
|
|
382
|
+
overflow: 'hidden',
|
|
383
|
+
textOverflow: 'ellipsis',
|
|
384
|
+
whiteSpace: 'nowrap',
|
|
385
|
+
}}
|
|
386
|
+
>
|
|
387
|
+
{variableLabels.map((label, index) => (
|
|
388
|
+
<React.Fragment key={`${label}-${index}`}>
|
|
389
|
+
{index ? ' / ' : ''}
|
|
390
|
+
{label}
|
|
391
|
+
</React.Fragment>
|
|
392
|
+
))}
|
|
393
|
+
</Tag>
|
|
394
|
+
{!disabled ? (
|
|
395
|
+
<Button
|
|
396
|
+
type="text"
|
|
397
|
+
size="small"
|
|
398
|
+
aria-label="icon-close"
|
|
399
|
+
onClick={onClearVariable}
|
|
400
|
+
icon={<CloseCircleFilled style={{ color: token.colorTextTertiary }} />}
|
|
401
|
+
/>
|
|
402
|
+
) : null}
|
|
403
|
+
</div>
|
|
404
|
+
) : isNull ? (
|
|
405
|
+
// v1 used the `placeholder` slot (not `value`) so the antd default
|
|
406
|
+
// placeholder colour applies — keeps the field looking visibly
|
|
407
|
+
// empty/inactive rather than holding a real text value.
|
|
408
|
+
<Input placeholder={`<${t('Null')}>`} readOnly disabled={disabled} style={{ width: '100%' }} />
|
|
409
|
+
) : (
|
|
410
|
+
renderConstantEditor(constantTypeForRendering, value, onChange, {
|
|
411
|
+
typedProps,
|
|
412
|
+
disabled,
|
|
413
|
+
placeholder,
|
|
414
|
+
t,
|
|
415
|
+
})
|
|
416
|
+
)}
|
|
417
|
+
</div>
|
|
418
|
+
<Cascader<SwitcherOption>
|
|
419
|
+
options={switcherOptions}
|
|
420
|
+
onChange={onSwitcherChange}
|
|
421
|
+
disabled={disabled}
|
|
422
|
+
changeOnSelect
|
|
423
|
+
>
|
|
424
|
+
<Button
|
|
425
|
+
aria-label="variable-switcher"
|
|
426
|
+
disabled={disabled}
|
|
427
|
+
type={isVariable ? 'primary' : 'default'}
|
|
428
|
+
style={{
|
|
429
|
+
flexShrink: 0,
|
|
430
|
+
fontStyle: 'italic',
|
|
431
|
+
fontFamily: '"New York", "Times New Roman", Times, serif',
|
|
432
|
+
}}
|
|
433
|
+
>
|
|
434
|
+
x
|
|
435
|
+
</Button>
|
|
436
|
+
</Cascader>
|
|
437
|
+
</Space.Compact>
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
export default TypedVariableInput;
|