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>({});
|
export const FormBlockContext = createContext<any>({});
|
||||||
|
|
||||||
const InternalFormBlockProvider = (props) => {
|
const InternalFormBlockProvider = (props) => {
|
||||||
const { action, readPretty, params, association } = props;
|
const { action, readPretty, params } = props;
|
||||||
const field = useField();
|
const field = useField();
|
||||||
const form = useMemo(
|
const form = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@ -35,6 +35,8 @@ const InternalFormBlockProvider = (props) => {
|
|||||||
params,
|
params,
|
||||||
action,
|
action,
|
||||||
form,
|
form,
|
||||||
|
// update 表示是表单编辑区块,create 表示是表单新增区块
|
||||||
|
type: action === 'get' ? 'update' : 'create',
|
||||||
field,
|
field,
|
||||||
service,
|
service,
|
||||||
resource,
|
resource,
|
||||||
@ -42,46 +44,28 @@ const InternalFormBlockProvider = (props) => {
|
|||||||
formBlockRef,
|
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>
|
</FormBlockContext.Provider>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
function normalBlock(): React.ReactNode {
|
/**
|
||||||
return readPretty ? (
|
* 获取表单区块的类型:update 表示是表单编辑区块,create 表示是表单新增区块
|
||||||
<RecordProvider parent={isEmpty(record?.__parent) ? record : record?.__parent} record={service?.data?.data}>
|
* @returns
|
||||||
<div ref={formBlockRef}>
|
*/
|
||||||
<RenderChildrenWithDataTemplates form={form} />
|
export const useFormBlockType = () => {
|
||||||
</div>
|
const ctx = useFormBlockContext() || {};
|
||||||
</RecordProvider>
|
return { type: ctx.type } as { type: 'update' | 'create' };
|
||||||
) : (
|
|
||||||
<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>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useIsEmptyRecord = () => {
|
export const useIsEmptyRecord = () => {
|
||||||
|
@ -6,14 +6,14 @@ import { RecursionField, observer, useFieldSchema } from '@formily/react';
|
|||||||
import { action } from '@formily/reactive';
|
import { action } from '@formily/reactive';
|
||||||
import { each } from '@formily/shared';
|
import { each } from '@formily/shared';
|
||||||
import { Button, Card, Divider, Tooltip } from 'antd';
|
import { Button, Card, Divider, Tooltip } from 'antd';
|
||||||
import _ from 'lodash';
|
|
||||||
import React, { useCallback, useContext } from 'react';
|
import React, { useCallback, useContext } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FormActiveFieldsProvider } from '../../../block-provider';
|
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 { isPatternDisabled, isSystemField } from '../../../schema-settings';
|
||||||
import {
|
import {
|
||||||
DefaultValueProvider,
|
DefaultValueProvider,
|
||||||
|
IsAllowToSetDefaultValueParams,
|
||||||
interfacesOfUnsupportedDefaultValue,
|
interfacesOfUnsupportedDefaultValue,
|
||||||
} from '../../../schema-settings/hooks/useIsAllowToSetDefaultValue';
|
} from '../../../schema-settings/hooks/useIsAllowToSetDefaultValue';
|
||||||
import { LocalVariablesProvider } from '../../../variables/hooks/useLocalVariables';
|
import { LocalVariablesProvider } from '../../../variables/hooks/useLocalVariables';
|
||||||
@ -33,12 +33,9 @@ export const Nester = (props) => {
|
|||||||
|
|
||||||
const ToOneNester = (props) => {
|
const ToOneNester = (props) => {
|
||||||
const { field } = useAssociationFieldContext<ArrayField>();
|
const { field } = useAssociationFieldContext<ArrayField>();
|
||||||
const record = useRecord();
|
|
||||||
|
|
||||||
// 保存原始数据,用于判断是否允许设置默认值
|
const isAllowToSetDefaultValue = useCallback(
|
||||||
const recordRef = React.useRef(_.omit(record, '__parent'));
|
({ form, fieldSchema, collectionField, getInterface, formBlockType }: IsAllowToSetDefaultValueParams) => {
|
||||||
|
|
||||||
const isAllowToSetDefaultValue = useCallback(({ form, fieldSchema, collectionField, getInterface }) => {
|
|
||||||
if (!collectionField) {
|
if (!collectionField) {
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
console.error(`collectionField should not be ${collectionField}`);
|
console.error(`collectionField should not be ${collectionField}`);
|
||||||
@ -56,7 +53,7 @@ const ToOneNester = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// hasOne 和 belongsTo 类型的字段只能有一个值,不会新增值,所以在编辑状态下不允许设置默认值
|
// hasOne 和 belongsTo 类型的字段只能有一个值,不会新增值,所以在编辑状态下不允许设置默认值
|
||||||
if (!_.isEmpty(recordRef.current)) {
|
if (formBlockType === 'update') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +63,9 @@ const ToOneNester = (props) => {
|
|||||||
!interfacesOfUnsupportedDefaultValue.includes(collectionField?.interface) &&
|
!interfacesOfUnsupportedDefaultValue.includes(collectionField?.interface) &&
|
||||||
!isSystemField(collectionField, getInterface)
|
!isSystemField(collectionField, getInterface)
|
||||||
);
|
);
|
||||||
}, []);
|
},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormActiveFieldsProvider name="nester">
|
<FormActiveFieldsProvider name="nester">
|
||||||
|
@ -27,8 +27,8 @@ import { HTMLEncode } from '../input/shared';
|
|||||||
import { useColorFields } from '../table-v2/Table.Column.Designer';
|
import { useColorFields } from '../table-v2/Table.Column.Designer';
|
||||||
import { FilterFormDesigner } from './FormItem.FilterFormDesigner';
|
import { FilterFormDesigner } from './FormItem.FilterFormDesigner';
|
||||||
import { useEnsureOperatorsValid } from './SchemaSettingOptions';
|
import { useEnsureOperatorsValid } from './SchemaSettingOptions';
|
||||||
import useLazyLoadAssociationFieldOfForm from './hooks/useLazyLoadAssociationFieldOfForm';
|
import useLazyLoadDisplayAssociationFieldsOfForm from './hooks/useLazyLoadAssociationFieldOfForm';
|
||||||
import useLazyLoadAssociationFieldOfSubForm from './hooks/useLazyLoadAssociationFieldOfSubForm';
|
import useLazyLoadAssociationFieldOfForm from './hooks/useLazyLoadAssociationFieldOfSubForm';
|
||||||
import useParseDefaultValue from './hooks/useParseDefaultValue';
|
import useParseDefaultValue from './hooks/useParseDefaultValue';
|
||||||
|
|
||||||
export const FormItem: any = observer(
|
export const FormItem: any = observer(
|
||||||
@ -46,8 +46,8 @@ export const FormItem: any = observer(
|
|||||||
|
|
||||||
// 需要放在注冊完变量之后
|
// 需要放在注冊完变量之后
|
||||||
useParseDefaultValue();
|
useParseDefaultValue();
|
||||||
|
useLazyLoadDisplayAssociationFieldsOfForm();
|
||||||
useLazyLoadAssociationFieldOfForm();
|
useLazyLoadAssociationFieldOfForm();
|
||||||
useLazyLoadAssociationFieldOfSubForm();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
addActiveFieldName?.(schema.name as string);
|
addActiveFieldName?.(schema.name as string);
|
||||||
|
@ -7,8 +7,11 @@ import { transformVariableValue } from '../../../../variables/utils/transformVar
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于懒加载 Form 区块中只用于展示的关联字段的值
|
* 用于懒加载 Form 区块中只用于展示的关联字段的值
|
||||||
|
*
|
||||||
|
* - 在表单区块中,有一个 Display association fields 的选项,这里面的字段,只是为了显示出相应的值,不可更改
|
||||||
|
* - 这里就是用于加载这些字段的值
|
||||||
*/
|
*/
|
||||||
const useLazyLoadAssociationFieldOfForm = () => {
|
const useLazyLoadDisplayAssociationFieldsOfForm = () => {
|
||||||
const { name } = useCollection();
|
const { name } = useCollection();
|
||||||
const { getCollectionJoinField } = useCollectionManager();
|
const { getCollectionJoinField } = useCollectionManager();
|
||||||
const form = useForm();
|
const form = useForm();
|
||||||
@ -47,4 +50,4 @@ const useLazyLoadAssociationFieldOfForm = () => {
|
|||||||
}, [schemaName.includes('.') ? form.values[schemaName.split('.')[0]] : null]);
|
}, [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 { useField, useFieldSchema } from '@formily/react';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useRecord } from '../../../..';
|
import { useFormBlockType, useRecord } from '../../../..';
|
||||||
import { useCollection, useCollectionManager } from '../../../../collection-manager';
|
import { useCollection, useCollectionManager } from '../../../../collection-manager';
|
||||||
import { useFlag } from '../../../../flag-provider';
|
import { useFlag } from '../../../../flag-provider';
|
||||||
import { useVariables } from '../../../../variables';
|
import { useVariables } from '../../../../variables';
|
||||||
import { transformVariableValue } from '../../../../variables/utils/transformVariableValue';
|
import { transformVariableValue } from '../../../../variables/utils/transformVariableValue';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用于懒加载 subForm 区块中的关系字段
|
* 用于懒加载 Form 区块中正常的关系字段
|
||||||
|
*
|
||||||
|
* - 当 record 中缺少对应的字段值时,通过解析变量的方法去获取关系字段的值
|
||||||
|
* - 注意:应该只有在编辑模式下运行,创建模式下直接返回
|
||||||
*/
|
*/
|
||||||
const useLazyLoadAssociationFieldOfSubForm = () => {
|
const useLazyLoadAssociationFieldOfForm = () => {
|
||||||
const { name } = useCollection();
|
const { name } = useCollection();
|
||||||
const { getCollectionJoinField } = useCollectionManager();
|
const { getCollectionJoinField } = useCollectionManager();
|
||||||
const record = useRecord();
|
const record = useRecord();
|
||||||
@ -19,11 +22,12 @@ const useLazyLoadAssociationFieldOfSubForm = () => {
|
|||||||
const variables = useVariables();
|
const variables = useVariables();
|
||||||
const field = useField<Field>();
|
const field = useField<Field>();
|
||||||
const { isInAssignFieldValues } = useFlag() || {};
|
const { isInAssignFieldValues } = useFlag() || {};
|
||||||
|
const { type: formBlockType } = useFormBlockType();
|
||||||
|
|
||||||
const schemaName = fieldSchema.name.toString();
|
const schemaName = fieldSchema.name.toString();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isInAssignFieldValues) {
|
if (isInAssignFieldValues || formBlockType === 'create') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,4 +63,4 @@ const useLazyLoadAssociationFieldOfSubForm = () => {
|
|||||||
}, [field, name, record, schemaName, isInAssignFieldValues]);
|
}, [field, name, record, schemaName, isInAssignFieldValues]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default useLazyLoadAssociationFieldOfSubForm;
|
export default useLazyLoadAssociationFieldOfForm;
|
||||||
|
@ -166,9 +166,7 @@ export const useSubTableSpecialCase = ({ field }) => {
|
|||||||
field.value = [{}];
|
field.value = [{}];
|
||||||
// 因为默认值的解析是异步的,所以下面的代码会优先于默认值的设置,这样就防止了设置完默认值后又被清空的问题
|
// 因为默认值的解析是异步的,所以下面的代码会优先于默认值的设置,这样就防止了设置完默认值后又被清空的问题
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (JSON.stringify(field.value) === '[{}]') {
|
|
||||||
field.value = value;
|
field.value = value;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
@ -84,9 +84,7 @@ export const linkageMergeAction = async ({
|
|||||||
// 2. TODO: 需要把里面解析变量的逻辑删除,因为在上一步已经解析过了
|
// 2. TODO: 需要把里面解析变量的逻辑删除,因为在上一步已经解析过了
|
||||||
result = evaluate(exp, { ...scope, now: () => new Date().toString(), ...expScope });
|
result = evaluate(exp, { ...scope, now: () => new Date().toString(), ...expScope });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
console.error(error);
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (value?.mode === 'constant') {
|
} else if (value?.mode === 'constant') {
|
||||||
result = value?.value || value;
|
result = value?.value || value;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { FormOutlined } from '@ant-design/icons';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { FormOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
import { useSchemaTemplateManager } from '../../schema-templates';
|
import { useSchemaTemplateManager } from '../../schema-templates';
|
||||||
import { SchemaInitializer } from '../SchemaInitializer';
|
import { SchemaInitializer } from '../SchemaInitializer';
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
import { Form } from '@formily/core';
|
import { Form } from '@formily/core';
|
||||||
import { Schema, useFieldSchema } from '@formily/react';
|
import { Schema, useFieldSchema } from '@formily/react';
|
||||||
import _ from 'lodash';
|
|
||||||
import React, { useContext, useMemo } from 'react';
|
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';
|
import { isPatternDisabled, isSystemField } from '../SchemaSettings';
|
||||||
|
|
||||||
interface DefaultValueProviderProps {
|
interface DefaultValueProviderProps {
|
||||||
@ -10,15 +15,12 @@ interface DefaultValueProviderProps {
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IsAllowToSetDefaultValueParams {
|
export interface IsAllowToSetDefaultValueParams {
|
||||||
collectionField: CollectionFieldOptions;
|
collectionField: CollectionFieldOptions;
|
||||||
getInterface: (name: string) => any;
|
getInterface: (name: string) => any;
|
||||||
|
formBlockType?: 'update' | 'create';
|
||||||
form: Form;
|
form: Form;
|
||||||
fieldSchema: Schema<any, any, any, any, any, any, any, any, any>;
|
fieldSchema: Schema<any, any, any, any, any, any, any, any, any>;
|
||||||
/**
|
|
||||||
* `useRecord` 返回的值
|
|
||||||
*/
|
|
||||||
record: Record<string, any>;
|
|
||||||
isSubTableColumn?: boolean;
|
isSubTableColumn?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +28,6 @@ interface Props {
|
|||||||
form?: Form;
|
form?: Form;
|
||||||
fieldSchema?: Schema<any, any, any, any, any, any, any, any, any>;
|
fieldSchema?: Schema<any, any, any, any, any, any, any, any, any>;
|
||||||
collectionField?: CollectionFieldOptions;
|
collectionField?: CollectionFieldOptions;
|
||||||
record?: Record<string, any>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DefaultValueContext = React.createContext<Omit<DefaultValueProviderProps, 'children'>>(null);
|
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>;
|
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 { getInterface, getCollectionJoinField } = useCollectionManager();
|
||||||
const { getField } = useCollection();
|
const { getField } = useCollection();
|
||||||
const { form: innerForm } = useFormBlockContext();
|
const { form: innerForm } = useFormBlockContext();
|
||||||
const innerFieldSchema = useFieldSchema();
|
const innerFieldSchema = useFieldSchema();
|
||||||
const innerRecord = useRecord();
|
const { type } = useFormBlockType();
|
||||||
const { isAllowToSetDefaultValue = _isAllowToSetDefaultValue } = useContext(DefaultValueContext) || {};
|
const { isAllowToSetDefaultValue = _isAllowToSetDefaultValue } = useContext(DefaultValueContext) || {};
|
||||||
|
|
||||||
const innerCollectionField =
|
const innerCollectionField =
|
||||||
@ -58,8 +59,8 @@ const useIsAllowToSetDefaultValue = ({ form, fieldSchema, collectionField, recor
|
|||||||
collectionField: collectionField || innerCollectionField,
|
collectionField: collectionField || innerCollectionField,
|
||||||
getInterface,
|
getInterface,
|
||||||
form: form || innerForm,
|
form: form || innerForm,
|
||||||
|
formBlockType: type,
|
||||||
fieldSchema: fieldSchema || innerFieldSchema,
|
fieldSchema: fieldSchema || innerFieldSchema,
|
||||||
record: record || innerRecord,
|
|
||||||
isSubTableColumn,
|
isSubTableColumn,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -86,9 +87,9 @@ export const interfacesOfUnsupportedDefaultValue = [
|
|||||||
function _isAllowToSetDefaultValue({
|
function _isAllowToSetDefaultValue({
|
||||||
collectionField,
|
collectionField,
|
||||||
getInterface,
|
getInterface,
|
||||||
|
formBlockType,
|
||||||
form,
|
form,
|
||||||
fieldSchema,
|
fieldSchema,
|
||||||
record,
|
|
||||||
isSubTableColumn,
|
isSubTableColumn,
|
||||||
}: IsAllowToSetDefaultValueParams) {
|
}: IsAllowToSetDefaultValueParams) {
|
||||||
if (isSubTableColumn) {
|
if (isSubTableColumn) {
|
||||||
@ -114,10 +115,8 @@ function _isAllowToSetDefaultValue({
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
record = _.omit(record, '__parent');
|
|
||||||
|
|
||||||
// 表单编辑状态下,不允许设置默认值
|
// 表单编辑状态下,不允许设置默认值
|
||||||
if (!_.isEmpty(record)) {
|
if (formBlockType === 'update') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user