From 28eae4a85b5e0c00f4ca4c6f89d0032d3106b4ce Mon Sep 17 00:00:00 2001 From: Zeke Zhang <958414905@qq.com> Date: Fri, 16 Feb 2024 08:48:37 +0800 Subject: [PATCH] fix(subTable): should clear form value after submit (#3508) * fix(subTable): should clear form value after submit * test: add test --- .../client/src/block-provider/hooks/index.ts | 8 +- .../__e2e__/schemaInitializer.test.ts | 23 ++ .../form-creation/__e2e__/templatesOfBug.ts | 224 +++++++++++++++++- .../form-item/hooks/useParseDefaultValue.ts | 6 +- .../schema-component/antd/table-v2/Table.tsx | 2 +- 5 files changed, 256 insertions(+), 7 deletions(-) diff --git a/packages/core/client/src/block-provider/hooks/index.ts b/packages/core/client/src/block-provider/hooks/index.ts index 073aef8c9..5122f6928 100644 --- a/packages/core/client/src/block-provider/hooks/index.ts +++ b/packages/core/client/src/block-provider/hooks/index.ts @@ -1,7 +1,7 @@ import { SchemaExpressionScopeContext, useField, useFieldSchema, useForm } from '@formily/react'; import { isURL, parse } from '@nocobase/utils/client'; import { App, message } from 'antd'; -import _, { cloneDeep } from 'lodash'; +import _ from 'lodash'; import get from 'lodash/get'; import omit from 'lodash/omit'; import { ChangeEvent, useCallback, useContext, useEffect } from 'react'; @@ -212,14 +212,14 @@ export const useCreateActionProps = () => { __parent?.service?.refresh?.(); if (!onSuccess?.successMessage) { message.success(t('Saved successfully')); - await form.reset(); + await form.reset(undefined, { forceClear: true }); return; } if (onSuccess?.manualClose) { modal.success({ title: compile(onSuccess?.successMessage), onOk: async () => { - await form.reset(); + await form.reset(undefined, { forceClear: true }); if (onSuccess?.redirecting && onSuccess?.redirectTo) { if (isURL(onSuccess.redirectTo)) { window.location.href = onSuccess.redirectTo; @@ -231,7 +231,7 @@ export const useCreateActionProps = () => { }); } else { message.success(compile(onSuccess?.successMessage)); - await form.reset(); + await form.reset(undefined, { forceClear: true }); if (onSuccess?.redirecting && onSuccess?.redirectTo) { if (isURL(onSuccess.redirectTo)) { window.location.href = onSuccess.redirectTo; diff --git a/packages/core/client/src/modules/form-creation/__e2e__/schemaInitializer.test.ts b/packages/core/client/src/modules/form-creation/__e2e__/schemaInitializer.test.ts index f305b6d11..4dfeb1b04 100644 --- a/packages/core/client/src/modules/form-creation/__e2e__/schemaInitializer.test.ts +++ b/packages/core/client/src/modules/form-creation/__e2e__/schemaInitializer.test.ts @@ -1,4 +1,5 @@ import { createBlockInPage, expect, oneEmptyForm, test } from '@nocobase/test/e2e'; +import { T3106 } from './templatesOfBug'; test.describe('where creation form block can be added', () => { test('page', async ({ page, mockPage }) => { @@ -78,6 +79,28 @@ test.describe('configure actions', () => { 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 }) => { await mockPage(oneEmptyForm).goto(); diff --git a/packages/core/client/src/modules/form-creation/__e2e__/templatesOfBug.ts b/packages/core/client/src/modules/form-creation/__e2e__/templatesOfBug.ts index 260b89a00..69a53bcd9 100644 --- a/packages/core/client/src/modules/form-creation/__e2e__/templatesOfBug.ts +++ b/packages/core/client/src/modules/form-creation/__e2e__/templatesOfBug.ts @@ -1,4 +1,4 @@ -import { PageConfig } from '@nocobase/test/e2e'; +import { PageConfig, generalWithM2oSingleSelect } from '@nocobase/test/e2e'; export const T2165 = { pageSchema: { @@ -5024,3 +5024,225 @@ export const T2200 = { '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, + }, +}; diff --git a/packages/core/client/src/schema-component/antd/form-item/hooks/useParseDefaultValue.ts b/packages/core/client/src/schema-component/antd/form-item/hooks/useParseDefaultValue.ts index 3213d6f13..62f1cb9c0 100644 --- a/packages/core/client/src/schema-component/antd/form-item/hooks/useParseDefaultValue.ts +++ b/packages/core/client/src/schema-component/antd/form-item/hooks/useParseDefaultValue.ts @@ -25,7 +25,8 @@ const useParseDefaultValue = () => { const variables = useVariables(); const localVariables = useLocalVariables(); const record = useRecord(); - const { isInAssignFieldValues, isInSetDefaultValueDialog, isInFormDataTemplate, isInSubTable } = useFlag() || {}; + const { isInAssignFieldValues, isInSetDefaultValueDialog, isInFormDataTemplate, isInSubTable, isInSubForm } = + useFlag() || {}; const { getField } = useCollection(); const { isSpecialCase, setDefaultValue } = useSpecialCase(); const index = useRecordIndex(); @@ -135,6 +136,9 @@ const useParseDefaultValue = () => { ); return dispose; + } else if (field.value == null && (isInSubTable || isInSubForm)) { + // 解决子表格(或子表单)中新增一行数据时,默认值不生效的问题 + field.setValue(fieldSchema.default); } }, [fieldSchema.default]); }; diff --git a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx index d9116be2e..31ae07553 100644 --- a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx +++ b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx @@ -346,7 +346,7 @@ export const Table: any = observer( }, [field, onRowDragEnd, dragSort]); /** - * 为没有设置 key 属性的 record 生成一个唯一的 key + * 为没有设置 key 属性的表格行生成一个唯一的 key * 1. rowKey 的默认值是 “key”,所以先判断有没有 record.key; * 2. 如果没有就生成一个唯一的 key,并以 record 的值作为索引; * 3. 这样下次就能取到对应的 key 的值;