From 7bb0084a884e2335c848d8ef9af3b48680a5b663 Mon Sep 17 00:00:00 2001 From: Zeke Zhang <958414905@qq.com> Date: Thu, 6 Feb 2025 10:50:10 +0800 Subject: [PATCH] fix: subform default value (#6165) * fix: default value * chore: add e2e test --- .../antd/form-item/FormItem.tsx | 6 + .../LinkageRules/bindLinkageRulesToFiled.ts | 25 +- .../__e2e__/linkageRules.test.ts | 29 +- .../src/schema-settings/__e2e__/template.ts | 460 ++++++++++++++++++ 4 files changed, 514 insertions(+), 6 deletions(-) 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 9105d05eda..4eb50dbb86 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 @@ -80,6 +80,12 @@ export const FormItem: any = withDynamicSchemaProps( [formItemLabelCss]: showTitle === false, }); }, [showTitle]); + + // 联动规则中的“隐藏保留值”的效果 + if (field.data?.hidden) { + return null; + } + return ( { - field.setState((state) => { - state[fieldName] = lastState?.value; + // 为了让字段的默认值中的变量能正常工作,需要保证字段被隐藏时,字段组件依然会被渲染 + if (fieldName === 'display' && lastState?.value === 'hidden') { + field.display = 'visible'; + field.data = field.data || {}; + // 在 FormItem 中使用这个属性来判断字段是否被隐藏 + field.data.hidden = true; + + requestAnimationFrame(() => { + field.setState((state) => { + state.display = 'visible'; + }); }); - }); + } else { + field[fieldName] = lastState?.value; + requestAnimationFrame(() => { + field.setState((state) => { + state[fieldName] = lastState?.value; + }); + }); + } + //字段隐藏时清空数据 if (fieldName === 'display' && lastState?.value === 'none') { field.value = null; diff --git a/packages/core/client/src/schema-settings/__e2e__/linkageRules.test.ts b/packages/core/client/src/schema-settings/__e2e__/linkageRules.test.ts index 31cdb9327a..7729b8a8ce 100644 --- a/packages/core/client/src/schema-settings/__e2e__/linkageRules.test.ts +++ b/packages/core/client/src/schema-settings/__e2e__/linkageRules.test.ts @@ -8,7 +8,10 @@ */ import { expect, test } from '@nocobase/test/e2e'; -import { formFieldDependsOnSubtableFieldsWithLinkageRules } from './template'; +import { + formFieldDependsOnSubtableFieldsWithLinkageRules, + whenSetToHideRetainedValueItShouldNotImpactTheFieldSDefaultValueVariables, +} from './template'; test.describe('linkage rules', () => { test('form field depends on subtable fields with linkage rules', async ({ page, mockPage, mockRecord }) => { @@ -54,6 +57,30 @@ test.describe('linkage rules', () => { page.getByLabel('block-item-CollectionField-test-form-test.result-result').getByRole('spinbutton'), ).toHaveValue(String(calcResult(record) + 10 * 10)); }); + + test("When set to 'Hide retained value', it should not impact the field's default value variables", async ({ + page, + mockPage, + }) => { + await mockPage(whenSetToHideRetainedValueItShouldNotImpactTheFieldSDefaultValueVariables).goto(); + + // 1. 给 Nickname 字段输入一个值,子表单中被隐藏的字段 title 的值应该为 Nickname 字段的值(因为其设置了默认值,其中使用了“当前表单”变量中 Nickname 字段的值) + await page + .getByRole('button', { name: 'block-item-CollectionField-users-form-users.nickname-Nickname' }) + .getByRole('textbox') + .fill('123456789'); + + // 2. 点击提交后,Roles 表格区块中应该显示刚才创建的 Role + + // 等待默认值生效 + await page.waitForTimeout(1000); + + await page.getByRole('button', { name: 'action-Action-Submit-submit-' }).click(); + await page.getByRole('button', { name: 'action-Action-Refresh-refresh' }).click(); + await expect( + page.getByRole('button', { name: 'block-item-CardItem-roles-' }).getByRole('row', { name: '123456789' }), + ).toBeVisible(); + }); }); function calcResult(record) { diff --git a/packages/core/client/src/schema-settings/__e2e__/template.ts b/packages/core/client/src/schema-settings/__e2e__/template.ts index 13b17febb5..0f0eaa5364 100644 --- a/packages/core/client/src/schema-settings/__e2e__/template.ts +++ b/packages/core/client/src/schema-settings/__e2e__/template.ts @@ -1074,3 +1074,463 @@ export const formFieldDependsOnSubtableFieldsWithLinkageRules = { 'x-index': 1, }, }; +export const whenSetToHideRetainedValueItShouldNotImpactTheFieldSDefaultValueVariables = { + pageSchema: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Page', + 'x-app-version': '1.2.22-alpha', + 'x-index': 1, + properties: { + p7ec8csgn5m: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': 'page:addBlock', + 'x-app-version': '1.2.22-alpha', + 'x-index': 1, + properties: { + zv4cspv6a29: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + 'x-app-version': '1.5.0', + properties: { + '8g82nnx49px': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + 'x-app-version': '1.5.0', + properties: { + o81qu0qr58k: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-acl-action-props': { + skipScopeCheck: true, + }, + 'x-acl-action': 'users:create', + 'x-decorator': 'FormBlockProvider', + 'x-use-decorator-props': 'useCreateFormBlockDecoratorProps', + 'x-decorator-props': { + dataSource: 'main', + collection: 'users', + }, + 'x-toolbar': 'BlockSchemaToolbar', + 'x-settings': 'blockSettings:createForm', + 'x-component': 'CardItem', + 'x-app-version': '1.5.0', + properties: { + '2y5nqom11x2': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'FormV2', + 'x-use-component-props': 'useCreateFormBlockProps', + 'x-app-version': '1.5.0', + properties: { + grid: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': 'form:configureFields', + 'x-app-version': '1.5.0', + properties: { + jw9u2or5ao3: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + 'x-app-version': '1.5.0', + properties: { + '2hjic42gro0': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + 'x-app-version': '1.5.0', + properties: { + nickname: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'string', + 'x-toolbar': 'FormItemSchemaToolbar', + 'x-settings': 'fieldSettings:FormItem', + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + 'x-collection-field': 'users.nickname', + 'x-component-props': {}, + 'x-app-version': '1.5.0', + 'x-uid': 'wiyq5i1cy3p', + 'x-async': false, + 'x-index': 1, + }, + roles: { + 'x-uid': 'hq9rpolzkgy', + _isJSONSchemaObject: true, + version: '2.0', + type: 'string', + 'x-toolbar': 'FormItemSchemaToolbar', + 'x-settings': 'fieldSettings:FormItem', + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + 'x-collection-field': 'users.roles', + 'x-component-props': { + fieldNames: { + label: 'name', + value: 'name', + }, + mode: 'Nester', + }, + 'x-app-version': '1.5.0', + default: null, + 'x-linkage-rules': [ + { + condition: { + $and: [], + }, + actions: [ + { + targetFields: ['title'], + operator: 'hidden', + }, + ], + }, + ], + properties: { + '61xdu2xz0id': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'AssociationField.Nester', + 'x-index': 1, + 'x-app-version': '1.5.0', + properties: { + grid: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': 'form:configureFields', + 'x-app-version': '1.5.0', + properties: { + cwi4824alag: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + 'x-app-version': '1.5.0', + properties: { + nciz3wbcwov: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + 'x-app-version': '1.5.0', + properties: { + title: { + 'x-uid': 'o1sjow3kb6d', + _isJSONSchemaObject: true, + version: '2.0', + type: 'string', + 'x-toolbar': 'FormItemSchemaToolbar', + 'x-settings': 'fieldSettings:FormItem', + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + 'x-collection-field': 'roles.title', + 'x-component-props': {}, + 'x-app-version': '1.5.0', + default: '{{$nForm.nickname}}', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'iau70tmmg0v', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'xtcm8jw27yn', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'zxwzyi9zno6', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'i5bbqlpixaq', + 'x-async': false, + }, + }, + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'ly4pbhn86ad', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'iwrf9t6dua7', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'elv4yj02qvv', + 'x-async': false, + 'x-index': 1, + }, + dbffcw0hegz: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-initializer': 'createForm:configureActions', + 'x-component': 'ActionBar', + 'x-component-props': { + layout: 'one-column', + }, + 'x-app-version': '1.5.0', + properties: { + t108zgbcxit: { + _isJSONSchemaObject: true, + version: '2.0', + title: '{{ t("Submit") }}', + 'x-action': 'submit', + 'x-component': 'Action', + 'x-use-component-props': 'useCreateActionProps', + 'x-toolbar': 'ActionSchemaToolbar', + 'x-settings': 'actionSettings:createSubmit', + 'x-component-props': { + type: 'primary', + htmlType: 'submit', + }, + 'x-action-settings': { + triggerWorkflows: [], + }, + type: 'void', + 'x-app-version': '1.5.0', + 'x-uid': 'i50ygu2vieu', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'zcsydga2buf', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'gslsn7jl6l1', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'wuoxu2y21vt', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'r5fug8doi7a', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'dhkuk4q7xwy', + 'x-async': false, + 'x-index': 1, + }, + '9s2vc6evb31': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + 'x-app-version': '1.5.0', + properties: { + '07vx4eek458': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + 'x-app-version': '1.5.0', + properties: { + ac0eo4uwy8n: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'TableBlockProvider', + 'x-acl-action': 'roles:list', + 'x-use-decorator-props': 'useTableBlockDecoratorProps', + 'x-decorator-props': { + collection: 'roles', + dataSource: 'main', + action: 'list', + params: { + pageSize: 20, + }, + rowKey: 'name', + showIndex: true, + dragSort: false, + }, + 'x-toolbar': 'BlockSchemaToolbar', + 'x-settings': 'blockSettings:table', + 'x-component': 'CardItem', + 'x-filter-targets': [], + 'x-app-version': '1.5.0', + properties: { + actions: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-initializer': 'table:configureActions', + 'x-component': 'ActionBar', + 'x-component-props': { + style: { + marginBottom: 'var(--nb-spacing)', + }, + }, + 'x-app-version': '1.5.0', + properties: { + '4qvejownfhj': { + _isJSONSchemaObject: true, + version: '2.0', + title: '{{ t("Refresh") }}', + 'x-action': 'refresh', + 'x-component': 'Action', + 'x-use-component-props': 'useRefreshActionProps', + 'x-toolbar': 'ActionSchemaToolbar', + 'x-settings': 'actionSettings:refresh', + 'x-component-props': { + icon: 'ReloadOutlined', + }, + 'x-align': 'right', + type: 'void', + 'x-app-version': '1.5.0', + 'x-uid': '933a1iqb1gv', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'm9ahqhvyuek', + 'x-async': false, + 'x-index': 1, + }, + mbylkrg6gvr: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'array', + 'x-initializer': 'table:configureColumns', + 'x-component': 'TableV2', + 'x-use-component-props': 'useTableBlockProps', + 'x-component-props': { + rowKey: 'id', + rowSelection: { + type: 'checkbox', + }, + }, + 'x-app-version': '1.5.0', + 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-toolbar': 'TableColumnSchemaToolbar', + 'x-initializer': 'table:configureItemActions', + 'x-settings': 'fieldSettings:TableColumn', + 'x-toolbar-props': { + initializer: 'table:configureItemActions', + }, + 'x-app-version': '1.5.0', + properties: { + s81pexo4gn0: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'DndContext', + 'x-component': 'Space', + 'x-component-props': { + split: '|', + }, + 'x-app-version': '1.5.0', + 'x-uid': '02wz01i4co3', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'kgpz7biqj4q', + 'x-async': false, + 'x-index': 1, + }, + '4s3t81kkedx': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'TableV2.Column.Decorator', + 'x-toolbar': 'TableColumnSchemaToolbar', + 'x-settings': 'fieldSettings:TableColumn', + 'x-component': 'TableV2.Column', + 'x-app-version': '1.5.0', + properties: { + title: { + _isJSONSchemaObject: true, + version: '2.0', + 'x-collection-field': 'roles.title', + 'x-component': 'CollectionField', + 'x-component-props': { + ellipsis: true, + }, + 'x-read-pretty': true, + 'x-decorator': null, + 'x-decorator-props': { + labelStyle: { + display: 'none', + }, + }, + 'x-app-version': '1.5.0', + 'x-uid': '0z4vb8b513t', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'iv2u1zb9oad', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': '96xrr05qtay', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': '66vv1xjjs0t', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '86pw777iy5v', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'af30xqxeajk', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'l7gm4k3394m', + 'x-async': false, + }, + }, + 'x-uid': 'ch2620lhiqs', + 'x-async': true, + }, +};