@nocobase/client-v2 2.2.0-alpha.1 → 2.2.0-alpha.11
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/APIClient.d.ts +1 -3
- package/es/BaseApplication.d.ts +3 -0
- package/es/PluginSettingsManager.d.ts +33 -0
- package/es/RouteRepository.d.ts +29 -6
- package/es/RouterManager.d.ts +15 -0
- package/es/authRedirect.d.ts +1 -0
- package/es/collection-field-interface/CollectionFieldInterface.d.ts +1 -0
- package/es/collection-field-interface/CollectionFieldInterfaceManager.d.ts +1 -0
- package/es/components/category-tabs/SortableCategoryTabs.d.ts +55 -0
- package/es/components/category-tabs/index.d.ts +9 -0
- package/es/components/form/JsonTextArea.d.ts +2 -1
- package/es/components/form/ScanInput/useCodeScanner.d.ts +3 -2
- package/es/components/form/TypedVariableInput.d.ts +31 -5
- package/es/components/form/VariableJsonTextArea.d.ts +19 -0
- package/es/components/form/filter/CollectionFilter.d.ts +2 -0
- package/es/components/form/filter/CollectionFilterItem.d.ts +11 -1
- package/es/components/form/filter/CollectionFilterPanel.d.ts +2 -0
- package/es/components/form/filter/index.d.ts +2 -0
- package/es/components/form/filter/useFilterActionProps.d.ts +2 -0
- package/es/components/form/index.d.ts +1 -0
- package/es/components/index.d.ts +2 -0
- package/es/entry-actions/EntryActionManager.d.ts +24 -0
- package/es/entry-actions/index.d.ts +9 -0
- package/es/flow/actions/afterSuccess.d.ts +8 -1
- package/es/flow/actions/index.d.ts +2 -2
- package/es/flow/actions/linkageRules.d.ts +2 -0
- package/es/flow/admin-shell/BaseLayoutModel.d.ts +6 -0
- package/es/flow/admin-shell/BaseLayoutRouteCoordinator.d.ts +7 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.d.ts +2 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuFlowUtils.d.ts +2 -1
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuModels.d.ts +3 -0
- package/es/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.d.ts +3 -2
- package/es/flow/admin-shell/admin-layout/AdminLayoutSlotModels.d.ts +5 -0
- package/es/flow/admin-shell/admin-layout/AppListRender.d.ts +2 -1
- package/es/flow/admin-shell/admin-layout/AppSwitcherActionPanelModel.d.ts +24 -0
- package/es/flow/admin-shell/admin-layout/index.d.ts +1 -0
- package/es/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.d.ts +6 -0
- package/es/flow/admin-shell/admin-layout/useApplications.d.ts +7 -2
- package/es/flow/components/FieldAssignExactDatePicker.d.ts +1 -0
- package/es/flow/components/FieldAssignRulesEditor.d.ts +3 -1
- package/es/flow/components/FieldAssignValueInput.d.ts +9 -0
- package/es/flow/components/FlowRoute.d.ts +2 -2
- package/es/flow/components/RunJSValueEditor.d.ts +1 -0
- package/es/flow/components/filter/FilterGroup.d.ts +1 -0
- package/es/flow/components/filter/VariableFilterItem.d.ts +6 -1
- package/es/flow/index.d.ts +1 -0
- package/es/flow/internal/registerDeviceTypeContext.d.ts +10 -0
- package/es/flow/models/base/ActionModelCore.d.ts +2 -0
- package/es/flow/models/base/BlockGridModel.d.ts +3 -0
- package/es/flow/models/base/GridModel.d.ts +1 -1
- package/es/flow/models/base/PageModel/PageModel.d.ts +12 -0
- package/es/flow/models/base/PageModel/PageModelTabBar.d.ts +22 -0
- package/es/flow/models/base/PageModel/PageTabModel.d.ts +12 -0
- package/es/flow/models/blocks/filter-form/FilterFormBlockModel.d.ts +5 -0
- package/es/flow/models/blocks/form/FormBlockModel.d.ts +4 -0
- package/es/flow/models/blocks/form/QuickEditFormModel.d.ts +17 -2
- package/es/flow/models/blocks/form/submitHandler.d.ts +1 -1
- package/es/flow/models/blocks/form/value-runtime/rules.d.ts +21 -0
- package/es/flow/models/blocks/form/value-runtime/runtime.d.ts +30 -0
- package/es/flow/models/blocks/form/value-runtime/types.d.ts +2 -2
- package/es/flow/models/blocks/js-block/JSBlock.d.ts +1 -0
- package/es/flow/models/blocks/table/TableActionsColumnModel.d.ts +1 -0
- package/es/flow/models/blocks/table/TableBlockModel.d.ts +1 -0
- package/es/flow/models/blocks/table/TableColumnModel.d.ts +1 -0
- package/es/flow/models/blocks/table/dragSort/dragSortHooks.d.ts +1 -1
- package/es/flow/models/blocks/table/dragSort/dragSortSettings.d.ts +2 -1
- package/es/flow/models/blocks/table/dragSort/dragSortUtils.d.ts +6 -4
- package/es/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.d.ts +2 -0
- package/es/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableColumnModel.d.ts +6 -0
- package/es/flow/models/fields/DateTimeFieldModel/dateLimit.d.ts +15 -7
- package/es/flow/resolveViewParamsToViewList.d.ts +1 -1
- package/es/flow/routeTransientInputArgs.d.ts +14 -0
- package/es/flow/utils/dataScopeRowSnapshot.d.ts +59 -0
- package/es/flow/utils/dateTimeDisplayProps.d.ts +49 -0
- package/es/flow/utils/formValueDeps.d.ts +32 -0
- package/es/flow-compat/FieldValidation.d.ts +2 -1
- package/es/flow-compat/fieldValidationConstants.d.ts +1 -1
- package/es/flow-compat/routeTypes.d.ts +1 -0
- package/es/index.d.ts +8 -1
- package/es/index.mjs +367 -181
- package/es/utils/getRouteRuntimeVersion.d.ts +23 -0
- package/es/utils/index.d.ts +1 -0
- package/es/utils/markdownSanitize.d.ts +11 -0
- package/lib/index.js +367 -181
- package/lib/locale/languageCodes.js +3 -1
- package/package.json +9 -7
- package/src/APIClient.ts +1 -10
- package/src/Application.tsx +4 -0
- package/src/BaseApplication.tsx +13 -6
- package/src/PluginSettingsManager.ts +53 -0
- package/src/RouteRepository.ts +151 -24
- package/src/RouterManager.tsx +142 -1
- package/src/__tests__/PluginSettingsManager.test.ts +13 -0
- package/src/__tests__/RouteRepository.test.ts +239 -0
- package/src/__tests__/RouterManager.test.ts +125 -0
- package/src/__tests__/app.test.tsx +73 -0
- package/src/__tests__/authRedirect.test.ts +17 -0
- package/src/__tests__/browserChecker.test.ts +61 -0
- package/src/__tests__/exports.test.ts +16 -0
- package/src/__tests__/getRouteRuntimeVersion.test.ts +68 -0
- package/src/__tests__/nocobase-buildin-plugin-auth.test.tsx +234 -2
- package/src/__tests__/plugin-manager.test.tsx +44 -2
- package/src/__tests__/settings-center.test.tsx +40 -1
- package/src/authRedirect.ts +38 -0
- package/src/collection-field-interface/CollectionFieldInterface.ts +1 -0
- package/src/collection-field-interface/CollectionFieldInterfaceManager.ts +1 -0
- package/src/collection-manager/field-configure.ts +1 -1
- package/src/collection-manager/field-validation.ts +1 -1
- package/src/collection-manager/interfaces/id.ts +1 -1
- package/src/collection-manager/interfaces/m2m.tsx +2 -2
- package/src/collection-manager/interfaces/m2o.tsx +2 -2
- package/src/collection-manager/interfaces/nanoid.ts +1 -1
- package/src/collection-manager/interfaces/o2m.tsx +2 -2
- package/src/collection-manager/interfaces/obo.tsx +2 -2
- package/src/collection-manager/interfaces/oho.tsx +2 -2
- package/src/collection-manager/interfaces/properties/index.ts +2 -2
- package/src/collection-manager/interfaces/uuid.ts +1 -1
- package/src/components/AppComponents.tsx +19 -3
- package/src/components/README.md +7 -1
- package/src/components/README.zh-CN.md +6 -1
- package/src/components/category-tabs/SortableCategoryTabs.tsx +210 -0
- package/src/components/category-tabs/index.ts +10 -0
- package/src/components/form/JsonTextArea.tsx +25 -11
- package/src/components/form/ScanInput/CodeScanner.tsx +79 -35
- package/src/components/form/ScanInput/__tests__/CodeScanner.test.tsx +101 -0
- package/src/components/form/ScanInput/__tests__/useCodeScanner.test.tsx +284 -11
- package/src/components/form/ScanInput/useCodeScanner.ts +332 -24
- package/src/components/form/TypedVariableInput.tsx +452 -101
- package/src/components/form/VariableJsonTextArea.tsx +175 -0
- package/src/components/form/__tests__/JsonTextArea.test.tsx +43 -0
- package/src/components/form/__tests__/TypedVariableInput.test.tsx +364 -12
- package/src/components/form/__tests__/VariableJsonTextArea.test.tsx +86 -0
- package/src/components/form/filter/CollectionFilter.tsx +4 -0
- package/src/components/form/filter/CollectionFilterItem.tsx +32 -7
- package/src/components/form/filter/CollectionFilterPanel.tsx +4 -0
- package/src/components/form/filter/__tests__/CollectionFilterItem.test.tsx +38 -0
- package/src/components/form/filter/__tests__/useFilterActionProps.test.tsx +95 -0
- package/src/components/form/filter/index.ts +2 -0
- package/src/components/form/filter/useFilterActionProps.ts +37 -6
- package/src/components/form/index.tsx +1 -0
- package/src/components/index.ts +2 -0
- package/src/entry-actions/EntryActionManager.ts +76 -0
- package/src/entry-actions/index.ts +10 -0
- package/src/flow/FlowPage.tsx +38 -3
- package/src/flow/__tests__/FlowPage.test.tsx +201 -27
- package/src/flow/__tests__/FlowRoute.test.tsx +1181 -80
- package/src/flow/__tests__/PluginFlowEngine.test.ts +58 -0
- package/src/flow/__tests__/getKey.test.ts +7 -0
- package/src/flow/__tests__/resolveViewParamsToViewList.test.ts +34 -0
- package/src/flow/actions/__tests__/actionLinkageRules.forkProps.test.ts +115 -0
- package/src/flow/actions/__tests__/afterSuccess.test.ts +73 -0
- package/src/flow/actions/__tests__/dataScopeFilter.test.ts +120 -0
- package/src/flow/actions/__tests__/dataScopeFormValueClear.test.ts +1124 -0
- package/src/flow/actions/__tests__/fieldLinkageRules.scopeDepth.test.ts +150 -1
- package/src/flow/actions/__tests__/linkageAssignField.legacy.test.ts +135 -0
- package/src/flow/actions/__tests__/linkageRules.hiddenSync.restore.test.ts +19 -5
- package/src/flow/actions/__tests__/linkageRules.subFormSetFieldProps.test.ts +92 -0
- package/src/flow/actions/__tests__/linkageRules.tab.test.ts +171 -0
- package/src/flow/actions/__tests__/linkageRulesRefresh.test.ts +7 -3
- package/src/flow/actions/__tests__/openView.defineProps.route.test.tsx +164 -0
- package/src/flow/actions/__tests__/subFormFieldLinkageRules.inputArgs.test.ts +2 -2
- package/src/flow/actions/afterSuccess.tsx +142 -3
- package/src/flow/actions/customVariable.tsx +1 -2
- package/src/flow/actions/dataScopeFilter.ts +20 -1
- package/src/flow/actions/dateTimeFormat.tsx +42 -28
- package/src/flow/actions/index.ts +3 -1
- package/src/flow/actions/linkageRules.tsx +209 -47
- package/src/flow/actions/linkageRulesFormValueRefresh.ts +22 -130
- package/src/flow/actions/linkageRulesRefresh.tsx +2 -6
- package/src/flow/actions/openView.tsx +59 -5
- package/src/flow/actions/runjs.tsx +2 -14
- package/src/flow/actions/validation.tsx +62 -30
- package/src/flow/admin-shell/BaseLayoutModel.tsx +149 -3
- package/src/flow/admin-shell/BaseLayoutRouteCoordinator.ts +187 -42
- package/src/flow/admin-shell/__tests__/AdminLayoutRouteCoordinator.test.ts +1020 -110
- package/src/flow/admin-shell/admin-layout/AdminLayoutComponent.tsx +74 -14
- package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.test.tsx +486 -0
- package/src/flow/admin-shell/admin-layout/AdminLayoutEntryGuard.tsx +64 -8
- package/src/flow/admin-shell/admin-layout/AdminLayoutMenuFlowUtils.ts +5 -3
- package/src/flow/admin-shell/admin-layout/AdminLayoutMenuModels.tsx +61 -9
- package/src/flow/admin-shell/admin-layout/AdminLayoutMenuUtils.tsx +71 -8
- package/src/flow/admin-shell/admin-layout/AdminLayoutModel.tsx +1 -1
- package/src/flow/admin-shell/admin-layout/AdminLayoutSlotModels.tsx +23 -9
- package/src/flow/admin-shell/admin-layout/AppListRender.tsx +13 -2
- package/src/flow/admin-shell/admin-layout/AppSwitcherActionPanelModel.tsx +289 -0
- package/src/flow/admin-shell/admin-layout/HelpLite.tsx +1 -3
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutComponent.test.tsx +435 -0
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutMenuModels.test.ts +99 -0
- package/src/flow/admin-shell/admin-layout/__tests__/AdminLayoutModel.test.tsx +518 -2
- package/src/flow/admin-shell/admin-layout/__tests__/TopbarActionsBar.test.tsx +214 -2
- package/src/flow/admin-shell/admin-layout/index.ts +1 -0
- package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.test.ts +20 -0
- package/src/flow/admin-shell/admin-layout/resolveAdminRouteRuntimeTarget.ts +33 -5
- package/src/flow/admin-shell/admin-layout/useApplications.tsx +81 -12
- package/src/flow/common/Markdown/Display.tsx +14 -3
- package/src/flow/common/Markdown/Edit.tsx +19 -7
- package/src/flow/common/Markdown/style.ts +4 -0
- package/src/flow/components/BlockItemCard.tsx +2 -2
- package/src/flow/components/DefaultValue.tsx +1 -2
- package/src/flow/components/DynamicFlowsIcon.tsx +447 -126
- package/src/flow/components/FieldAssignExactDatePicker.tsx +25 -11
- package/src/flow/components/FieldAssignRulesEditor.tsx +128 -21
- package/src/flow/components/FieldAssignValueInput.tsx +91 -20
- package/src/flow/components/FlowRoute.tsx +256 -53
- package/src/flow/components/RunJSValueEditor.tsx +9 -1
- package/src/flow/components/__tests__/DynamicFlowsIcon.test.tsx +148 -2
- package/src/flow/components/__tests__/FieldAssignRulesEditor.test.tsx +508 -4
- package/src/flow/components/__tests__/FieldAssignValueInput.context.test.tsx +216 -0
- package/src/flow/components/__tests__/fieldAssignOptions.test.ts +151 -3
- package/src/flow/components/code-editor/__tests__/useCodeRunner.test.tsx +2 -17
- package/src/flow/components/code-editor/hooks/useCodeRunner.ts +2 -14
- package/src/flow/components/code-editor/runjsDiagnostics.ts +8 -45
- package/src/flow/components/fieldAssignOptions.ts +155 -27
- package/src/flow/components/filter/FilterGroup.tsx +33 -5
- package/src/flow/components/filter/VariableFilterItem.tsx +158 -10
- package/src/flow/components/filter/__tests__/FilterGroup.test.tsx +45 -0
- package/src/flow/components/filter/__tests__/VariableFilterItem.leftMetaTree.test.tsx +9 -0
- package/src/flow/components/filter/__tests__/VariableFilterItem.test.tsx +70 -1
- package/src/flow/flows/editMarkdownFlow.tsx +1 -1
- package/src/flow/getViewDiffAndUpdateHidden.tsx +1 -0
- package/src/flow/index.ts +4 -1
- package/src/flow/internal/components/Markdown/util.ts +2 -1
- package/src/flow/internal/registerDeviceTypeContext.ts +39 -0
- package/src/flow/internal/utils/operatorSchemaHelper.ts +15 -1
- package/src/flow/models/actions/JSActionModel.tsx +2 -7
- package/src/flow/models/actions/JSCollectionActionModel.tsx +2 -7
- package/src/flow/models/actions/JSItemActionModel.tsx +2 -7
- package/src/flow/models/actions/JSRecordActionModel.tsx +2 -7
- package/src/flow/models/base/ActionModel.tsx +21 -8
- package/src/flow/models/base/ActionModelCore.tsx +11 -4
- package/src/flow/models/base/BlockGridModel.tsx +26 -0
- package/src/flow/models/base/CollectionBlockModel.tsx +6 -2
- package/src/flow/models/base/GridModel.tsx +38 -7
- package/src/flow/models/base/PageModel/PageModel.tsx +387 -50
- package/src/flow/models/base/PageModel/PageModelTabBar.tsx +114 -0
- package/src/flow/models/base/PageModel/PageTabModel.tsx +249 -18
- package/src/flow/models/base/PageModel/__tests__/PageModel.test.ts +817 -13
- package/src/flow/models/base/PageModel/__tests__/PageModelTabBar.module-isolation.test.tsx +130 -0
- package/src/flow/models/base/PageModel/__tests__/PageModelTabBar.test.tsx +118 -0
- package/src/flow/models/base/PageModel/__tests__/PageTabModel.test.ts +1075 -7
- package/src/flow/models/base/__tests__/ActionModel.test.ts +83 -0
- package/src/flow/models/base/__tests__/ActionModelCore.render.test.tsx +37 -0
- package/src/flow/models/base/__tests__/BlockGridModel.selectSceneActivation.test.ts +124 -0
- package/src/flow/models/base/__tests__/CollectionBlockModel.addAppends.test.ts +41 -0
- package/src/flow/models/base/__tests__/GridModel.dragSnapshotContainer.test.ts +239 -1
- package/src/flow/models/base/__tests__/transformRowsToSingleColumn.test.ts +48 -0
- package/src/flow/models/blocks/filter-form/FilterFormBlockModel.tsx +59 -6
- package/src/flow/models/blocks/filter-form/FilterFormItemModel.tsx +27 -12
- package/src/flow/models/blocks/filter-form/FilterFormJSActionModel.tsx +2 -7
- package/src/flow/models/blocks/filter-form/__tests__/FilterFormItemModel.defineChildren.test.ts +36 -0
- package/src/flow/models/blocks/filter-form/__tests__/defaultValues.wiring.test.ts +143 -4
- package/src/flow/models/blocks/filter-form/fields/FilterFormCustomFieldModel.tsx +1 -1
- package/src/flow/models/blocks/filter-manager/flow-actions/__tests__/customizeFilterRender.test.tsx +56 -1
- package/src/flow/models/blocks/form/EditFormModel.tsx +1 -0
- package/src/flow/models/blocks/form/FormActionModel.tsx +1 -1
- package/src/flow/models/blocks/form/FormBlockModel.tsx +7 -0
- package/src/flow/models/blocks/form/JSFormActionModel.tsx +2 -7
- package/src/flow/models/blocks/form/QuickEditFormModel.tsx +189 -36
- package/src/flow/models/blocks/form/__tests__/FormBlockModel.test.tsx +17 -0
- package/src/flow/models/blocks/form/__tests__/QuickEditFormModel.quickEdit.test.ts +350 -2
- package/src/flow/models/blocks/form/__tests__/submitHandler.test.ts +54 -1
- package/src/flow/models/blocks/form/submitHandler.ts +17 -3
- package/src/flow/models/blocks/form/value-runtime/__tests__/runtime.test.ts +940 -75
- package/src/flow/models/blocks/form/value-runtime/rules.ts +445 -13
- package/src/flow/models/blocks/form/value-runtime/runtime.ts +348 -13
- package/src/flow/models/blocks/form/value-runtime/types.ts +2 -2
- package/src/flow/models/blocks/js-block/JSBlock.tsx +225 -9
- package/src/flow/models/blocks/js-block/__tests__/JSBlockModel.test.tsx +150 -0
- package/src/flow/models/blocks/table/JSColumnModel.tsx +1 -9
- package/src/flow/models/blocks/table/TableActionsColumnModel.tsx +38 -14
- package/src/flow/models/blocks/table/TableBlockModel.tsx +42 -19
- package/src/flow/models/blocks/table/TableColumnModel.tsx +72 -6
- package/src/flow/models/blocks/table/__tests__/TableActionsColumnModel.test.tsx +111 -1
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.dragSort.test.ts +127 -0
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.mobileSettingsButtons.test.tsx +78 -0
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.quickEditRefresh.test.ts +12 -0
- package/src/flow/models/blocks/table/__tests__/TableBlockModel.rowSelection.test.tsx +1 -0
- package/src/flow/models/blocks/table/__tests__/TableColumnModel.test.tsx +243 -1
- package/src/flow/models/blocks/table/dragSort/dragSortHooks.tsx +28 -17
- package/src/flow/models/blocks/table/dragSort/dragSortSettings.ts +13 -6
- package/src/flow/models/blocks/table/dragSort/dragSortUtils.ts +15 -2
- package/src/flow/models/fields/AssociationFieldModel/AssociationFieldModel.tsx +1 -1
- package/src/flow/models/fields/AssociationFieldModel/PopupSubTableFieldModel/PopupSubTableFieldModel.tsx +31 -7
- package/src/flow/models/fields/AssociationFieldModel/RecordSelectFieldModel.tsx +61 -17
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableColumnModel.tsx +141 -19
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/SubTableField.tsx +13 -1
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/__tests__/SubTableColumnModel.rowRecord.test.ts +197 -0
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/__tests__/SubTableFieldModel.reset.test.ts +180 -0
- package/src/flow/models/fields/AssociationFieldModel/SubTableFieldModel/index.tsx +6 -4
- package/src/flow/models/fields/AssociationFieldModel/__tests__/AssociationFieldModel.updateAssociation.test.ts +72 -0
- package/src/flow/models/fields/AssociationFieldModel/__tests__/RecordPickerFieldModel.itemContext.test.ts +23 -0
- package/src/flow/models/fields/ClickableFieldModel.tsx +5 -0
- package/src/flow/models/fields/DateTimeFieldModel/__tests__/DateTimeNoTzFieldModel.dateLimit.test.tsx +149 -0
- package/src/flow/models/fields/DateTimeFieldModel/dateLimit.ts +149 -113
- package/src/flow/models/fields/DisplayDateTimeFieldModel.tsx +29 -1
- package/src/flow/models/fields/InputFieldModel.tsx +40 -2
- package/src/flow/models/fields/JSEditableFieldModel.tsx +2 -11
- package/src/flow/models/fields/JSFieldModel.tsx +2 -7
- package/src/flow/models/fields/JSItemModel.tsx +2 -14
- package/src/flow/models/fields/SelectFieldModel.tsx +6 -4
- package/src/flow/models/fields/TextareaFieldModel.tsx +72 -3
- package/src/flow/models/fields/VariableFieldFormModel.tsx +3 -3
- package/src/flow/models/fields/__tests__/DisplayDateTimeFieldModel.test.tsx +96 -0
- package/src/flow/models/fields/__tests__/InputFieldModel.test.tsx +117 -1
- package/src/flow/models/fields/__tests__/SelectFieldModel.test.tsx +43 -0
- package/src/flow/models/fields/__tests__/TextareaFieldModel.test.tsx +131 -0
- package/src/flow/models/fields/__tests__/VariableFieldFormModel.test.tsx +51 -0
- package/src/flow/models/fields/mobile-components/MobileLazySelect.tsx +20 -10
- package/src/flow/models/fields/mobile-components/MobileSelect.tsx +24 -12
- package/src/flow/models/topbar/TopbarActionModel.tsx +168 -10
- package/src/flow/resolveViewParamsToViewList.tsx +11 -3
- package/src/flow/routeTransientInputArgs.ts +27 -0
- package/src/flow/utils/__tests__/dateTimeFormat.test.ts +300 -0
- package/src/flow/utils/dataScopeFormValueClear.ts +219 -81
- package/src/flow/utils/dataScopeRowSnapshot.ts +616 -0
- package/src/flow/utils/dateTimeDisplayProps.ts +135 -0
- package/src/flow/utils/formValueDeps.ts +170 -0
- package/src/flow-compat/FieldValidation.tsx +122 -60
- package/src/flow-compat/Popover.tsx +43 -4
- package/src/flow-compat/__tests__/Popover.test.tsx +34 -0
- package/src/flow-compat/fieldValidationConstants.ts +1 -1
- package/src/flow-compat/routeTypes.ts +1 -0
- package/src/index.ts +14 -1
- package/src/layout-manager/__tests__/LayoutRoute.test.tsx +41 -1
- package/src/locale/languageCodes.ts +3 -1
- package/src/nocobase-buildin-plugin/index.tsx +63 -15
- package/src/settings-center/AdminSettingsLayout.tsx +10 -2
- package/src/settings-center/SystemSettingsPage.tsx +1 -2
- package/src/settings-center/plugin-manager/PluginCard.tsx +2 -2
- package/src/settings-center/plugin-manager/index.tsx +3 -0
- package/src/settings-center/utils.tsx +0 -6
- package/src/utils/getRouteRuntimeVersion.ts +185 -0
- package/src/utils/index.tsx +1 -0
- package/src/utils/markdownSanitize.ts +88 -0
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import React, { useMemo, useState } from 'react';
|
|
10
|
+
import React, { useCallback, useMemo, useState } from 'react';
|
|
11
11
|
import { DatePicker, Select, Space } from 'antd';
|
|
12
12
|
import { inferPickerType } from '../../flow-compat';
|
|
13
13
|
import { dayjs, getDateTimeFormat, getPickerFormat } from '@nocobase/utils/client';
|
|
@@ -29,6 +29,7 @@ export interface FieldAssignExactDatePickerProps {
|
|
|
29
29
|
isRange?: boolean;
|
|
30
30
|
onChange?: (value: ExactDatePickerValue) => void;
|
|
31
31
|
style?: React.CSSProperties;
|
|
32
|
+
disabled?: boolean;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
function getRawSingleValue(value: unknown, isRange: boolean): unknown {
|
|
@@ -114,7 +115,7 @@ function parseRangeValue(value: unknown, format: string): [dayjs.Dayjs, dayjs.Da
|
|
|
114
115
|
}
|
|
115
116
|
|
|
116
117
|
export const FieldAssignExactDatePicker: React.FC<FieldAssignExactDatePickerProps> = (props) => {
|
|
117
|
-
const { picker = 'date', format, showTime, timeFormat, value, isRange = false, onChange, style } = props;
|
|
118
|
+
const { picker = 'date', format, showTime, timeFormat, value, isRange = false, onChange, style, disabled } = props;
|
|
118
119
|
const flowCtx = useFlowContext();
|
|
119
120
|
const t = flowCtx.model.translate.bind(flowCtx.model);
|
|
120
121
|
|
|
@@ -124,17 +125,17 @@ export const FieldAssignExactDatePicker: React.FC<FieldAssignExactDatePickerProp
|
|
|
124
125
|
return inferPickerFromRawValue(rawSingleValue, picker);
|
|
125
126
|
});
|
|
126
127
|
|
|
127
|
-
const getResolvedFormat = (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
() => getResolvedFormat(targetPicker),
|
|
135
|
-
[targetPicker, format, picker, showTime, timeFormat],
|
|
128
|
+
const getResolvedFormat = useCallback(
|
|
129
|
+
(nextPicker: ExactDatePickerMode) => {
|
|
130
|
+
const baseFormat = nextPicker === picker && format ? format : getPickerFormat(nextPicker);
|
|
131
|
+
const dateFormat = nextPicker === 'date' ? stripTimeFromFormat(baseFormat) : baseFormat;
|
|
132
|
+
return getDateTimeFormat(nextPicker, dateFormat, showTime, timeFormat);
|
|
133
|
+
},
|
|
134
|
+
[format, picker, showTime, timeFormat],
|
|
136
135
|
);
|
|
137
136
|
|
|
137
|
+
const resolvedFormat = useMemo(() => getResolvedFormat(targetPicker), [getResolvedFormat, targetPicker]);
|
|
138
|
+
|
|
138
139
|
const singleValue = useMemo(() => {
|
|
139
140
|
if (isRange) return null;
|
|
140
141
|
return parseDateFromRawValue(value, resolvedFormat);
|
|
@@ -156,6 +157,10 @@ export const FieldAssignExactDatePicker: React.FC<FieldAssignExactDatePickerProp
|
|
|
156
157
|
);
|
|
157
158
|
|
|
158
159
|
const handlePickerTypeChange = (nextPicker: ExactDatePickerMode) => {
|
|
160
|
+
if (disabled) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
159
164
|
setTargetPicker(nextPicker);
|
|
160
165
|
|
|
161
166
|
if (!onChange) {
|
|
@@ -182,7 +187,11 @@ export const FieldAssignExactDatePicker: React.FC<FieldAssignExactDatePickerProp
|
|
|
182
187
|
inputReadOnly: flowCtx.isMobileLayout,
|
|
183
188
|
showTime: showTime ? { defaultValue: dayjs('00:00:00', 'HH:mm:ss') } : false,
|
|
184
189
|
value: singleValue,
|
|
190
|
+
disabled,
|
|
185
191
|
onChange: (nextDate: dayjs.Dayjs | null) => {
|
|
192
|
+
if (disabled) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
186
195
|
if (nextDate && dayjs.isDayjs(nextDate)) {
|
|
187
196
|
onChange?.(nextDate);
|
|
188
197
|
return;
|
|
@@ -200,7 +209,11 @@ export const FieldAssignExactDatePicker: React.FC<FieldAssignExactDatePickerProp
|
|
|
200
209
|
inputReadOnly: flowCtx.isMobileLayout,
|
|
201
210
|
showTime: showTime ? { defaultValue: [dayjs('00:00:00', 'HH:mm:ss'), dayjs('23:59:59', 'HH:mm:ss')] } : false,
|
|
202
211
|
value: rangeValue,
|
|
212
|
+
disabled,
|
|
203
213
|
onChange: (nextDates: [dayjs.Dayjs | null, dayjs.Dayjs | null] | null) => {
|
|
214
|
+
if (disabled) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
204
217
|
if (Array.isArray(nextDates) && nextDates[0] && nextDates[1]) {
|
|
205
218
|
onChange?.([nextDates[0], nextDates[1]]);
|
|
206
219
|
return;
|
|
@@ -218,6 +231,7 @@ export const FieldAssignExactDatePicker: React.FC<FieldAssignExactDatePickerProp
|
|
|
218
231
|
value={targetPicker}
|
|
219
232
|
options={pickerOptions}
|
|
220
233
|
onChange={handlePickerTypeChange}
|
|
234
|
+
disabled={disabled}
|
|
221
235
|
/>
|
|
222
236
|
{isRange ? <DatePicker.RangePicker {...rangePickerProps} /> : <DatePicker {...singlePickerProps} />}
|
|
223
237
|
</Space.Compact>
|
|
@@ -28,7 +28,7 @@ import { buildFieldAssignCascaderOptionsFromCollection, type FieldAssignCascader
|
|
|
28
28
|
import { isRunJSValue, isVariableExpression, type MetaTreeNode } from '@nocobase/flow-engine';
|
|
29
29
|
import { isToManyAssociationField } from '../internal/utils/modelUtils';
|
|
30
30
|
|
|
31
|
-
export type AssignMode = 'default' | 'assign';
|
|
31
|
+
export type AssignMode = 'default' | 'assign' | 'override';
|
|
32
32
|
|
|
33
33
|
type CollectionFieldLike = {
|
|
34
34
|
name?: unknown;
|
|
@@ -89,6 +89,8 @@ export interface FieldAssignRulesEditorProps {
|
|
|
89
89
|
defaultMode?: AssignMode;
|
|
90
90
|
/** 固定 mode:用于“仅默认值/仅赋值”的场景 */
|
|
91
91
|
fixedMode?: AssignMode;
|
|
92
|
+
/** 可选 mode 列表;fixedMode 优先级更高 */
|
|
93
|
+
allowedModes?: AssignMode[];
|
|
92
94
|
/** 是否显示 condition */
|
|
93
95
|
showCondition?: boolean;
|
|
94
96
|
/** 是否显示 enable 开关 */
|
|
@@ -109,6 +111,65 @@ export interface FieldAssignRulesEditorProps {
|
|
|
109
111
|
maxAssociationFieldDepth?: number;
|
|
110
112
|
}
|
|
111
113
|
|
|
114
|
+
const ALL_ASSIGN_MODES: AssignMode[] = ['default', 'override', 'assign'];
|
|
115
|
+
|
|
116
|
+
function cloneCascaderOption(option: FieldAssignCascaderOption): FieldAssignCascaderOption {
|
|
117
|
+
return {
|
|
118
|
+
...option,
|
|
119
|
+
children: option.children?.map((child) => cloneCascaderOption(child)),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function mergeCascaderOptionInto(options: FieldAssignCascaderOption[], source: FieldAssignCascaderOption) {
|
|
124
|
+
const value = source?.value ? String(source.value) : '';
|
|
125
|
+
if (!value) return;
|
|
126
|
+
|
|
127
|
+
const existing = options.find((item) => String(item?.value || '') === value);
|
|
128
|
+
if (!existing) {
|
|
129
|
+
options.push(cloneCascaderOption(source));
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (!existing.label && source.label) {
|
|
134
|
+
existing.label = source.label;
|
|
135
|
+
}
|
|
136
|
+
if (source.isLeaf === false || existing.children?.length || source.children?.length) {
|
|
137
|
+
existing.isLeaf = false;
|
|
138
|
+
}
|
|
139
|
+
if (source.loading) {
|
|
140
|
+
existing.loading = source.loading;
|
|
141
|
+
}
|
|
142
|
+
if (source.children?.length) {
|
|
143
|
+
existing.children = mergeCascaderOptions(existing.children || [], source.children);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function mergeCascaderOptions(
|
|
148
|
+
configured: FieldAssignCascaderOption[],
|
|
149
|
+
allFields: FieldAssignCascaderOption[],
|
|
150
|
+
): FieldAssignCascaderOption[] {
|
|
151
|
+
const result = (Array.isArray(configured) ? configured : []).map((item) => cloneCascaderOption(item));
|
|
152
|
+
for (const item of Array.isArray(allFields) ? allFields : []) {
|
|
153
|
+
mergeCascaderOptionInto(result, item);
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function isAssignMode(mode: unknown): mode is AssignMode {
|
|
159
|
+
return mode === 'default' || mode === 'override' || mode === 'assign';
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function normalizeAssignModes(modes?: AssignMode[]): AssignMode[] {
|
|
163
|
+
const source = Array.isArray(modes) && modes.length ? modes : ALL_ASSIGN_MODES;
|
|
164
|
+
const out: AssignMode[] = [];
|
|
165
|
+
for (const mode of source) {
|
|
166
|
+
if (!isAssignMode(mode)) continue;
|
|
167
|
+
if (out.includes(mode)) continue;
|
|
168
|
+
out.push(mode);
|
|
169
|
+
}
|
|
170
|
+
return out.length ? out : ALL_ASSIGN_MODES;
|
|
171
|
+
}
|
|
172
|
+
|
|
112
173
|
export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (props) => {
|
|
113
174
|
const {
|
|
114
175
|
t,
|
|
@@ -118,6 +179,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
118
179
|
onChange,
|
|
119
180
|
defaultMode = 'assign',
|
|
120
181
|
fixedMode,
|
|
182
|
+
allowedModes: rawAllowedModes,
|
|
121
183
|
showCondition = true,
|
|
122
184
|
showEnable = true,
|
|
123
185
|
showValueEditorWhenNoField = false,
|
|
@@ -129,13 +191,43 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
129
191
|
} = props;
|
|
130
192
|
|
|
131
193
|
const value = React.useMemo(() => (Array.isArray(rawValue) ? rawValue : []), [rawValue]);
|
|
194
|
+
const allowedModes = React.useMemo(
|
|
195
|
+
() => normalizeAssignModes(fixedMode ? [fixedMode] : rawAllowedModes),
|
|
196
|
+
[fixedMode, rawAllowedModes],
|
|
197
|
+
);
|
|
198
|
+
const getDefaultMode = React.useCallback((): AssignMode => {
|
|
199
|
+
if (fixedMode) return fixedMode;
|
|
200
|
+
if (isAssignMode(defaultMode) && allowedModes.includes(defaultMode)) return defaultMode;
|
|
201
|
+
return allowedModes[0] || 'assign';
|
|
202
|
+
}, [allowedModes, defaultMode, fixedMode]);
|
|
203
|
+
const normalizeItemMode = React.useCallback(
|
|
204
|
+
(item: FieldAssignRuleItem): FieldAssignRuleItem => {
|
|
205
|
+
const mode = isAssignMode(item?.mode) && allowedModes.includes(item.mode) ? item.mode : getDefaultMode();
|
|
206
|
+
return item?.mode === mode ? item : { ...item, mode };
|
|
207
|
+
},
|
|
208
|
+
[allowedModes, getDefaultMode],
|
|
209
|
+
);
|
|
210
|
+
const emitChange = React.useCallback(
|
|
211
|
+
(next: FieldAssignRuleItem[]) => {
|
|
212
|
+
onChange?.(next.map((item) => normalizeItemMode(item)));
|
|
213
|
+
},
|
|
214
|
+
[normalizeItemMode, onChange],
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
const normalizeFieldOptions = React.useCallback((options: FieldAssignRulesEditorProps['fieldOptions']) => {
|
|
218
|
+
return Array.isArray(options)
|
|
219
|
+
? (options as FieldAssignCascaderOption[]).map((option) => cloneCascaderOption(option))
|
|
220
|
+
: [];
|
|
221
|
+
}, []);
|
|
132
222
|
const [cascaderOptions, setCascaderOptions] = React.useState<FieldAssignCascaderOption[]>(() =>
|
|
133
|
-
|
|
223
|
+
normalizeFieldOptions(fieldOptions),
|
|
134
224
|
);
|
|
225
|
+
const loadedCascaderOptionsRef = React.useRef<WeakSet<FieldAssignCascaderOption>>(new WeakSet());
|
|
135
226
|
|
|
136
227
|
React.useEffect(() => {
|
|
137
|
-
|
|
138
|
-
|
|
228
|
+
loadedCascaderOptionsRef.current = new WeakSet();
|
|
229
|
+
setCascaderOptions(normalizeFieldOptions(fieldOptions));
|
|
230
|
+
}, [fieldOptions, normalizeFieldOptions, rootCollection, maxAssociationFieldDepth]);
|
|
139
231
|
|
|
140
232
|
const getRuleKey = React.useCallback((item: FieldAssignRuleItem, index: number) => item?.key || String(index), []);
|
|
141
233
|
const [titleFieldDraftMap, setTitleFieldDraftMap] = React.useState<Record<string, string | undefined>>({});
|
|
@@ -312,7 +404,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
312
404
|
|
|
313
405
|
const patchItem = (index: number, patch: Partial<FieldAssignRuleItem>) => {
|
|
314
406
|
const next = value.map((it, i) => (i === index ? { ...it, ...patch } : it));
|
|
315
|
-
|
|
407
|
+
emitChange(next);
|
|
316
408
|
};
|
|
317
409
|
|
|
318
410
|
const removeItem = (index: number) => {
|
|
@@ -334,7 +426,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
334
426
|
setSyncingRuleKey(null);
|
|
335
427
|
}
|
|
336
428
|
const next = value.filter((_, i) => i !== index);
|
|
337
|
-
|
|
429
|
+
emitChange(next);
|
|
338
430
|
};
|
|
339
431
|
|
|
340
432
|
const moveItem = (index: number, direction: 'up' | 'down') => {
|
|
@@ -343,7 +435,7 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
343
435
|
if (targetIndex < 0 || targetIndex >= next.length) return;
|
|
344
436
|
const [item] = next.splice(index, 1);
|
|
345
437
|
next.splice(targetIndex, 0, item);
|
|
346
|
-
|
|
438
|
+
emitChange(next);
|
|
347
439
|
};
|
|
348
440
|
|
|
349
441
|
const addItem = () => {
|
|
@@ -352,29 +444,33 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
352
444
|
{
|
|
353
445
|
key: uid(),
|
|
354
446
|
enable: true,
|
|
355
|
-
mode:
|
|
447
|
+
mode: getDefaultMode(),
|
|
356
448
|
condition: { logic: '$and', items: [] },
|
|
357
449
|
targetPath: undefined,
|
|
358
450
|
value: undefined,
|
|
359
451
|
},
|
|
360
452
|
];
|
|
361
|
-
|
|
453
|
+
emitChange(next);
|
|
362
454
|
};
|
|
363
455
|
|
|
364
456
|
const getEffectiveMode = (item: FieldAssignRuleItem): AssignMode => {
|
|
365
457
|
if (fixedMode) return fixedMode;
|
|
366
|
-
|
|
458
|
+
if (isAssignMode(item?.mode) && allowedModes.includes(item.mode)) return item.mode;
|
|
459
|
+
return getDefaultMode();
|
|
367
460
|
};
|
|
368
461
|
|
|
369
462
|
const renderAssignModeLabel = React.useCallback(
|
|
370
463
|
(mode: AssignMode) => {
|
|
371
|
-
const modeText =
|
|
464
|
+
const modeText =
|
|
465
|
+
mode === 'default' ? t('Default value') : mode === 'override' ? t('Override value') : t('Fixed value');
|
|
372
466
|
const modeHelpText =
|
|
373
467
|
mode === 'default'
|
|
374
468
|
? t(
|
|
375
469
|
'A pre-filled value. Editable, for new entries only, and won’t affect existing data (including empty values).',
|
|
376
470
|
)
|
|
377
|
-
:
|
|
471
|
+
: mode === 'override'
|
|
472
|
+
? t('Overrides existing values until the user edits it.')
|
|
473
|
+
: t('A system-set value. Read-only.');
|
|
378
474
|
|
|
379
475
|
const preventModeToggle = (e: React.MouseEvent<HTMLElement>) => {
|
|
380
476
|
e.preventDefault();
|
|
@@ -551,23 +647,26 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
551
647
|
const opts = selectedOptions || [];
|
|
552
648
|
const target = opts[opts.length - 1];
|
|
553
649
|
if (!target) return;
|
|
554
|
-
if (target.children && Array.isArray(target.children) && target.children.length) return;
|
|
555
650
|
if (target.isLeaf) return;
|
|
651
|
+
if (loadedCascaderOptionsRef.current.has(target)) return;
|
|
556
652
|
|
|
557
653
|
const segments = opts.map((o) => String(o?.value)).filter(Boolean);
|
|
558
654
|
const targetCollection = resolveTargetCollectionBySegments(segments);
|
|
559
655
|
if (!targetCollection) {
|
|
560
|
-
target.isLeaf =
|
|
656
|
+
target.isLeaf = !(target.children && target.children.length);
|
|
657
|
+
loadedCascaderOptionsRef.current.add(target);
|
|
561
658
|
setCascaderOptions((prev) => [...prev]);
|
|
562
659
|
return;
|
|
563
660
|
}
|
|
564
661
|
|
|
565
662
|
const children = buildChildrenFromCollection(targetCollection, segments.length);
|
|
566
663
|
if (!children.length) {
|
|
567
|
-
target.isLeaf =
|
|
664
|
+
target.isLeaf = !(target.children && target.children.length);
|
|
568
665
|
} else {
|
|
569
|
-
target.children = children;
|
|
666
|
+
target.children = mergeCascaderOptions(target.children || [], children);
|
|
667
|
+
target.isLeaf = false;
|
|
570
668
|
}
|
|
669
|
+
loadedCascaderOptionsRef.current.add(target);
|
|
571
670
|
setCascaderOptions((prev) => [...prev]);
|
|
572
671
|
},
|
|
573
672
|
[buildChildrenFromCollection, resolveTargetCollectionBySegments],
|
|
@@ -583,12 +682,14 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
583
682
|
const hit = options.find((o) => String(o?.value) === seg);
|
|
584
683
|
if (!hit) return;
|
|
585
684
|
selected.push(hit);
|
|
685
|
+
if (!hit.isLeaf && !loadedCascaderOptionsRef.current.has(hit)) {
|
|
686
|
+
await loadCascaderData(selected);
|
|
687
|
+
}
|
|
586
688
|
if (hit.children?.length) {
|
|
587
689
|
options = hit.children;
|
|
588
690
|
continue;
|
|
589
691
|
}
|
|
590
692
|
if (hit.isLeaf) return;
|
|
591
|
-
await loadCascaderData(selected);
|
|
592
693
|
options = hit.children || [];
|
|
593
694
|
}
|
|
594
695
|
},
|
|
@@ -619,7 +720,9 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
619
720
|
await preloadCascaderPath(segs);
|
|
620
721
|
}
|
|
621
722
|
};
|
|
622
|
-
|
|
723
|
+
run().catch((error) => {
|
|
724
|
+
console.warn('[FieldAssignRulesEditor] Failed to preload cascader path', error);
|
|
725
|
+
});
|
|
623
726
|
return () => {
|
|
624
727
|
cancelled = true;
|
|
625
728
|
};
|
|
@@ -627,7 +730,8 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
627
730
|
|
|
628
731
|
const renderPanelHeader = (item: FieldAssignRuleItem, index: number) => {
|
|
629
732
|
const mode = getEffectiveMode(item);
|
|
630
|
-
const modeText =
|
|
733
|
+
const modeText =
|
|
734
|
+
mode === 'default' ? t('Default value') : mode === 'override' ? t('Override value') : t('Fixed value');
|
|
631
735
|
const fieldLabel = getFieldLabel(item.targetPath);
|
|
632
736
|
const title = fieldLabel ? String(fieldLabel) : t('Please select field');
|
|
633
737
|
|
|
@@ -935,8 +1039,11 @@ export const FieldAssignRulesEditor: React.FC<FieldAssignRulesEditorProps> = (pr
|
|
|
935
1039
|
onChange={(event) => patchItem(index, { mode: event.target.value as AssignMode })}
|
|
936
1040
|
>
|
|
937
1041
|
<Space size={16}>
|
|
938
|
-
|
|
939
|
-
|
|
1042
|
+
{allowedModes.map((allowedMode) => (
|
|
1043
|
+
<Radio key={allowedMode} value={allowedMode}>
|
|
1044
|
+
{renderAssignModeLabel(allowedMode)}
|
|
1045
|
+
</Radio>
|
|
1046
|
+
))}
|
|
940
1047
|
</Space>
|
|
941
1048
|
</Radio.Group>
|
|
942
1049
|
</div>
|
|
@@ -42,6 +42,12 @@ import { normalizeFilterValueByOperator } from '../models/blocks/filter-form/val
|
|
|
42
42
|
import { FieldAssignExactDatePicker, type ExactDatePickerMode } from './FieldAssignExactDatePicker';
|
|
43
43
|
import { limitAssociationMetaTree } from './filter/metaTreeAssociationDepth';
|
|
44
44
|
|
|
45
|
+
type VariableInputConverters = {
|
|
46
|
+
renderInputComponent?: (metaTreeNode: MetaTreeNode | null) => React.ComponentType<any> | null;
|
|
47
|
+
resolvePathFromValue?: (value: any) => string[] | undefined;
|
|
48
|
+
resolveValueFromPath?: (metaTreeNode: MetaTreeNode) => any;
|
|
49
|
+
};
|
|
50
|
+
|
|
45
51
|
const DATE_FIELD_INTERFACES = new Set(['date', 'datetime', 'datetimeNoTz', 'createdAt', 'updatedAt', 'unixTimestamp']);
|
|
46
52
|
|
|
47
53
|
const TZ_AWARE_DATE_INTERFACES = new Set(['datetime', 'createdAt', 'updatedAt', 'unixTimestamp']);
|
|
@@ -341,7 +347,11 @@ interface Props {
|
|
|
341
347
|
* 默认 false,保持历史行为。
|
|
342
348
|
*/
|
|
343
349
|
enableDateVariableAsConstant?: boolean;
|
|
350
|
+
/** 是否允许在变量选择器中使用 RunJS。默认 true,保持历史行为。 */
|
|
351
|
+
allowRunJS?: boolean;
|
|
344
352
|
maxAssociationFieldDepth?: number;
|
|
353
|
+
disabled?: boolean;
|
|
354
|
+
variableConverters?: VariableInputConverters;
|
|
345
355
|
}
|
|
346
356
|
|
|
347
357
|
type ResolvedFieldContext = {
|
|
@@ -712,7 +722,10 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
712
722
|
preferFormItemFieldModel,
|
|
713
723
|
associationFieldNamesOverride,
|
|
714
724
|
enableDateVariableAsConstant = false,
|
|
725
|
+
allowRunJS = true,
|
|
715
726
|
maxAssociationFieldDepth = 2,
|
|
727
|
+
disabled = false,
|
|
728
|
+
variableConverters,
|
|
716
729
|
}) => {
|
|
717
730
|
const flowCtx = useFlowContext<FlowModelContext>();
|
|
718
731
|
const normalizeEventValue = React.useCallback((eventOrValue: unknown) => {
|
|
@@ -1028,18 +1041,22 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1028
1041
|
collectionField: effectiveCollectionField,
|
|
1029
1042
|
});
|
|
1030
1043
|
|
|
1031
|
-
const
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1044
|
+
const sourceContext = resolved?.itemModel?.context || flowCtx.model?.context;
|
|
1045
|
+
const created = engine?.createModel?.(
|
|
1046
|
+
{
|
|
1047
|
+
use: 'VariableFieldFormModel',
|
|
1048
|
+
subModels: {
|
|
1049
|
+
fields: [
|
|
1050
|
+
{
|
|
1051
|
+
use: effectiveFieldModelUse,
|
|
1052
|
+
stepParams: tempFieldStepParams,
|
|
1053
|
+
props: tempFieldProps,
|
|
1054
|
+
},
|
|
1055
|
+
],
|
|
1056
|
+
},
|
|
1041
1057
|
},
|
|
1042
|
-
|
|
1058
|
+
sourceContext ? { delegate: sourceContext } : undefined,
|
|
1059
|
+
);
|
|
1043
1060
|
if (!created) return;
|
|
1044
1061
|
|
|
1045
1062
|
// 注入上下文(集合/数据源/字段/区块/资源)
|
|
@@ -1073,7 +1090,7 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1073
1090
|
fm.setStepParams('selectSettings', 'fieldNames', { label: overrideLabel });
|
|
1074
1091
|
}
|
|
1075
1092
|
fm?.setProps?.({
|
|
1076
|
-
disabled
|
|
1093
|
+
disabled,
|
|
1077
1094
|
readPretty: false,
|
|
1078
1095
|
pattern: 'editable',
|
|
1079
1096
|
updateAssociation: false,
|
|
@@ -1136,6 +1153,7 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1136
1153
|
preferFormItemFieldModel,
|
|
1137
1154
|
associationFieldNamesOverride?.label,
|
|
1138
1155
|
associationFieldNamesOverride?.value,
|
|
1156
|
+
disabled,
|
|
1139
1157
|
]);
|
|
1140
1158
|
|
|
1141
1159
|
// 当传入 operator / operatorMetaList 时,按 operator schema 适配临时字段的输入组件与 props。
|
|
@@ -1188,6 +1206,9 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1188
1206
|
React.useEffect(() => {
|
|
1189
1207
|
const coercedValue = coerceEmptyValueForRenderer(inputProps?.value);
|
|
1190
1208
|
const handleChange = (ev: any) => {
|
|
1209
|
+
if (inputProps?.disabled) {
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1191
1212
|
const nextRaw = normalizeEventValue(ev);
|
|
1192
1213
|
const normalizedForStore = operator ? normalizeFilterValueByOperator(operator, nextRaw) : nextRaw;
|
|
1193
1214
|
const nextValue = coerceEmptyValueForRenderer(normalizedForStore);
|
|
@@ -1219,6 +1240,7 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1219
1240
|
value={inputProps?.value}
|
|
1220
1241
|
onChange={(e) => inputProps?.onChange?.(normalizeEventValue(e))}
|
|
1221
1242
|
placeholder={placeholder}
|
|
1243
|
+
disabled={inputProps?.disabled}
|
|
1222
1244
|
style={withFullWidthStyle(wrapperStyle)}
|
|
1223
1245
|
/>
|
|
1224
1246
|
);
|
|
@@ -1237,6 +1259,7 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1237
1259
|
const C: React.FC<any> = (inputProps) => {
|
|
1238
1260
|
const wrapperStyle = pickStyle(inputProps?.style);
|
|
1239
1261
|
const raw = inputProps?.value;
|
|
1262
|
+
const isDisabled = Boolean(inputProps?.disabled);
|
|
1240
1263
|
const parsed = isCtxDateExpression(raw) ? parseCtxDateExpression(raw) : raw;
|
|
1241
1264
|
const parsedValue = typeof parsed === 'undefined' ? undefined : parsed;
|
|
1242
1265
|
const { token } = theme.useToken();
|
|
@@ -1261,6 +1284,9 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1261
1284
|
});
|
|
1262
1285
|
|
|
1263
1286
|
const handleSelect = (val: string) => {
|
|
1287
|
+
if (isDisabled) {
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1264
1290
|
setOpen(false);
|
|
1265
1291
|
if (val === 'exact') {
|
|
1266
1292
|
inputProps?.onChange?.('');
|
|
@@ -1275,10 +1301,16 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1275
1301
|
};
|
|
1276
1302
|
|
|
1277
1303
|
const handleExactSingleChange = (nextValue: any) => {
|
|
1304
|
+
if (isDisabled) {
|
|
1305
|
+
return;
|
|
1306
|
+
}
|
|
1278
1307
|
inputProps?.onChange?.(nextValue || '');
|
|
1279
1308
|
};
|
|
1280
1309
|
|
|
1281
1310
|
const handleExactRangeChange = (nextValue: any) => {
|
|
1311
|
+
if (isDisabled) {
|
|
1312
|
+
return;
|
|
1313
|
+
}
|
|
1282
1314
|
inputProps?.onChange?.(nextValue || '');
|
|
1283
1315
|
};
|
|
1284
1316
|
|
|
@@ -1323,7 +1355,11 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1323
1355
|
<Select
|
|
1324
1356
|
options={options}
|
|
1325
1357
|
open={open}
|
|
1326
|
-
onDropdownVisibleChange={
|
|
1358
|
+
onDropdownVisibleChange={(nextOpen) => {
|
|
1359
|
+
if (!isDisabled) {
|
|
1360
|
+
setOpen(nextOpen);
|
|
1361
|
+
}
|
|
1362
|
+
}}
|
|
1327
1363
|
allowClear={false}
|
|
1328
1364
|
style={{
|
|
1329
1365
|
width: '100%',
|
|
@@ -1333,13 +1369,18 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1333
1369
|
value={selectedType}
|
|
1334
1370
|
onChange={handleSelect}
|
|
1335
1371
|
dropdownRender={dropdownRender}
|
|
1372
|
+
disabled={isDisabled}
|
|
1336
1373
|
/>
|
|
1337
1374
|
{['past', 'next'].includes(selectedType) && [
|
|
1338
1375
|
<InputNumber
|
|
1339
1376
|
key="number"
|
|
1340
1377
|
style={{ flex: 1 }}
|
|
1341
1378
|
value={(parsedValue as any)?.number}
|
|
1379
|
+
disabled={isDisabled}
|
|
1342
1380
|
onChange={(nextNumber) => {
|
|
1381
|
+
if (isDisabled) {
|
|
1382
|
+
return;
|
|
1383
|
+
}
|
|
1343
1384
|
inputProps?.onChange?.({
|
|
1344
1385
|
...(parsedValue as any),
|
|
1345
1386
|
type: selectedType,
|
|
@@ -1352,7 +1393,11 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1352
1393
|
key="unit"
|
|
1353
1394
|
value={(parsedValue as any)?.unit}
|
|
1354
1395
|
style={{ minWidth: 130, maxWidth: 140 }}
|
|
1396
|
+
disabled={isDisabled}
|
|
1355
1397
|
onChange={(nextUnit) => {
|
|
1398
|
+
if (isDisabled) {
|
|
1399
|
+
return;
|
|
1400
|
+
}
|
|
1356
1401
|
inputProps?.onChange?.({
|
|
1357
1402
|
...(parsedValue as any),
|
|
1358
1403
|
type: selectedType,
|
|
@@ -1375,6 +1420,7 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1375
1420
|
isRange={isRange}
|
|
1376
1421
|
value={isRange ? exactRangeValue : exactSingleValue}
|
|
1377
1422
|
onChange={isRange ? handleExactRangeChange : handleExactSingleChange}
|
|
1423
|
+
disabled={isDisabled}
|
|
1378
1424
|
style={{ flex: 1 }}
|
|
1379
1425
|
/>
|
|
1380
1426
|
)}
|
|
@@ -1394,7 +1440,12 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1394
1440
|
|
|
1395
1441
|
const RunJSComponent = React.useMemo(() => {
|
|
1396
1442
|
const C: React.FC<any> = (inputProps) => (
|
|
1397
|
-
<RunJSValueEditor
|
|
1443
|
+
<RunJSValueEditor
|
|
1444
|
+
t={flowCtx.t}
|
|
1445
|
+
value={inputProps?.value}
|
|
1446
|
+
onChange={inputProps?.onChange}
|
|
1447
|
+
disabled={inputProps?.disabled}
|
|
1448
|
+
/>
|
|
1398
1449
|
);
|
|
1399
1450
|
return C;
|
|
1400
1451
|
}, [flowCtx]);
|
|
@@ -1417,11 +1468,13 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1417
1468
|
render: ConstantEditor,
|
|
1418
1469
|
},
|
|
1419
1470
|
{ title: tExpr('Null'), name: 'null', type: 'object', paths: ['null'], render: NullComponent },
|
|
1420
|
-
|
|
1471
|
+
...(allowRunJS
|
|
1472
|
+
? [{ title: tExpr('RunJS'), name: 'runjs', type: 'object', paths: ['runjs'], render: RunJSComponent }]
|
|
1473
|
+
: []),
|
|
1421
1474
|
...limitedBase,
|
|
1422
1475
|
];
|
|
1423
1476
|
};
|
|
1424
|
-
}, [flowCtx, ConstantEditor, NullComponent, RunJSComponent, maxAssociationFieldDepth]);
|
|
1477
|
+
}, [flowCtx, ConstantEditor, NullComponent, RunJSComponent, allowRunJS, maxAssociationFieldDepth]);
|
|
1425
1478
|
|
|
1426
1479
|
const displayValue = React.useMemo(() => {
|
|
1427
1480
|
if (!useDateVariableConstant) {
|
|
@@ -1438,6 +1491,10 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1438
1491
|
|
|
1439
1492
|
const handleVariableInputChange = React.useCallback(
|
|
1440
1493
|
(nextValue: any) => {
|
|
1494
|
+
if (disabled) {
|
|
1495
|
+
return;
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1441
1498
|
if (!useDateVariableConstant) {
|
|
1442
1499
|
onChange(nextValue);
|
|
1443
1500
|
return;
|
|
@@ -1445,7 +1502,7 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1445
1502
|
|
|
1446
1503
|
onChange(normalizeDateVariableOutput(nextValue, dateVariableComponentProps));
|
|
1447
1504
|
},
|
|
1448
|
-
[dateVariableComponentProps, onChange, useDateVariableConstant],
|
|
1505
|
+
[dateVariableComponentProps, disabled, onChange, useDateVariableConstant],
|
|
1449
1506
|
);
|
|
1450
1507
|
|
|
1451
1508
|
if (!fieldPath) {
|
|
@@ -1460,26 +1517,40 @@ export const FieldAssignValueInput: React.FC<Props> = ({
|
|
|
1460
1517
|
metaTree={metaTree}
|
|
1461
1518
|
style={{ width: '100%' }}
|
|
1462
1519
|
clearValue={''}
|
|
1520
|
+
disabled={disabled}
|
|
1463
1521
|
converters={{
|
|
1522
|
+
...variableConverters,
|
|
1464
1523
|
renderInputComponent: (meta) => {
|
|
1524
|
+
const external = variableConverters?.renderInputComponent?.(meta ?? null);
|
|
1525
|
+
if (external) {
|
|
1526
|
+
return external;
|
|
1527
|
+
}
|
|
1465
1528
|
const firstPath = meta?.paths?.[0];
|
|
1466
1529
|
if (firstPath === 'constant') return ConstantEditor;
|
|
1467
1530
|
if (firstPath === 'null') return NullComponent;
|
|
1468
|
-
if (firstPath === 'runjs') return RunJSComponent;
|
|
1531
|
+
if (allowRunJS && firstPath === 'runjs') return RunJSComponent;
|
|
1469
1532
|
return null;
|
|
1470
1533
|
},
|
|
1471
1534
|
resolveValueFromPath: (item) => {
|
|
1535
|
+
const external = variableConverters?.resolveValueFromPath?.(item);
|
|
1536
|
+
if (external !== undefined) {
|
|
1537
|
+
return external;
|
|
1538
|
+
}
|
|
1472
1539
|
const firstPath = item?.paths?.[0];
|
|
1473
1540
|
if (firstPath === 'constant') {
|
|
1474
1541
|
return useDateVariableConstant ? { type: 'today' } : '';
|
|
1475
1542
|
}
|
|
1476
1543
|
if (firstPath === 'null') return null;
|
|
1477
|
-
if (firstPath === 'runjs') return { code: '', version: 'v2' };
|
|
1544
|
+
if (allowRunJS && firstPath === 'runjs') return { code: '', version: 'v2' };
|
|
1478
1545
|
return undefined;
|
|
1479
1546
|
},
|
|
1480
1547
|
resolvePathFromValue: (currentValue) => {
|
|
1548
|
+
const external = variableConverters?.resolvePathFromValue?.(currentValue);
|
|
1549
|
+
if (external !== undefined) {
|
|
1550
|
+
return external;
|
|
1551
|
+
}
|
|
1481
1552
|
if (currentValue === null) return ['null'];
|
|
1482
|
-
if (isRunJSValue(currentValue)) return ['runjs'];
|
|
1553
|
+
if (allowRunJS && isRunJSValue(currentValue)) return ['runjs'];
|
|
1483
1554
|
if (useDateVariableConstant && isCtxDateExpression(currentValue)) {
|
|
1484
1555
|
return ['constant'];
|
|
1485
1556
|
}
|