From 771ebaaaec1c1e07e115042df2c28b6916506717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=AB=E9=9B=A8=E6=B0=B4=E8=BF=87=E6=BB=A4=E7=9A=84?= =?UTF-8?q?=E7=A9=BA=E6=B0=94-Rain?= <958414905@qq.com> Date: Thu, 23 Nov 2023 21:05:07 +0800 Subject: [PATCH] fix: should load association data in subform (#3083) --- .../__tests__/e2e/loadAssociationData.test.ts | 66 ++ .../antd/association-field/InternalViewer.tsx | 2 +- .../antd/form-item/__tests__/utils.test.ts | 52 + .../useLazyLoadAssociationFieldOfForm.ts | 4 +- ...eLazyLoadDisplayAssociationFieldsOfForm.ts | 12 +- .../schema-component/antd/form-item/utils.ts | 14 +- packages/core/test/src/client/e2eUtils.ts | 2 +- packages/core/test/src/client/index.ts | 1 + .../test/src/client/templatesOfBug/T-2614.ts | 836 ++++++++++++++++ .../test/src/client/templatesOfBug/T-2615.ts | 904 ++++++++++++++++++ .../test/src/client/templatesOfBug/index.ts | 2 + .../server/field-interfaces/association.ts | 20 +- .../src/server/index.ts | 6 +- 13 files changed, 1897 insertions(+), 24 deletions(-) create mode 100644 packages/core/client/src/__tests__/e2e/loadAssociationData.test.ts create mode 100644 packages/core/client/src/schema-component/antd/form-item/__tests__/utils.test.ts create mode 100644 packages/core/test/src/client/templatesOfBug/T-2614.ts create mode 100644 packages/core/test/src/client/templatesOfBug/T-2615.ts create mode 100644 packages/core/test/src/client/templatesOfBug/index.ts diff --git a/packages/core/client/src/__tests__/e2e/loadAssociationData.test.ts b/packages/core/client/src/__tests__/e2e/loadAssociationData.test.ts new file mode 100644 index 000000000..e8d04352d --- /dev/null +++ b/packages/core/client/src/__tests__/e2e/loadAssociationData.test.ts @@ -0,0 +1,66 @@ +import { T2614, T2615, expect, test } from '@nocobase/test/client'; + +test.describe('load association data', () => { + // https://nocobase.height.app/T-2615 + test('should load association data', async ({ page, mockPage, mockRecord }) => { + const nocoPage = await mockPage(T2615).waitForInit(); + await mockRecord('T2615'); + await nocoPage.goto(); + + // 1. 新增表单中应该显示关系字段的数据 + await page.getByRole('button', { name: 'Add new' }).click(); + await page.getByLabel('block-item-CollectionField-T2615-form-T2615.m2o-m2o').getByLabel('Search').click(); + await page.getByRole('option', { name: '1' }).click(); + await expect(page.getByLabel('block-item-CollectionField-T2615-form-T2615.m2o.m2oOfTarget1')).toHaveText( + `m2oOfTarget1:1`, + ); + + // 关闭弹窗 + await page.getByLabel('drawer-Action.Container-T2615-Add record-mask').click(); + await page.getByRole('button', { name: 'OK', exact: true }).click(); + + // 2. 编辑表单中应该显示关系字段的数据 + await page.getByLabel('action-Action.Link-Edit record-update-T2615-table-0').click(); + await expect(page.getByLabel('block-item-CollectionField-T2615-form-T2615.m2o-m2o')).toHaveText(`m2o:1`); + await expect(page.getByLabel('block-item-CollectionField-T2615-form-T2615.m2o.m2oOfTarget1')).toHaveText( + `m2oOfTarget1:1`, + ); + + await page.getByLabel('drawer-Action.Container-T2615-Edit record-mask').click(); + + // 3. 详情中应该显示关系字段的数据 + await page.getByLabel('action-Action.Link-View record-view-T2615-table-0').click(); + await expect(page.getByLabel('block-item-CollectionField-T2615-form-T2615.m2o-m2o')).toHaveText(`m2o:1`); + await expect(page.getByLabel('block-item-CollectionField-T2615-form-T2615.m2o.m2oOfTarget1')).toHaveText( + `m2oOfTarget1:1`, + ); + }); + + // https://nocobase.height.app/T-2614 + test('should load association data in subform', async ({ page, mockPage, mockRecord }) => { + const nocoPage = await mockPage(T2614).waitForInit(); + await mockRecord('T2614'); + await nocoPage.goto(); + + // 查看详情 + await page.getByLabel('action-Action.Link-View record-view-T2614-table-0').click(); + await expect( + page.getByLabel('block-item-CollectionField-T2614Target1-form-T2614Target1.m2oOfTarget1-m2oOfTarget1'), + ).toHaveText(`m2oOfTarget1:1`); + await expect( + page.getByLabel('block-item-CollectionField-T2614Target1-form-T2614Target1.m2oOfTarget1.id'), + ).toHaveText(`ID:1`); + + // 关闭弹窗 + await page.getByLabel('drawer-Action.Container-T2614-View record-mask').click(); + + // 编辑详情 + await page.getByLabel('action-Action.Link-Edit record-update-T2614-table-0').click(); + await expect( + page.getByLabel('block-item-CollectionField-T2614Target1-form-T2614Target1.m2oOfTarget1-m2oOfTarget1'), + ).toHaveText(`m2oOfTarget1:1`); + await expect( + page.getByLabel('block-item-CollectionField-T2614Target1-form-T2614Target1.m2oOfTarget1.id'), + ).toHaveText(`ID:1`); + }); +}); diff --git a/packages/core/client/src/schema-component/antd/association-field/InternalViewer.tsx b/packages/core/client/src/schema-component/antd/association-field/InternalViewer.tsx index 634b1523f..ff5a16465 100644 --- a/packages/core/client/src/schema-component/antd/association-field/InternalViewer.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/InternalViewer.tsx @@ -10,9 +10,9 @@ import { useCompile } from '../../hooks'; import { ActionContextProvider, useActionContext } from '../action'; import { EllipsisWithTooltip } from '../input/EllipsisWithTooltip'; import { useAssociationFieldContext, useFieldNames, useInsertSchema } from './hooks'; +import { transformNestedData } from './InternalCascadeSelect'; import schema from './schema'; import { getLabelFormatValue, useLabelUiSchema } from './util'; -import { transformNestedData } from './InternalCascadeSelect'; interface IEllipsisWithTooltipRef { setPopoverVisible: (boolean) => void; diff --git a/packages/core/client/src/schema-component/antd/form-item/__tests__/utils.test.ts b/packages/core/client/src/schema-component/antd/form-item/__tests__/utils.test.ts new file mode 100644 index 000000000..b1661fd17 --- /dev/null +++ b/packages/core/client/src/schema-component/antd/form-item/__tests__/utils.test.ts @@ -0,0 +1,52 @@ +import { isFieldValueEmpty } from '../utils'; + +describe('isFieldValueEmpty', () => { + it('should return true for empty array', () => { + const value = []; + const targetKey = 'name'; + const result = isFieldValueEmpty(value, targetKey); + expect(result).toBe(true); + }); + + it('should return true for array with empty objects', () => { + const value = [{ name: null }, { name: undefined }]; + const targetKey = 'name'; + const result = isFieldValueEmpty(value, targetKey); + expect(result).toBe(true); + }); + + it('should return false for array with non-empty objects', () => { + const value = [{ name: 'John' }, { name: 'Doe' }]; + const targetKey = 'name'; + const result = isFieldValueEmpty(value, targetKey); + expect(result).toBe(false); + }); + + it('should return true for empty object', () => { + const value = {}; + const targetKey = 'name'; + const result = isFieldValueEmpty(value, targetKey); + expect(result).toBe(true); + }); + + it('should return true for object with null value', () => { + const value = { name: null }; + const targetKey = 'name'; + const result = isFieldValueEmpty(value, targetKey); + expect(result).toBe(true); + }); + + it('should return true for object with undefined value', () => { + const value = { name: undefined }; + const targetKey = 'name'; + const result = isFieldValueEmpty(value, targetKey); + expect(result).toBe(true); + }); + + it('should return false for object with non-empty value', () => { + const value = { name: 'John' }; + const targetKey = 'name'; + const result = isFieldValueEmpty(value, targetKey); + expect(result).toBe(false); + }); +}); diff --git a/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadAssociationFieldOfForm.ts b/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadAssociationFieldOfForm.ts index ad8286912..63e84b894 100644 --- a/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadAssociationFieldOfForm.ts +++ b/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadAssociationFieldOfForm.ts @@ -47,7 +47,7 @@ const useLazyLoadAssociationFieldOfForm = () => { return; } - if (!variables || !isFieldValueEmpty(_.get(record, schemaName))) { + if (!variables || !isFieldValueEmpty(_.get(record, schemaName), collectionField.targetKey || 'id')) { return; } @@ -69,7 +69,7 @@ const useLazyLoadAssociationFieldOfForm = () => { // 3. 所以,当 `变量预加载` 的请求晚于编辑表单的请求时,就会造成这个问题; // 更优的解决方案是:在 `变量预加载` 中也加上子表单中的关系字段路径,并删除编辑表单请求数据的逻辑(因为没必要了)。 // 但是这样改动较大,可以等之后 e2e 测试较完备后再处理。 - if (!isFieldValueEmpty(field.value)) { + if (!isFieldValueEmpty(field.value, collectionField.targetKey || 'id')) { return; } diff --git a/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadDisplayAssociationFieldsOfForm.ts b/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadDisplayAssociationFieldsOfForm.ts index 7ac6a0d0f..497bb8aa5 100644 --- a/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadDisplayAssociationFieldsOfForm.ts +++ b/packages/core/client/src/schema-component/antd/form-item/hooks/useLazyLoadDisplayAssociationFieldsOfForm.ts @@ -29,14 +29,18 @@ const useLazyLoadDisplayAssociationFieldsOfForm = () => { const schemaName = fieldSchema.name.toString(); const formValue = _.cloneDeep(isInSubForm || isInSubTable ? subFormValue : form.values); const collectionFieldRef = useRef(null); + const sourceCollectionFieldRef = useRef(null); - if (collectionFieldRef.current == null) { + if (collectionFieldRef.current == null && isDisplayField(schemaName)) { collectionFieldRef.current = getCollectionJoinField(`${name}.${schemaName}`); } + if (sourceCollectionFieldRef.current == null && isDisplayField(schemaName)) { + sourceCollectionFieldRef.current = getCollectionJoinField(`${name}.${schemaName.split('.')[0]}`); + } const sourceKeyValue = - isDisplayField(schemaName) && collectionFieldRef.current - ? _.get(formValue, `${schemaName.split('.')[0]}.${collectionFieldRef.current.sourceKey}`) + isDisplayField(schemaName) && sourceCollectionFieldRef.current + ? _.get(formValue, `${schemaName.split('.')[0]}.${sourceCollectionFieldRef.current?.targetKey || 'id'}`) : undefined; useEffect(() => { @@ -68,7 +72,7 @@ const useLazyLoadDisplayAssociationFieldsOfForm = () => { nextTick(() => { const result = transformVariableValue(value, { targetCollectionField: collectionFieldRef.current }); // fix https://nocobase.height.app/T-2608 - if (_.isEmpty(result)) { + if (_.isEmpty(result) && !_.isNumber(result)) { field.value = null; } else { field.value = result; diff --git a/packages/core/client/src/schema-component/antd/form-item/utils.ts b/packages/core/client/src/schema-component/antd/form-item/utils.ts index 58418e736..17e4943b3 100644 --- a/packages/core/client/src/schema-component/antd/form-item/utils.ts +++ b/packages/core/client/src/schema-component/antd/form-item/utils.ts @@ -1,8 +1,16 @@ import _ from 'lodash'; -export const isFieldValueEmpty = (value) => { - value = _.isArray(value) ? _.filter(value, (v) => !_.isEmpty(v)) : value; - return _.isEmpty(value); +/** + * 通过 targetKey 判断关系字段的数据是否为空 + * @param value + * @param targetKey + * @returns + */ +export const isFieldValueEmpty = (value, targetKey) => { + if (_.isArray(value)) { + return _.isEmpty(_.filter(value, (v) => v?.[targetKey] != null)); + } + return value?.[targetKey] == null; }; export const isDisplayField = (schemaName: string) => { diff --git a/packages/core/test/src/client/e2eUtils.ts b/packages/core/test/src/client/e2eUtils.ts index e4a0f2e77..33b3bf798 100644 --- a/packages/core/test/src/client/e2eUtils.ts +++ b/packages/core/test/src/client/e2eUtils.ts @@ -86,7 +86,7 @@ interface CollectionSetting { }>; } -interface PageConfig { +export interface PageConfig { /** * 用户可见的页面名称 * @default uid() diff --git a/packages/core/test/src/client/index.ts b/packages/core/test/src/client/index.ts index 48fc3a1c5..da96847dd 100644 --- a/packages/core/test/src/client/index.ts +++ b/packages/core/test/src/client/index.ts @@ -1 +1,2 @@ export * from './e2eUtils'; +export * from './templatesOfBug'; diff --git a/packages/core/test/src/client/templatesOfBug/T-2614.ts b/packages/core/test/src/client/templatesOfBug/T-2614.ts new file mode 100644 index 000000000..0c17e88b9 --- /dev/null +++ b/packages/core/test/src/client/templatesOfBug/T-2614.ts @@ -0,0 +1,836 @@ +import { PageConfig } from '../e2eUtils'; + +export const T2614: PageConfig = { + collections: [ + { + name: 'T2614', + fields: [ + { + name: 'm2o', + interface: 'm2o', + target: 'T2614Target1', + }, + ], + }, + { + name: 'T2614Target1', + fields: [ + { + name: 'm2oOfTarget1', + interface: 'm2o', + target: 'T2614Target2', + }, + ], + }, + { + name: 'T2614Target2', + fields: [ + { + name: 'm2oOfTarget2', + interface: 'm2o', + target: 'users', + }, + ], + }, + ], + pageSchema: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Page', + properties: { + oaeetth18tf: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': 'BlockInitializers', + properties: { + vv0l8wohslb: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + '7se9siwa4ce': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + '249fb0vofov': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'TableBlockProvider', + 'x-acl-action': 'T2614:list', + 'x-decorator-props': { + collection: 'T2614', + resource: 'T2614', + 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': 'vq4vg5mpbxz', + 'x-async': false, + 'x-index': 1, + }, + v76qyn133dr: { + _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: { + '02okcjna453': { + 'x-uid': 'xowhnp7a686', + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: 'View record', + 'x-action': 'view', + 'x-designer': 'Action.Designer', + 'x-component': 'Action.Link', + 'x-component-props': { + openMode: 'drawer', + danger: false, + }, + 'x-decorator': 'ACLActionProvider', + 'x-designer-props': { + linkageAction: true, + }, + properties: { + drawer: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: '{{ t("View record") }}', + '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("Details")}}', + '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': 'RecordBlockInitializers', + properties: { + qbl84fadyr0: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + pfnr7qcapp2: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + eomkz742tgm: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-acl-action': 'T2614:get', + 'x-decorator': 'FormBlockProvider', + 'x-decorator-props': { + resource: 'T2614', + collection: 'T2614', + readPretty: true, + action: 'get', + useParams: '{{ useParamsFromRecord }}', + useSourceId: '{{ useSourceIdFromParentRecord }}', + }, + 'x-designer': 'FormV2.ReadPrettyDesigner', + 'x-component': 'CardItem', + properties: { + sekfkpv5dh2: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'FormV2', + 'x-read-pretty': true, + 'x-component-props': { + useProps: '{{ useFormBlockProps }}', + }, + properties: { + actions: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-initializer': + 'ReadPrettyFormActionInitializers', + 'x-component': 'ActionBar', + 'x-component-props': { + style: { + marginBottom: 24, + }, + }, + 'x-uid': 'mt321nhie11', + 'x-async': false, + 'x-index': 1, + }, + grid: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': + 'ReadPrettyFormItemInitializers', + properties: { + i39cn9ve66b: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + h6aq6z28saw: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + m2o: { + 'x-uid': '5zamj2l0hxp', + _isJSONSchemaObject: true, + version: '2.0', + type: 'string', + 'x-designer': 'FormItem.Designer', + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + 'x-collection-field': 'T2614.m2o', + 'x-component-props': { + mode: 'Nester', + }, + properties: { + sgu8ssav8z3: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': + 'AssociationField.Nester', + 'x-index': 1, + properties: { + grid: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': + 'FormItemInitializers', + properties: { + e5kqdzyj562: { + _isJSONSchemaObject: + true, + version: '2.0', + type: 'void', + 'x-component': + 'Grid.Row', + properties: { + '36nwk5wtcze': { + _isJSONSchemaObject: + true, + version: '2.0', + type: 'void', + 'x-component': + 'Grid.Col', + properties: { + m2oOfTarget1: { + _isJSONSchemaObject: + true, + version: '2.0', + type: 'string', + 'x-designer': + 'FormItem.Designer', + 'x-component': + 'CollectionField', + 'x-decorator': + 'FormItem', + 'x-collection-field': + 'T2614Target1.m2oOfTarget1', + 'x-component-props': + {}, + 'x-uid': + '9x1i9kks2io', + 'x-async': + false, + 'x-index': 1, + }, + }, + 'x-uid': + 'gnqmqaqs49i', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'sku445zzg07', + 'x-async': false, + 'x-index': 1, + }, + bnd1dnje70d: { + _isJSONSchemaObject: + true, + version: '2.0', + type: 'void', + 'x-component': + 'Grid.Row', + properties: { + ygyvra5m18v: { + _isJSONSchemaObject: + true, + version: '2.0', + type: 'void', + 'x-component': + 'Grid.Col', + properties: { + 'm2oOfTarget1.id': + { + _isJSONSchemaObject: + true, + version: + '2.0', + type: 'string', + 'x-designer': + 'FormItem.Designer', + 'x-component': + 'CollectionField', + 'x-read-pretty': + true, + 'x-component-props': + { + 'pattern-disable': + true, + }, + 'x-decorator': + 'FormItem', + 'x-collection-field': + 'T2614Target1.m2oOfTarget1.id', + 'x-uid': + '0trg79yim60', + 'x-async': + false, + 'x-index': 1, + }, + }, + 'x-uid': + 'auigm7t6blc', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '6ll6h4ii2td', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'wxo0qlrm5ss', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '73iro2istbt', + 'x-async': false, + }, + }, + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'h3feczketbc', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'nb5fbboc504', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'dehspo2sh69', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'lyvcisiy2mz', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'u78ad3fqfdo', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'r8s2aj79b9q', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'fgsdtpfae0q', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'dzzom03ln6q', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'u8h5d2ecch0', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '1dlp1swsc68', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'qa2uyudep13', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-async': false, + 'x-index': 1, + }, + '697zke71z0l': { + 'x-uid': '7o63dwge91d', + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: 'Edit record', + 'x-action': 'update', + 'x-designer': 'Action.Designer', + 'x-component': 'Action.Link', + 'x-component-props': { + openMode: 'drawer', + danger: false, + }, + 'x-decorator': 'ACLActionProvider', + 'x-designer-props': { + linkageAction: true, + }, + properties: { + drawer: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: '{{ t("Edit record") }}', + '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("Edit")}}', + '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': 'RecordBlockInitializers', + properties: { + z79dioevb4n: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + krzxk68va81: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + '7ms7r5wolwa': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-acl-action-props': { + skipScopeCheck: false, + }, + 'x-acl-action': 'T2614:update', + 'x-decorator': 'FormBlockProvider', + 'x-decorator-props': { + useSourceId: '{{ useSourceIdFromParentRecord }}', + useParams: '{{ useParamsFromRecord }}', + action: 'get', + resource: 'T2614', + collection: 'T2614', + }, + 'x-designer': 'FormV2.Designer', + 'x-component': 'CardItem', + 'x-component-props': {}, + properties: { + '4pxevnwkd12': { + _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: { + j9egu0k0tkq: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + zpv9u8httu7: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + m2o: { + 'x-uid': '1pyjlpyhxue', + _isJSONSchemaObject: true, + version: '2.0', + type: 'string', + 'x-designer': 'FormItem.Designer', + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + 'x-collection-field': 'T2614.m2o', + 'x-component-props': { + mode: 'Nester', + }, + properties: { + ts1e7dq92gw: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': + 'AssociationField.Nester', + 'x-index': 1, + properties: { + grid: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': + 'FormItemInitializers', + properties: { + esgv9d2n3jl: { + _isJSONSchemaObject: + true, + version: '2.0', + type: 'void', + 'x-component': + 'Grid.Row', + properties: { + fvjf1i0u5tj: { + _isJSONSchemaObject: + true, + version: '2.0', + type: 'void', + 'x-component': + 'Grid.Col', + properties: { + m2oOfTarget1: { + _isJSONSchemaObject: + true, + version: '2.0', + type: 'string', + 'x-designer': + 'FormItem.Designer', + 'x-component': + 'CollectionField', + 'x-decorator': + 'FormItem', + 'x-collection-field': + 'T2614Target1.m2oOfTarget1', + 'x-component-props': + {}, + 'x-uid': + 'tbl4cxpqqhr', + 'x-async': + false, + 'x-index': 1, + }, + }, + 'x-uid': + '0inwt7v6zx1', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'ooid2e23vzk', + 'x-async': false, + 'x-index': 1, + }, + '8jo9e13m9pu': { + _isJSONSchemaObject: + true, + version: '2.0', + type: 'void', + 'x-component': + 'Grid.Row', + properties: { + dbwz7xfmcsf: { + _isJSONSchemaObject: + true, + version: '2.0', + type: 'void', + 'x-component': + 'Grid.Col', + properties: { + 'm2oOfTarget1.id': + { + _isJSONSchemaObject: + true, + version: + '2.0', + type: 'string', + 'x-designer': + 'FormItem.Designer', + 'x-component': + 'CollectionField', + 'x-read-pretty': + true, + 'x-component-props': + { + 'pattern-disable': + true, + }, + 'x-decorator': + 'FormItem', + 'x-collection-field': + 'T2614Target1.m2oOfTarget1.id', + 'x-uid': + 'no1h1z3kbqn', + 'x-async': + false, + 'x-index': 1, + }, + }, + 'x-uid': + 'f1w8n47pxgk', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'v6x8pzyim4q', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'ixnvtkde6ut', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'a0765a01l4v', + 'x-async': false, + }, + }, + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'nhq72b5xej7', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '0rchr17dcvr', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'fvfqd52uoaa', + 'x-async': false, + 'x-index': 1, + }, + actions: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-initializer': 'UpdateFormActionInitializers', + 'x-component': 'ActionBar', + 'x-component-props': { + layout: 'one-column', + style: { + marginTop: 24, + }, + }, + 'x-uid': 'bm93ifuifak', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': '6s8ie14bci8', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'hljdd9nlub3', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'h14avrpxyu9', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'n54e5yj7uo8', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'o6q0ebwuei0', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'ej65121swhj', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '521m41b059u', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '6ddt1wgx8zu', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': '1oj9b60cf3w', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'qdzdffxf5da', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 't7svx0a3pce', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'w8kzfaxgchd', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'hg44qtd6uw6', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'vv4zzxbtbja', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '6klhg23a43i', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '9ebjl68x43b', + 'x-async': true, + 'x-index': 1, + }, +}; diff --git a/packages/core/test/src/client/templatesOfBug/T-2615.ts b/packages/core/test/src/client/templatesOfBug/T-2615.ts new file mode 100644 index 000000000..5f6e059c8 --- /dev/null +++ b/packages/core/test/src/client/templatesOfBug/T-2615.ts @@ -0,0 +1,904 @@ +import { PageConfig } from '../e2eUtils'; + +export const T2615: PageConfig = { + collections: [ + { + name: 'T2615', + fields: [ + { + name: 'm2o', + interface: 'm2o', + target: 'T2615Target1', + }, + ], + }, + { + name: 'T2615Target1', + fields: [ + { + name: 'm2oOfTarget1', + interface: 'm2o', + target: 'T2615Target2', + }, + ], + }, + { + name: 'T2615Target2', + fields: [ + { + name: 'm2oOfTarget2', + interface: 'm2o', + target: 'users', + }, + ], + }, + ], + pageSchema: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Page', + properties: { + eoe6sphevnd: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': 'BlockInitializers', + properties: { + '1valv0kj8vs': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + nkq10mh10ps: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + '22lk2du0ib3': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-decorator': 'TableBlockProvider', + 'x-acl-action': 'T2615:list', + 'x-decorator-props': { + collection: 'T2615', + resource: 'T2615', + 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)', + }, + }, + properties: { + unexw8b0ued: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-action': 'create', + 'x-acl-action': 'create', + title: "{{t('Add new')}}", + 'x-designer': 'Action.Designer', + 'x-component': 'Action', + 'x-decorator': 'ACLActionProvider', + 'x-component-props': { + openMode: 'drawer', + type: 'primary', + component: 'CreateRecordAction', + icon: 'PlusOutlined', + }, + 'x-align': 'right', + 'x-acl-action-props': { + skipScopeCheck: true, + }, + properties: { + drawer: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: '{{ t("Add record") }}', + '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': 'TabPaneInitializersForCreateFormBlock', + properties: { + tab1: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: '{{t("Add new")}}', + '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: { + '8ei3tsaojf6': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + '5u0ju1wsgkl': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + zxwg35f8sg7: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-acl-action-props': { + skipScopeCheck: true, + }, + 'x-acl-action': 'T2615:create', + 'x-decorator': 'FormBlockProvider', + 'x-decorator-props': { + resource: 'T2615', + collection: 'T2615', + }, + 'x-designer': 'FormV2.Designer', + 'x-component': 'CardItem', + 'x-component-props': {}, + properties: { + '9i2u8628hoz': { + _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: { + i7cb2o172ey: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + enue1mnnt4g: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + m2o: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'string', + 'x-designer': 'FormItem.Designer', + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + 'x-collection-field': 'T2615.m2o', + 'x-component-props': {}, + 'x-uid': 'tif3ncbwwru', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'jh5w5yne4qt', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'aqo2rtciew5', + 'x-async': false, + 'x-index': 1, + }, + qfr6n6ymx77: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + ldlk5ifn56r: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + 'm2o.m2oOfTarget1': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'string', + 'x-designer': 'FormItem.Designer', + 'x-component': 'CollectionField', + 'x-read-pretty': true, + 'x-component-props': { + 'pattern-disable': true, + fieldNames: { + label: 'id', + value: 'id', + }, + }, + 'x-decorator': 'FormItem', + 'x-collection-field': + 'T2615.m2o.m2oOfTarget1', + 'x-uid': 'gii2rk1q4fx', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'k2k4hzsmxzw', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'tysg8zh5wpp', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': '7ff0fvn1ci1', + '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': '6u35dl8quee', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': '5syf9qhcwch', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '26kgmi2guwg', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'i1hdum7ju7d', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '8e7td05t5rv', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'nlgcjcl7sm2', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'hzn4uinj3i7', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'qkv3lilo9ew', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'k945b89wggu', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'pz18nxb0x51', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '94386mg3n6z', + 'x-async': false, + 'x-index': 1, + }, + '3m6w3iz4c5t': { + _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: { + yych9x95hrp: { + 'x-uid': 'uv7zmtj0r5u', + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: 'Edit record', + 'x-action': 'update', + 'x-designer': 'Action.Designer', + 'x-component': 'Action.Link', + 'x-component-props': { + openMode: 'drawer', + danger: false, + }, + 'x-decorator': 'ACLActionProvider', + 'x-designer-props': { + linkageAction: true, + }, + properties: { + drawer: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: '{{ t("Edit record") }}', + '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("Edit")}}', + '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': 'RecordBlockInitializers', + properties: { + l79xm6sfjst: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + '7cyquusb2ca': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + '8dxzx9t0571': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-acl-action-props': { + skipScopeCheck: false, + }, + 'x-acl-action': 'T2615:update', + 'x-decorator': 'FormBlockProvider', + 'x-decorator-props': { + useSourceId: '{{ useSourceIdFromParentRecord }}', + useParams: '{{ useParamsFromRecord }}', + action: 'get', + resource: 'T2615', + collection: 'T2615', + }, + 'x-designer': 'FormV2.Designer', + 'x-component': 'CardItem', + 'x-component-props': {}, + properties: { + '21sxtdkbcw0': { + _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: { + '7eayo28dgzo': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + oj9yj21ujd8: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + m2o: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'string', + 'x-designer': 'FormItem.Designer', + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + 'x-collection-field': 'T2615.m2o', + 'x-component-props': {}, + 'x-uid': 'qxn8qacg682', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'axx7wvrxnem', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'qgkr6iz0e1t', + 'x-async': false, + 'x-index': 1, + }, + zsdbhvdvaru: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + '082hatydnd0': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + 'm2o.m2oOfTarget1': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'string', + 'x-designer': 'FormItem.Designer', + 'x-component': 'CollectionField', + 'x-read-pretty': true, + 'x-component-props': { + 'pattern-disable': true, + fieldNames: { + label: 'id', + value: 'id', + }, + }, + 'x-decorator': 'FormItem', + 'x-collection-field': + 'T2615.m2o.m2oOfTarget1', + 'x-uid': 'n5s7j4n193r', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'nm9qq5hao2e', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'ey3595qsqyk', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'w8zdw4dr89d', + 'x-async': false, + 'x-index': 1, + }, + actions: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-initializer': 'UpdateFormActionInitializers', + 'x-component': 'ActionBar', + 'x-component-props': { + layout: 'one-column', + style: { + marginTop: 24, + }, + }, + 'x-uid': 'conyu4tdnsb', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': '6jeoainb2oa', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '27azok1hcrs', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'x0gpfgjc0n1', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '0up3rbfoby1', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'tul7kvn3s6m', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'jz2lb20hu1s', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'ssbzj9yrh8r', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'dak290d9mnz', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-async': false, + 'x-index': 1, + }, + t452of8muaq: { + 'x-uid': 'q4op427zlfp', + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: 'View record', + 'x-action': 'view', + 'x-designer': 'Action.Designer', + 'x-component': 'Action.Link', + 'x-component-props': { + openMode: 'drawer', + danger: false, + }, + 'x-decorator': 'ACLActionProvider', + 'x-designer-props': { + linkageAction: true, + }, + properties: { + drawer: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + title: '{{ t("View record") }}', + '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("Details")}}', + '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': 'RecordBlockInitializers', + properties: { + nlnfd9hnl53: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + o1mvvolrr3n: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + '02tm0tr9gie': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-acl-action': 'T2615:get', + 'x-decorator': 'FormBlockProvider', + 'x-decorator-props': { + resource: 'T2615', + collection: 'T2615', + readPretty: true, + action: 'get', + useParams: '{{ useParamsFromRecord }}', + useSourceId: '{{ useSourceIdFromParentRecord }}', + }, + 'x-designer': 'FormV2.ReadPrettyDesigner', + 'x-component': 'CardItem', + properties: { + xa10ops1tmr: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'FormV2', + 'x-read-pretty': true, + 'x-component-props': { + useProps: '{{ useFormBlockProps }}', + }, + properties: { + actions: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-initializer': + 'ReadPrettyFormActionInitializers', + 'x-component': 'ActionBar', + 'x-component-props': { + style: { + marginBottom: 24, + }, + }, + 'x-uid': 'jq1vdqw4oyy', + 'x-async': false, + 'x-index': 1, + }, + grid: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid', + 'x-initializer': + 'ReadPrettyFormItemInitializers', + properties: { + j9mxulol74m: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + r4alweypz03: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + m2o: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'string', + 'x-designer': 'FormItem.Designer', + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + 'x-collection-field': 'T2615.m2o', + 'x-component-props': {}, + 'x-uid': 'ttv0hjsnnsy', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'p9yvxr8b7vg', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'r198z5pv6c4', + 'x-async': false, + 'x-index': 1, + }, + xb97qr5ustn: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Row', + properties: { + wje8oyfbn1d: { + _isJSONSchemaObject: true, + version: '2.0', + type: 'void', + 'x-component': 'Grid.Col', + properties: { + 'm2o.m2oOfTarget1': { + _isJSONSchemaObject: true, + version: '2.0', + type: 'string', + 'x-designer': 'FormItem.Designer', + 'x-component': 'CollectionField', + 'x-read-pretty': true, + 'x-component-props': { + 'pattern-disable': true, + fieldNames: { + label: 'id', + value: 'id', + }, + }, + 'x-decorator': 'FormItem', + 'x-collection-field': + 'T2615.m2o.m2oOfTarget1', + 'x-uid': '6pdlbj34175', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'p2alwntoxkg', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'rgsbhuo0lzv', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'a39j3mj83xp', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'd6xf1x23yzx', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '5esxphd790l', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'pzr8i6utc83', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'u8wkbbgvb05', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'boh5n3tkmgu', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'd0cfvm929ca', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'wt7e6356t9k', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'cqnlqotquv9', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'x8yf6ex62ju', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 't4gcpw7ji0u', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '8d8oe7qocry', + 'x-async': false, + 'x-index': 2, + }, + }, + 'x-uid': 'vyf1ac9nsl5', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': '8zp6xvttwvi', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'axknjuou42g', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'xtxm0hd6lbi', + 'x-async': false, + 'x-index': 1, + }, + }, + 'x-uid': 'lbdmizeodxy', + 'x-async': true, + 'x-index': 1, + }, +}; diff --git a/packages/core/test/src/client/templatesOfBug/index.ts b/packages/core/test/src/client/templatesOfBug/index.ts new file mode 100644 index 000000000..1c6357183 --- /dev/null +++ b/packages/core/test/src/client/templatesOfBug/index.ts @@ -0,0 +1,2 @@ +export * from './T-2614'; +export * from './T-2615'; diff --git a/packages/plugins/@nocobase/plugin-mock-collections/src/server/field-interfaces/association.ts b/packages/plugins/@nocobase/plugin-mock-collections/src/server/field-interfaces/association.ts index 680ca8146..423444bd9 100644 --- a/packages/plugins/@nocobase/plugin-mock-collections/src/server/field-interfaces/association.ts +++ b/packages/plugins/@nocobase/plugin-mock-collections/src/server/field-interfaces/association.ts @@ -106,8 +106,8 @@ export const oho = { ]; return reverseFieldHandle(defaults, options); }, - mock: async (options, { mockCollectionData }) => { - return mockCollectionData(options.target, 1, true); + mock: async (options, { mockCollectionData, maxDepth, depth }) => { + return mockCollectionData(options.target, 1, depth + 1, maxDepth); }, }; @@ -159,8 +159,8 @@ export const obo = { ]; return reverseFieldHandle(defaults, options); }, - mock: async (options, { mockCollectionData }) => { - return mockCollectionData(options.target, 1, true); + mock: async (options, { mockCollectionData, depth, maxDepth }) => { + return mockCollectionData(options.target, 1, depth + 1, maxDepth); }, }; @@ -213,8 +213,8 @@ export const o2m = { ]; return reverseFieldHandle(defaults, options); }, - mock: async (options, { mockCollectionData }) => { - return mockCollectionData(options.target, faker.number.int({ min: 2, max: 5 }), true); + mock: async (options, { mockCollectionData, depth, maxDepth }) => { + return mockCollectionData(options.target, faker.number.int({ min: 2, max: 5 }), depth + 1, maxDepth); }, }; @@ -268,8 +268,8 @@ export const m2o = { ]; return reverseFieldHandle(defaults, options); }, - mock: async (options, { mockCollectionData }) => { - return mockCollectionData(options.target, 1, true); + mock: async (options, { mockCollectionData, depth, maxDepth }) => { + return mockCollectionData(options.target, 1, depth + 1, maxDepth); }, }; @@ -351,7 +351,7 @@ export const m2m = { }; return reverseFieldHandle(defaults, options); }, - mock: async (options, { mockCollectionData }) => { - return mockCollectionData(options.target, faker.number.int({ min: 2, max: 5 }), true); + mock: async (options, { mockCollectionData, depth, maxDepth }) => { + return mockCollectionData(options.target, faker.number.int({ min: 2, max: 5 }), depth + 1, maxDepth); }, }; diff --git a/packages/plugins/@nocobase/plugin-mock-collections/src/server/index.ts b/packages/plugins/@nocobase/plugin-mock-collections/src/server/index.ts index 5dd0a79ba..0c970932a 100644 --- a/packages/plugins/@nocobase/plugin-mock-collections/src/server/index.ts +++ b/packages/plugins/@nocobase/plugin-mock-collections/src/server/index.ts @@ -188,7 +188,7 @@ export class PluginMockCollectionsServer extends Plugin { mock: async (ctx, next) => { const { resourceName } = ctx.action; const { values, count = 10 } = ctx.action.params; - const mockCollectionData = async (collectionName, count = 1, skipAssoc = false) => { + const mockCollectionData = async (collectionName, count = 1, depth = 0, maxDepth = 2) => { const collection = ctx.db.getCollection(collectionName) as Collection; const items = await Promise.all( _.range(count).map(async (i) => { @@ -203,12 +203,12 @@ export class PluginMockCollectionsServer extends Plugin { if (!field.options.interface) { continue; } - if (skipAssoc && ['m2o', 'm2m', 'o2m', 'obo', 'oho'].includes(field.options.interface)) { + if (depth >= maxDepth && ['m2o', 'm2m', 'o2m', 'obo', 'oho'].includes(field.options.interface)) { continue; } const fn = fieldInterfaces[field.options.interface]; if (fn?.mock) { - values[field.name] = await fn.mock(field.options, { mockCollectionData }); + values[field.name] = await fn.mock(field.options, { mockCollectionData, maxDepth, depth }); } } return values;