From 87a8b2e844cd68e3a970fb01da7a2d77fa35b8ac Mon Sep 17 00:00:00 2001 From: katherinehhh Date: Wed, 11 Oct 2023 14:24:31 +0800 Subject: [PATCH] fix: fix the wrong way to determine form type (#2787) * fix: depulicate action should load data as depulicate fields config * fix: use formBlockType * Revert "fix: depulicate action should load data as depulicate fields config" This reverts commit 5acb6a1c7046ae8a89243edc4529a5201a9a8f14. * Revert "fix: should allow to set default value in relationship form block (#2777)" This reverts commit 0140e623a6dddccb3dc52549b7718bb3c3380b6f. * fix: should not lazy load data of association fields when creating form * fix: fix subTable * test: add test * test: add test --------- Co-authored-by: Rain <958414905@qq.com> --- .../src/__tests__/e2e/bugs/T-2187.test.ts | 368 ++++++++++++++++++ .../src/block-provider/FormBlockProvider.tsx | 60 ++- .../antd/association-field/Nester.tsx | 61 ++- .../antd/form-item/FormItem.tsx | 6 +- .../useLazyLoadAssociationFieldOfForm.ts | 7 +- .../useLazyLoadAssociationFieldOfSubForm.ts | 14 +- .../antd/form-item/hooks/useSpecialCase.ts | 4 +- .../schema-component/antd/form-v2/utils.tsx | 4 +- .../RecordAssociationFormBlockInitializer.tsx | 2 +- .../hooks/useIsAllowToSetDefaultValue.tsx | 29 +- 10 files changed, 454 insertions(+), 101 deletions(-) create mode 100644 packages/core/client/src/__tests__/e2e/bugs/T-2187.test.ts diff --git a/packages/core/client/src/__tests__/e2e/bugs/T-2187.test.ts b/packages/core/client/src/__tests__/e2e/bugs/T-2187.test.ts new file mode 100644 index 000000000..da1af3ed0 --- /dev/null +++ b/packages/core/client/src/__tests__/e2e/bugs/T-2187.test.ts @@ -0,0 +1,368 @@ +import { expect, test } from '@nocobase/test/client'; + +const config = { + pageSchema: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Page', + properties: { + k24lhmzq1u2: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': 'BlockInitializers', + properties: { + zp24b63pujf: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + e8t2mwjafsr: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + '9x571vayogf': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'TableBlockProvider', + 'x-acl-action': 'users:list', + 'x-decorator-props': { + collection: 'users', + resource: 'users', + action: 'list', + params: { + pageSize: 20, + }, + rowKey: 'id', + showIndex: true, + dragSort: false, + disableTemplate: false, + }, + 'x-designer': 'TableBlockDesigner', + 'x-component': 'CardItem', + 'x-filter-targets': [], + properties: { + actions: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-initializer': 'TableActionInitializers', + 'x-component': 'ActionBar', + 'x-component-props': { + style: { + marginBottom: 'var(--nb-spacing)', + }, + }, + 'x-uid': 't2drja2eg9p', + 'x-async': false, + 'x-index': 1, + }, + edacvuffzln: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'array', + 'x-initializer': 'TableColumnInitializers', + 'x-component': 'TableV2', + 'x-component-props': { + rowKey: 'id', + rowSelection: { + type: 'checkbox', + }, + useProps: '{{ useTableBlockProps }}', + }, + properties: { + actions: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: '{{ t("Actions") }}', + 'x-action-column': 'actions', + 'x-decorator': 'TableV2.Column.ActionBar', + 'x-component': 'TableV2.Column', + 'x-designer': 'TableV2.ActionColumnDesigner', + 'x-initializer': 'TableActionColumnInitializers', + properties: { + actions: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'DndContext', + 'x-component': 'Space', + 'x-component-props': { + split: '|', + }, + properties: { + '2j97snwh4cx': { + 'x-uid': 'il7gzvmxtzu', + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-action': 'duplicate', + 'x-acl-action': 'create', + title: '{{ t("Duplicate") }}', + 'x-designer': 'Action.Designer', + 'x-component': 'Action.Link', + 'x-decorator': 'ACLActionProvider', + 'x-component-props': { + openMode: 'drawer', + component: 'DuplicateAction', + duplicateMode: 'continueduplicate', + duplicateFields: ['nickname'], + duplicateCollection: 'users', + }, + 'x-designer-props': { + linkageAction: true, + }, + properties: { + drawer: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: '{{ t("Duplicate") }}', + 'x-component': 'Action.Container', + 'x-component-props': { + className: 'nb-action-popup', + }, + properties: { + tabs: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Tabs', + 'x-component-props': {}, + 'x-initializer': 'TabPaneInitializers', + properties: { + tab1: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: '{{t("Duplicate")}}', + 'x-component': 'Tabs.TabPane', + 'x-designer': 'Tabs.Designer', + 'x-component-props': {}, + properties: { + grid: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': 'CreateFormBlockInitializers', + properties: { + qvyfk3a9a2g: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + t8ooaf8oxm0: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + jo3yh728qkn: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-acl-action-props': { + skipScopeCheck: true, + }, + 'x-acl-action': 'users:create', + 'x-decorator': 'FormBlockProvider', + 'x-decorator-props': { + resource: 'users', + collection: 'users', + }, + 'x-designer': 'FormV2.Designer', + 'x-component': 'CardItem', + 'x-component-props': {}, + properties: { + '5o8dowro5r1': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'FormV2', + 'x-component-props': { + useProps: '{{ useFormBlockProps }}', + }, + properties: { + grid: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': 'FormItemInitializers', + properties: { + h191s1ni4am: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + twb640jbhp3: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + nickname: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'string', + 'x-designer': 'FormItem.Designer', + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + 'x-collection-field': + 'users.nickname', + 'x-component-props': {}, + 'x-uid': 'pcw1toh7uvj', + 'x-async': false, + 'x-index': 1, + }, + roles: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'string', + 'x-designer': 'FormItem.Designer', + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + 'x-collection-field': 'users.roles', + 'x-component-props': {}, + 'x-uid': '197m7f208wz', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'bbkl81w4h5e', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '1blkzui6noh', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'pcpeajmpx9k', + 'x-async': false, + 'x-index': 1, + }, + actions: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-initializer': 'CreateFormActionInitializers', + 'x-component': 'ActionBar', + 'x-component-props': { + layout: 'one-column', + style: { + marginTop: 24, + }, + }, + 'x-uid': 'y3gbelepat8', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'rmu7uywdppl', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'kpfthrvsd4l', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'drns72r222r', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'iongy3crgdb', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'zw6jjtof2vn', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'hm4kv8gn4me', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'pztq2aledmj', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'qr43qja4p46', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '2w1e5m7at3v', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'uranm958u5v', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '38j1kvvsdtp', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'k4isiobw2ab', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'vr305f4itlf', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 't70enk0z07b', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'rjmnr89y4f6', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'kd7dz5gvdv6', + 'x-async': true, + 'x-index': 1, + }, +}; + +// fix https://nocobase.height.app/T-2187 +test('BUG: in the Duplicate mode, the Roles field should not have a value after clicking it because it is not selected', async ({ + page, + mockPage, +}) => { + await mockPage(config).goto(); + + await page.getByText('Duplicate').click(); + await expect(page.getByTestId('users.nickname-field').getByRole('textbox')).toHaveValue('Super Admin'); + await expect(page.getByText('AdminMemberRoot')).not.toBeVisible(); +}); diff --git a/packages/core/client/src/block-provider/FormBlockProvider.tsx b/packages/core/client/src/block-provider/FormBlockProvider.tsx index 232178531..261b8bee2 100644 --- a/packages/core/client/src/block-provider/FormBlockProvider.tsx +++ b/packages/core/client/src/block-provider/FormBlockProvider.tsx @@ -13,7 +13,7 @@ import { FormActiveFieldsProvider } from './hooks'; export const FormBlockContext = createContext({}); const InternalFormBlockProvider = (props) => { - const { action, readPretty, params, association } = props; + const { action, readPretty, params } = props; const field = useField(); const form = useMemo( () => @@ -35,6 +35,8 @@ const InternalFormBlockProvider = (props) => { params, action, form, + // update 表示是表单编辑区块,create 表示是表单新增区块 + type: action === 'get' ? 'update' : 'create', field, service, resource, @@ -42,46 +44,28 @@ const InternalFormBlockProvider = (props) => { formBlockRef, }} > - {association ? associationBlock() : normalBlock()} + {readPretty ? ( + +
+ +
+
+ ) : ( +
+ +
+ )} ); +}; - function normalBlock(): React.ReactNode { - return readPretty ? ( - -
- -
-
- ) : ( -
- -
- ); - } - - // 这里的 Form 区块是新增区块,所以其字段是可以设置默认值的。又因为是否可以设置默认值是由 record 是否为空来决定的, - // 所以在这里需要将 record 设置为空,这样就可以设置默认值了。相关代码:https://github.com/nocobase/nocobase/blob/fa3127e467bcb3a2425eedfb06fc110cc6eb7f1e/packages/core/client/src/schema-settings/hooks/useIsAllowToSetDefaultValue.tsx#L117-L122 - // - // 如何添加关系区块的 Form 区块: - // 1. 点击 Table 行的查看按钮; - // 2. 弹出的 Drawer 中可以添加关系区块; - // 3. 选择对多字段,点击 Form 区块; - function associationBlock(): React.ReactNode { - return readPretty ? ( - -
- -
-
- ) : ( - -
- -
-
- ); - } +/** + * 获取表单区块的类型:update 表示是表单编辑区块,create 表示是表单新增区块 + * @returns + */ +export const useFormBlockType = () => { + const ctx = useFormBlockContext() || {}; + return { type: ctx.type } as { type: 'update' | 'create' }; }; export const useIsEmptyRecord = () => { diff --git a/packages/core/client/src/schema-component/antd/association-field/Nester.tsx b/packages/core/client/src/schema-component/antd/association-field/Nester.tsx index 49bb03fda..802bf6f29 100644 --- a/packages/core/client/src/schema-component/antd/association-field/Nester.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/Nester.tsx @@ -6,14 +6,14 @@ import { RecursionField, observer, useFieldSchema } from '@formily/react'; import { action } from '@formily/reactive'; import { each } from '@formily/shared'; import { Button, Card, Divider, Tooltip } from 'antd'; -import _ from 'lodash'; import React, { useCallback, useContext } from 'react'; import { useTranslation } from 'react-i18next'; import { FormActiveFieldsProvider } from '../../../block-provider'; -import { RecordIndexProvider, RecordProvider, useRecord } from '../../../record-provider'; +import { RecordIndexProvider, RecordProvider } from '../../../record-provider'; import { isPatternDisabled, isSystemField } from '../../../schema-settings'; import { DefaultValueProvider, + IsAllowToSetDefaultValueParams, interfacesOfUnsupportedDefaultValue, } from '../../../schema-settings/hooks/useIsAllowToSetDefaultValue'; import { LocalVariablesProvider } from '../../../variables/hooks/useLocalVariables'; @@ -33,40 +33,39 @@ export const Nester = (props) => { const ToOneNester = (props) => { const { field } = useAssociationFieldContext(); - const record = useRecord(); - // 保存原始数据,用于判断是否允许设置默认值 - const recordRef = React.useRef(_.omit(record, '__parent')); - - const isAllowToSetDefaultValue = useCallback(({ form, fieldSchema, collectionField, getInterface }) => { - if (!collectionField) { - if (process.env.NODE_ENV !== 'production') { - console.error(`collectionField should not be ${collectionField}`); + const isAllowToSetDefaultValue = useCallback( + ({ form, fieldSchema, collectionField, getInterface, formBlockType }: IsAllowToSetDefaultValueParams) => { + if (!collectionField) { + if (process.env.NODE_ENV !== 'production') { + console.error(`collectionField should not be ${collectionField}`); + } + return false; } - return false; - } - // 当 Field component 不是下列组件时,不允许设置默认值 - if ( - collectionField.target && - fieldSchema['x-component-props']?.mode && - !['Picker', 'Select'].includes(fieldSchema['x-component-props'].mode) - ) { - return false; - } + // 当 Field component 不是下列组件时,不允许设置默认值 + if ( + collectionField.target && + fieldSchema['x-component-props']?.mode && + !['Picker', 'Select'].includes(fieldSchema['x-component-props'].mode) + ) { + return false; + } - // hasOne 和 belongsTo 类型的字段只能有一个值,不会新增值,所以在编辑状态下不允许设置默认值 - if (!_.isEmpty(recordRef.current)) { - return false; - } + // hasOne 和 belongsTo 类型的字段只能有一个值,不会新增值,所以在编辑状态下不允许设置默认值 + if (formBlockType === 'update') { + return false; + } - return ( - !form?.readPretty && - !isPatternDisabled(fieldSchema) && - !interfacesOfUnsupportedDefaultValue.includes(collectionField?.interface) && - !isSystemField(collectionField, getInterface) - ); - }, []); + return ( + !form?.readPretty && + !isPatternDisabled(fieldSchema) && + !interfacesOfUnsupportedDefaultValue.includes(collectionField?.interface) && + !isSystemField(collectionField, getInterface) + ); + }, + [], + ); return ( diff --git a/packages/core/client/src/schema-component/antd/form-item/FormItem.tsx b/packages/core/client/src/schema-component/antd/form-item/FormItem.tsx index bbf082594..b7d03bbb9 100644 --- a/packages/core/client/src/schema-component/antd/form-item/FormItem.tsx +++ b/packages/core/client/src/schema-component/antd/form-item/FormItem.tsx @@ -27,8 +27,8 @@ import { HTMLEncode } from '../input/shared'; import { useColorFields } from '../table-v2/Table.Column.Designer'; import { FilterFormDesigner } from './FormItem.FilterFormDesigner'; import { useEnsureOperatorsValid } from './SchemaSettingOptions'; -import useLazyLoadAssociationFieldOfForm from './hooks/useLazyLoadAssociationFieldOfForm'; -import useLazyLoadAssociationFieldOfSubForm from './hooks/useLazyLoadAssociationFieldOfSubForm'; +import useLazyLoadDisplayAssociationFieldsOfForm from './hooks/useLazyLoadAssociationFieldOfForm'; +import useLazyLoadAssociationFieldOfForm from './hooks/useLazyLoadAssociationFieldOfSubForm'; import useParseDefaultValue from './hooks/useParseDefaultValue'; export const FormItem: any = observer( @@ -46,8 +46,8 @@ export const FormItem: any = observer( // 需要放在注冊完变量之后 useParseDefaultValue(); + useLazyLoadDisplayAssociationFieldsOfForm(); useLazyLoadAssociationFieldOfForm(); - useLazyLoadAssociationFieldOfSubForm(); useEffect(() => { addActiveFieldName?.(schema.name as string); diff --git a/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadAssociationFieldOfForm.ts b/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadAssociationFieldOfForm.ts index 59ecc4c99..bbc9e5556 100644 --- a/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadAssociationFieldOfForm.ts +++ b/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadAssociationFieldOfForm.ts @@ -7,8 +7,11 @@ import { transformVariableValue } from '../../../../variables/utils/transformVar /** * 用于懒加载 Form 区块中只用于展示的关联字段的值 + * + * - 在表单区块中,有一个 Display association fields 的选项,这里面的字段,只是为了显示出相应的值,不可更改 + * - 这里就是用于加载这些字段的值 */ -const useLazyLoadAssociationFieldOfForm = () => { +const useLazyLoadDisplayAssociationFieldsOfForm = () => { const { name } = useCollection(); const { getCollectionJoinField } = useCollectionManager(); const form = useForm(); @@ -47,4 +50,4 @@ const useLazyLoadAssociationFieldOfForm = () => { }, [schemaName.includes('.') ? form.values[schemaName.split('.')[0]] : null]); }; -export default useLazyLoadAssociationFieldOfForm; +export default useLazyLoadDisplayAssociationFieldsOfForm; diff --git a/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadAssociationFieldOfSubForm.ts b/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadAssociationFieldOfSubForm.ts index 6a5e8925b..8cb7fa1de 100644 --- a/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadAssociationFieldOfSubForm.ts +++ b/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadAssociationFieldOfSubForm.ts @@ -2,16 +2,19 @@ import { Field } from '@formily/core'; import { useField, useFieldSchema } from '@formily/react'; import _ from 'lodash'; import { useEffect } from 'react'; -import { useRecord } from '../../../..'; +import { useFormBlockType, useRecord } from '../../../..'; import { useCollection, useCollectionManager } from '../../../../collection-manager'; import { useFlag } from '../../../../flag-provider'; import { useVariables } from '../../../../variables'; import { transformVariableValue } from '../../../../variables/utils/transformVariableValue'; /** - * 用于懒加载 subForm 区块中的关系字段 + * 用于懒加载 Form 区块中正常的关系字段 + * + * - 当 record 中缺少对应的字段值时,通过解析变量的方法去获取关系字段的值 + * - 注意:应该只有在编辑模式下运行,创建模式下直接返回 */ -const useLazyLoadAssociationFieldOfSubForm = () => { +const useLazyLoadAssociationFieldOfForm = () => { const { name } = useCollection(); const { getCollectionJoinField } = useCollectionManager(); const record = useRecord(); @@ -19,11 +22,12 @@ const useLazyLoadAssociationFieldOfSubForm = () => { const variables = useVariables(); const field = useField(); const { isInAssignFieldValues } = useFlag() || {}; + const { type: formBlockType } = useFormBlockType(); const schemaName = fieldSchema.name.toString(); useEffect(() => { - if (isInAssignFieldValues) { + if (isInAssignFieldValues || formBlockType === 'create') { return; } @@ -59,4 +63,4 @@ const useLazyLoadAssociationFieldOfSubForm = () => { }, [field, name, record, schemaName, isInAssignFieldValues]); }; -export default useLazyLoadAssociationFieldOfSubForm; +export default useLazyLoadAssociationFieldOfForm; diff --git a/packages/core/client/src/schema-component/antd/form-item/hooks/useSpecialCase.ts b/packages/core/client/src/schema-component/antd/form-item/hooks/useSpecialCase.ts index b1a83307b..38a5961ed 100644 --- a/packages/core/client/src/schema-component/antd/form-item/hooks/useSpecialCase.ts +++ b/packages/core/client/src/schema-component/antd/form-item/hooks/useSpecialCase.ts @@ -166,9 +166,7 @@ export const useSubTableSpecialCase = ({ field }) => { field.value = [{}]; // 因为默认值的解析是异步的,所以下面的代码会优先于默认值的设置,这样就防止了设置完默认值后又被清空的问题 setTimeout(() => { - if (JSON.stringify(field.value) === '[{}]') { - field.value = value; - } + field.value = value; }); } }, []); diff --git a/packages/core/client/src/schema-component/antd/form-v2/utils.tsx b/packages/core/client/src/schema-component/antd/form-v2/utils.tsx index 67b4d74ec..588ae4fee 100644 --- a/packages/core/client/src/schema-component/antd/form-v2/utils.tsx +++ b/packages/core/client/src/schema-component/antd/form-v2/utils.tsx @@ -84,9 +84,7 @@ export const linkageMergeAction = async ({ // 2. TODO: 需要把里面解析变量的逻辑删除,因为在上一步已经解析过了 result = evaluate(exp, { ...scope, now: () => new Date().toString(), ...expScope }); } catch (error) { - if (process.env.NODE_ENV !== 'production') { - throw error; - } + console.error(error); } } else if (value?.mode === 'constant') { result = value?.value || value; diff --git a/packages/core/client/src/schema-initializer/items/RecordAssociationFormBlockInitializer.tsx b/packages/core/client/src/schema-initializer/items/RecordAssociationFormBlockInitializer.tsx index 8d342ff0c..1a76b8d20 100644 --- a/packages/core/client/src/schema-initializer/items/RecordAssociationFormBlockInitializer.tsx +++ b/packages/core/client/src/schema-initializer/items/RecordAssociationFormBlockInitializer.tsx @@ -1,5 +1,5 @@ -import { FormOutlined } from '@ant-design/icons'; import React from 'react'; +import { FormOutlined } from '@ant-design/icons'; import { useSchemaTemplateManager } from '../../schema-templates'; import { SchemaInitializer } from '../SchemaInitializer'; diff --git a/packages/core/client/src/schema-settings/hooks/useIsAllowToSetDefaultValue.tsx b/packages/core/client/src/schema-settings/hooks/useIsAllowToSetDefaultValue.tsx index c28fef394..96fc3e9a9 100644 --- a/packages/core/client/src/schema-settings/hooks/useIsAllowToSetDefaultValue.tsx +++ b/packages/core/client/src/schema-settings/hooks/useIsAllowToSetDefaultValue.tsx @@ -1,8 +1,13 @@ import { Form } from '@formily/core'; import { Schema, useFieldSchema } from '@formily/react'; -import _ from 'lodash'; import React, { useContext, useMemo } from 'react'; -import { CollectionFieldOptions, useCollection, useCollectionManager, useFormBlockContext, useRecord } from '../..'; +import { + CollectionFieldOptions, + useCollection, + useCollectionManager, + useFormBlockContext, + useFormBlockType, +} from '../..'; import { isPatternDisabled, isSystemField } from '../SchemaSettings'; interface DefaultValueProviderProps { @@ -10,15 +15,12 @@ interface DefaultValueProviderProps { children: React.ReactNode; } -interface IsAllowToSetDefaultValueParams { +export interface IsAllowToSetDefaultValueParams { collectionField: CollectionFieldOptions; getInterface: (name: string) => any; + formBlockType?: 'update' | 'create'; form: Form; fieldSchema: Schema; - /** - * `useRecord` 返回的值 - */ - record: Record; isSubTableColumn?: boolean; } @@ -26,7 +28,6 @@ interface Props { form?: Form; fieldSchema?: Schema; collectionField?: CollectionFieldOptions; - record?: Record; } const DefaultValueContext = React.createContext>(null); @@ -41,12 +42,12 @@ export const DefaultValueProvider = (props: DefaultValueProviderProps) => { return {props.children}; }; -const useIsAllowToSetDefaultValue = ({ form, fieldSchema, collectionField, record }: Props = {}) => { +const useIsAllowToSetDefaultValue = ({ form, fieldSchema, collectionField }: Props = {}) => { const { getInterface, getCollectionJoinField } = useCollectionManager(); const { getField } = useCollection(); const { form: innerForm } = useFormBlockContext(); const innerFieldSchema = useFieldSchema(); - const innerRecord = useRecord(); + const { type } = useFormBlockType(); const { isAllowToSetDefaultValue = _isAllowToSetDefaultValue } = useContext(DefaultValueContext) || {}; const innerCollectionField = @@ -58,8 +59,8 @@ const useIsAllowToSetDefaultValue = ({ form, fieldSchema, collectionField, recor collectionField: collectionField || innerCollectionField, getInterface, form: form || innerForm, + formBlockType: type, fieldSchema: fieldSchema || innerFieldSchema, - record: record || innerRecord, isSubTableColumn, }); }, @@ -86,9 +87,9 @@ export const interfacesOfUnsupportedDefaultValue = [ function _isAllowToSetDefaultValue({ collectionField, getInterface, + formBlockType, form, fieldSchema, - record, isSubTableColumn, }: IsAllowToSetDefaultValueParams) { if (isSubTableColumn) { @@ -114,10 +115,8 @@ function _isAllowToSetDefaultValue({ return false; } - record = _.omit(record, '__parent'); - // 表单编辑状态下,不允许设置默认值 - if (!_.isEmpty(record)) { + if (formBlockType === 'update') { return false; }