fix(subTable): should clear form value after submit (#3508)
* fix(subTable): should clear form value after submit * test: add test
This commit is contained in:
parent
869bf4a621
commit
28eae4a85b
@ -1,7 +1,7 @@
|
|||||||
import { SchemaExpressionScopeContext, useField, useFieldSchema, useForm } from '@formily/react';
|
import { SchemaExpressionScopeContext, useField, useFieldSchema, useForm } from '@formily/react';
|
||||||
import { isURL, parse } from '@nocobase/utils/client';
|
import { isURL, parse } from '@nocobase/utils/client';
|
||||||
import { App, message } from 'antd';
|
import { App, message } from 'antd';
|
||||||
import _, { cloneDeep } from 'lodash';
|
import _ from 'lodash';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import omit from 'lodash/omit';
|
import omit from 'lodash/omit';
|
||||||
import { ChangeEvent, useCallback, useContext, useEffect } from 'react';
|
import { ChangeEvent, useCallback, useContext, useEffect } from 'react';
|
||||||
@ -212,14 +212,14 @@ export const useCreateActionProps = () => {
|
|||||||
__parent?.service?.refresh?.();
|
__parent?.service?.refresh?.();
|
||||||
if (!onSuccess?.successMessage) {
|
if (!onSuccess?.successMessage) {
|
||||||
message.success(t('Saved successfully'));
|
message.success(t('Saved successfully'));
|
||||||
await form.reset();
|
await form.reset(undefined, { forceClear: true });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (onSuccess?.manualClose) {
|
if (onSuccess?.manualClose) {
|
||||||
modal.success({
|
modal.success({
|
||||||
title: compile(onSuccess?.successMessage),
|
title: compile(onSuccess?.successMessage),
|
||||||
onOk: async () => {
|
onOk: async () => {
|
||||||
await form.reset();
|
await form.reset(undefined, { forceClear: true });
|
||||||
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
|
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
|
||||||
if (isURL(onSuccess.redirectTo)) {
|
if (isURL(onSuccess.redirectTo)) {
|
||||||
window.location.href = onSuccess.redirectTo;
|
window.location.href = onSuccess.redirectTo;
|
||||||
@ -231,7 +231,7 @@ export const useCreateActionProps = () => {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
message.success(compile(onSuccess?.successMessage));
|
message.success(compile(onSuccess?.successMessage));
|
||||||
await form.reset();
|
await form.reset(undefined, { forceClear: true });
|
||||||
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
|
if (onSuccess?.redirecting && onSuccess?.redirectTo) {
|
||||||
if (isURL(onSuccess.redirectTo)) {
|
if (isURL(onSuccess.redirectTo)) {
|
||||||
window.location.href = onSuccess.redirectTo;
|
window.location.href = onSuccess.redirectTo;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { createBlockInPage, expect, oneEmptyForm, test } from '@nocobase/test/e2e';
|
import { createBlockInPage, expect, oneEmptyForm, test } from '@nocobase/test/e2e';
|
||||||
|
import { T3106 } from './templatesOfBug';
|
||||||
|
|
||||||
test.describe('where creation form block can be added', () => {
|
test.describe('where creation form block can be added', () => {
|
||||||
test('page', async ({ page, mockPage }) => {
|
test('page', async ({ page, mockPage }) => {
|
||||||
@ -78,6 +79,28 @@ test.describe('configure actions', () => {
|
|||||||
await expect(page.getByRole('button', { name: 'Submit' })).not.toBeVisible();
|
await expect(page.getByRole('button', { name: 'Submit' })).not.toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// https://nocobase.height.app/T-3106
|
||||||
|
test('subTable: should clear form value after submit', async ({ page, mockPage }) => {
|
||||||
|
await mockPage(T3106).goto();
|
||||||
|
|
||||||
|
await page.getByRole('button', { name: 'Add new' }).click();
|
||||||
|
await expect(
|
||||||
|
page.getByLabel('block-item-CollectionField-users-form-users.nickname-Nickname').getByRole('textbox'),
|
||||||
|
).toHaveValue('test name');
|
||||||
|
|
||||||
|
// 点击提交后,应该清空子表格中的值
|
||||||
|
await page.getByLabel('action-Action-Submit-submit-').click();
|
||||||
|
await expect(
|
||||||
|
page.getByLabel('block-item-CollectionField-users-form-users.nickname-Nickname').getByRole('textbox'),
|
||||||
|
).toBeHidden();
|
||||||
|
|
||||||
|
// 再次点击添加按钮,默认值应该正常显示出来
|
||||||
|
await page.getByRole('button', { name: 'Add new' }).click();
|
||||||
|
await expect(
|
||||||
|
page.getByLabel('block-item-CollectionField-users-form-users.nickname-Nickname').getByRole('textbox'),
|
||||||
|
).toHaveValue('test name');
|
||||||
|
});
|
||||||
|
|
||||||
test('customize: save record', async ({ page, mockPage }) => {
|
test('customize: save record', async ({ page, mockPage }) => {
|
||||||
await mockPage(oneEmptyForm).goto();
|
await mockPage(oneEmptyForm).goto();
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { PageConfig } from '@nocobase/test/e2e';
|
import { PageConfig, generalWithM2oSingleSelect } from '@nocobase/test/e2e';
|
||||||
|
|
||||||
export const T2165 = {
|
export const T2165 = {
|
||||||
pageSchema: {
|
pageSchema: {
|
||||||
@ -5024,3 +5024,225 @@ export const T2200 = {
|
|||||||
'x-index': 1,
|
'x-index': 1,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const T3106: PageConfig = {
|
||||||
|
collections: generalWithM2oSingleSelect,
|
||||||
|
pageSchema: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Page',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
'1lqiou007g2': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-initializer': 'BlockInitializers',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
cxk2aa058lc: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
'4ulo13u15kt': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
'5mflo02rgff': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-acl-action-props': {
|
||||||
|
skipScopeCheck: true,
|
||||||
|
},
|
||||||
|
'x-acl-action': 'general:create',
|
||||||
|
'x-decorator': 'FormBlockProvider',
|
||||||
|
'x-decorator-props': {
|
||||||
|
resource: 'general',
|
||||||
|
collection: 'general',
|
||||||
|
},
|
||||||
|
'x-designer': 'FormV2.Designer',
|
||||||
|
'x-component': 'CardItem',
|
||||||
|
'x-component-props': {},
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
ucvfcgnna36: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'FormV2',
|
||||||
|
'x-component-props': {
|
||||||
|
useProps: '{{ useFormBlockProps }}',
|
||||||
|
},
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
grid: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-initializer': 'FormItemInitializers',
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
wbvuzjzl83g: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
properties: {
|
||||||
|
azpa6sirla4: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
properties: {
|
||||||
|
oneToMany: {
|
||||||
|
'x-uid': 'eia8l8nfir4',
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'string',
|
||||||
|
'x-designer': 'FormItem.Designer',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-collection-field': 'general.oneToMany',
|
||||||
|
'x-component-props': {
|
||||||
|
mode: 'SubTable',
|
||||||
|
},
|
||||||
|
default: null,
|
||||||
|
properties: {
|
||||||
|
'7lmlkxgw1b5': {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'AssociationField.SubTable',
|
||||||
|
'x-initializer': 'TableColumnInitializers',
|
||||||
|
'x-initializer-props': {
|
||||||
|
action: false,
|
||||||
|
},
|
||||||
|
'x-index': 1,
|
||||||
|
properties: {
|
||||||
|
ymdcw5r51n4: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-decorator': 'TableV2.Column.Decorator',
|
||||||
|
'x-designer': 'TableV2.Column.Designer',
|
||||||
|
'x-component': 'TableV2.Column',
|
||||||
|
properties: {
|
||||||
|
nickname: {
|
||||||
|
'x-uid': 'mb9f1rt5ntz',
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
'x-collection-field': 'users.nickname',
|
||||||
|
'x-component': 'CollectionField',
|
||||||
|
'x-component-props': {
|
||||||
|
ellipsis: true,
|
||||||
|
},
|
||||||
|
'x-decorator': 'FormItem',
|
||||||
|
'x-decorator-props': {
|
||||||
|
labelStyle: {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default: 'test name',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'jfom9bv2q4x',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '050ngca24nq',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'wtb8ez642ve',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'u8bc0cw1f3d',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'qz6evwj5dg0',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
'x-initializer': 'FormActionInitializers',
|
||||||
|
'x-component': 'ActionBar',
|
||||||
|
'x-component-props': {
|
||||||
|
layout: 'one-column',
|
||||||
|
style: {
|
||||||
|
marginTop: 24,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-index': 2,
|
||||||
|
properties: {
|
||||||
|
rzvo5hzdj7o: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
title: '{{ t("Submit") }}',
|
||||||
|
'x-action': 'submit',
|
||||||
|
'x-component': 'Action',
|
||||||
|
'x-designer': 'Action.Designer',
|
||||||
|
'x-component-props': {
|
||||||
|
type: 'primary',
|
||||||
|
htmlType: 'submit',
|
||||||
|
useProps: '{{ useCreateActionProps }}',
|
||||||
|
},
|
||||||
|
'x-action-settings': {
|
||||||
|
triggerWorkflows: [],
|
||||||
|
},
|
||||||
|
type: 'void',
|
||||||
|
'x-uid': 'rju16bgspem',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'gahv9zkc6v3',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '93hi2qyh1ku',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'y2pyetixul3',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '2zy0gr02px1',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': '80kyofmv32j',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'dtvu1pmc6um',
|
||||||
|
'x-async': false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'x-uid': 'i10t0bkpvlq',
|
||||||
|
'x-async': true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
@ -25,7 +25,8 @@ const useParseDefaultValue = () => {
|
|||||||
const variables = useVariables();
|
const variables = useVariables();
|
||||||
const localVariables = useLocalVariables();
|
const localVariables = useLocalVariables();
|
||||||
const record = useRecord();
|
const record = useRecord();
|
||||||
const { isInAssignFieldValues, isInSetDefaultValueDialog, isInFormDataTemplate, isInSubTable } = useFlag() || {};
|
const { isInAssignFieldValues, isInSetDefaultValueDialog, isInFormDataTemplate, isInSubTable, isInSubForm } =
|
||||||
|
useFlag() || {};
|
||||||
const { getField } = useCollection();
|
const { getField } = useCollection();
|
||||||
const { isSpecialCase, setDefaultValue } = useSpecialCase();
|
const { isSpecialCase, setDefaultValue } = useSpecialCase();
|
||||||
const index = useRecordIndex();
|
const index = useRecordIndex();
|
||||||
@ -135,6 +136,9 @@ const useParseDefaultValue = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return dispose;
|
return dispose;
|
||||||
|
} else if (field.value == null && (isInSubTable || isInSubForm)) {
|
||||||
|
// 解决子表格(或子表单)中新增一行数据时,默认值不生效的问题
|
||||||
|
field.setValue(fieldSchema.default);
|
||||||
}
|
}
|
||||||
}, [fieldSchema.default]);
|
}, [fieldSchema.default]);
|
||||||
};
|
};
|
||||||
|
@ -346,7 +346,7 @@ export const Table: any = observer(
|
|||||||
}, [field, onRowDragEnd, dragSort]);
|
}, [field, onRowDragEnd, dragSort]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 为没有设置 key 属性的 record 生成一个唯一的 key
|
* 为没有设置 key 属性的表格行生成一个唯一的 key
|
||||||
* 1. rowKey 的默认值是 “key”,所以先判断有没有 record.key;
|
* 1. rowKey 的默认值是 “key”,所以先判断有没有 record.key;
|
||||||
* 2. 如果没有就生成一个唯一的 key,并以 record 的值作为索引;
|
* 2. 如果没有就生成一个唯一的 key,并以 record 的值作为索引;
|
||||||
* 3. 这样下次就能取到对应的 key 的值;
|
* 3. 这样下次就能取到对应的 key 的值;
|
||||||
|
Loading…
Reference in New Issue
Block a user