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 0140e623a6
.
* 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>
This commit is contained in:
parent
af32a4e59a
commit
87a8b2e844
368
packages/core/client/src/__tests__/e2e/bugs/T-2187.test.ts
Normal file
368
packages/core/client/src/__tests__/e2e/bugs/T-2187.test.ts
Normal file
@ -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();
|
||||
});
|
@ -13,7 +13,7 @@ import { FormActiveFieldsProvider } from './hooks';
|
||||
export const FormBlockContext = createContext<any>({});
|
||||
|
||||
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 ? (
|
||||
<RecordProvider parent={isEmpty(record?.__parent) ? record : record?.__parent} record={service?.data?.data}>
|
||||
<div ref={formBlockRef}>
|
||||
<RenderChildrenWithDataTemplates form={form} />
|
||||
</div>
|
||||
</RecordProvider>
|
||||
) : (
|
||||
<div ref={formBlockRef}>
|
||||
<RenderChildrenWithDataTemplates form={form} />
|
||||
</div>
|
||||
)}
|
||||
</FormBlockContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
function normalBlock(): React.ReactNode {
|
||||
return readPretty ? (
|
||||
<RecordProvider parent={isEmpty(record?.__parent) ? record : record?.__parent} record={service?.data?.data}>
|
||||
<div ref={formBlockRef}>
|
||||
<RenderChildrenWithDataTemplates form={form} />
|
||||
</div>
|
||||
</RecordProvider>
|
||||
) : (
|
||||
<div ref={formBlockRef}>
|
||||
<RenderChildrenWithDataTemplates form={form} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 这里的 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 ? (
|
||||
<RecordProvider parent={isEmpty(record?.__parent) ? record : record?.__parent} record={service?.data?.data}>
|
||||
<div ref={formBlockRef}>
|
||||
<RenderChildrenWithDataTemplates form={form} />
|
||||
</div>
|
||||
</RecordProvider>
|
||||
) : (
|
||||
<RecordProvider parent={isEmpty(record?.__parent) ? record : record?.__parent} record={{}}>
|
||||
<div ref={formBlockRef}>
|
||||
<RenderChildrenWithDataTemplates form={form} />
|
||||
</div>
|
||||
</RecordProvider>
|
||||
);
|
||||
}
|
||||
/**
|
||||
* 获取表单区块的类型:update 表示是表单编辑区块,create 表示是表单新增区块
|
||||
* @returns
|
||||
*/
|
||||
export const useFormBlockType = () => {
|
||||
const ctx = useFormBlockContext() || {};
|
||||
return { type: ctx.type } as { type: 'update' | 'create' };
|
||||
};
|
||||
|
||||
export const useIsEmptyRecord = () => {
|
||||
|
@ -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<ArrayField>();
|
||||
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 (
|
||||
<FormActiveFieldsProvider name="nester">
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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<Field>();
|
||||
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;
|
||||
|
@ -166,9 +166,7 @@ export const useSubTableSpecialCase = ({ field }) => {
|
||||
field.value = [{}];
|
||||
// 因为默认值的解析是异步的,所以下面的代码会优先于默认值的设置,这样就防止了设置完默认值后又被清空的问题
|
||||
setTimeout(() => {
|
||||
if (JSON.stringify(field.value) === '[{}]') {
|
||||
field.value = value;
|
||||
}
|
||||
field.value = value;
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
@ -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;
|
||||
|
@ -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';
|
||||
|
@ -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<any, any, any, any, any, any, any, any, any>;
|
||||
/**
|
||||
* `useRecord` 返回的值
|
||||
*/
|
||||
record: Record<string, any>;
|
||||
isSubTableColumn?: boolean;
|
||||
}
|
||||
|
||||
@ -26,7 +28,6 @@ interface Props {
|
||||
form?: Form;
|
||||
fieldSchema?: Schema<any, any, any, any, any, any, any, any, any>;
|
||||
collectionField?: CollectionFieldOptions;
|
||||
record?: Record<string, any>;
|
||||
}
|
||||
|
||||
const DefaultValueContext = React.createContext<Omit<DefaultValueProviderProps, 'children'>>(null);
|
||||
@ -41,12 +42,12 @@ export const DefaultValueProvider = (props: DefaultValueProviderProps) => {
|
||||
return <DefaultValueContext.Provider value={value}>{props.children}</DefaultValueContext.Provider>;
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user