fix(TreeTable): add child error (#4008)

* fix(TreeTable): add new error

* test: add e2e for T-3235

* fix: parentId
This commit is contained in:
Zeke Zhang 2024-04-11 17:25:46 +08:00 committed by GitHub
parent 6d7ecba59e
commit fa815aeb3c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 54 additions and 10 deletions

View File

@ -5,6 +5,7 @@ import React, { createContext, useContext, useEffect, useMemo, useRef } from 're
import { withDynamicSchemaProps } from '../application/hoc/withDynamicSchemaProps'; import { withDynamicSchemaProps } from '../application/hoc/withDynamicSchemaProps';
import { useCollection_deprecated } from '../collection-manager'; import { useCollection_deprecated } from '../collection-manager';
import { CollectionRecord, useCollectionParentRecordData, useCollectionRecord } from '../data-source'; import { CollectionRecord, useCollectionParentRecordData, useCollectionRecord } from '../data-source';
import { useTreeParentRecord } from '../modules/blocks/data-blocks/table/TreeRecordProvider';
import { RecordProvider, useRecord } from '../record-provider'; import { RecordProvider, useRecord } from '../record-provider';
import { useActionContext, useDesignable } from '../schema-component'; import { useActionContext, useDesignable } from '../schema-component';
import { Templates as DataTemplateSelect } from '../schema-component/antd/form-v2/Templates'; import { Templates as DataTemplateSelect } from '../schema-component/antd/form-v2/Templates';
@ -147,14 +148,14 @@ export const useFormBlockContext = () => {
*/ */
export const useFormBlockProps = () => { export const useFormBlockProps = () => {
const ctx = useFormBlockContext(); const ctx = useFormBlockContext();
const record = useRecord(); const treeParentRecord = useTreeParentRecord();
const { fieldSchema } = useActionContext(); const { fieldSchema } = useActionContext();
const addChild = fieldSchema?.['x-component-props']?.addChild; const addChild = fieldSchema?.['x-component-props']?.addChild;
useEffect(() => { useEffect(() => {
if (addChild) { if (addChild) {
ctx.form?.query('parent').take((field) => { ctx.form?.query('parent').take((field) => {
field.disabled = true; field.disabled = true;
field.value = new Proxy({ ...record?.__parent }, {}); field.value = treeParentRecord;
}); });
} }
}); });

View File

@ -22,6 +22,7 @@ import { useAPIClient, useRequest } from '../../api-client';
import { useCollectionManager_deprecated, useCollection_deprecated } from '../../collection-manager'; import { useCollectionManager_deprecated, useCollection_deprecated } from '../../collection-manager';
import { useFilterBlock } from '../../filter-provider/FilterProvider'; import { useFilterBlock } from '../../filter-provider/FilterProvider';
import { mergeFilter, transformToFilter } from '../../filter-provider/utils'; import { mergeFilter, transformToFilter } from '../../filter-provider/utils';
import { useTreeParentRecord } from '../../modules/blocks/data-blocks/table/TreeRecordProvider';
import { useRecord } from '../../record-provider'; import { useRecord } from '../../record-provider';
import { removeNullCondition, useActionContext, useCompile } from '../../schema-component'; import { removeNullCondition, useActionContext, useCompile } from '../../schema-component';
import { isSubMode } from '../../schema-component/antd/association-field/util'; import { isSubMode } from '../../schema-component/antd/association-field/util';
@ -117,7 +118,7 @@ export function useCollectValuesToSubmit() {
const variables = useVariables(); const variables = useVariables();
const localVariables = useLocalVariables({ currentForm: form }); const localVariables = useLocalVariables({ currentForm: form });
const actionSchema = useFieldSchema(); const actionSchema = useFieldSchema();
const currentRecord = useRecord(); const treeParentRecord = useTreeParentRecord();
return useCallback(async () => { return useCallback(async () => {
const { assignedValues: originalAssignedValues = {}, overwriteValues } = actionSchema?.['x-action-settings'] ?? {}; const { assignedValues: originalAssignedValues = {}, overwriteValues } = actionSchema?.['x-action-settings'] ?? {};
@ -156,8 +157,8 @@ export function useCollectValuesToSubmit() {
const addChild = fieldSchema?.['x-component-props']?.addChild; const addChild = fieldSchema?.['x-component-props']?.addChild;
if (addChild) { if (addChild) {
const treeParentField = getTreeParentField(); const treeParentField = getTreeParentField();
values[treeParentField?.name ?? 'parent'] = omit(currentRecord?.__parent, ['children']); values[treeParentField?.name ?? 'parent'] = treeParentRecord;
values[treeParentField?.foreignKey ?? 'parentId'] = currentRecord?.__parent?.id; values[treeParentField?.foreignKey ?? 'parentId'] = treeParentRecord?.id;
} }
return { return {
@ -167,7 +168,6 @@ export function useCollectValuesToSubmit() {
}; };
}, [ }, [
actionSchema, actionSchema,
currentRecord?.__parent,
field, field,
fieldNames, fieldNames,
fieldSchema, fieldSchema,
@ -179,6 +179,7 @@ export function useCollectValuesToSubmit() {
localVariables, localVariables,
name, name,
resource, resource,
treeParentRecord,
variables, variables,
]); ]);
} }

View File

@ -0,0 +1,21 @@
import React, { FC, createContext } from 'react';
interface TreeRecordContextProps {
parent: any;
}
const TreeRecordContext = createContext<TreeRecordContextProps>(null);
/**
* Tree Table Tree Table RecordProvider RecordProvider Tree Table
* @param param0
* @returns
*/
export const TreeRecordProvider: FC<TreeRecordContextProps> = ({ children, parent }) => {
return <TreeRecordContext.Provider value={{ parent }}>{children}</TreeRecordContext.Provider>;
};
export const useTreeParentRecord = () => {
const context = React.useContext(TreeRecordContext);
return context?.parent;
};

View File

@ -788,6 +788,24 @@ test.describe('actions schema settings', () => {
showMenu: () => showMenu(page), showMenu: () => showMenu(page),
supportedOptions: ['Edit button', 'Linkage rules', 'Open mode', 'Popup size', 'Delete'], supportedOptions: ['Edit button', 'Linkage rules', 'Open mode', 'Popup size', 'Delete'],
}); });
// https://nocobase.height.app/T-3235
// add child 表单中的 Parent 字段应该有数据
await page.getByLabel('action-Action.Link-Add child-').click({
position: { x: 5, y: 5 }, // 防止按钮被遮挡
});
await page.getByLabel('schema-initializer-Grid-popup').hover();
await page.getByRole('menuitem', { name: 'form Form' }).click();
await page.mouse.move(300, 0);
await page.getByLabel('schema-initializer-Grid-form:').hover();
await page.getByRole('menuitem', { name: 'Parent', exact: true }).click();
await page.mouse.move(300, 0);
await expect(
page
.getByLabel('block-item-CollectionField-')
.getByTestId('select-object-single')
.getByText('1', { exact: true }),
).toBeVisible();
}); });
}); });

View File

@ -2,7 +2,7 @@ import { useCollectionRecordData } from '../../data-source/collection-record/Col
/** /**
* @internal * @internal
* sourceId hook * sourceRecord hook
* @param association * @param association
* @returns * @returns
*/ */

View File

@ -9,8 +9,9 @@ import { StablePopover, useActionContext } from '../..';
import { useDesignable } from '../../'; import { useDesignable } from '../../';
import { useACLActionParamsContext } from '../../../acl'; import { useACLActionParamsContext } from '../../../acl';
import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps';
import { useDataBlockRequest } from '../../../data-source'; import { useCollectionParentRecordData, useDataBlockRequest } from '../../../data-source';
import { Icon } from '../../../icon'; import { Icon } from '../../../icon';
import { TreeRecordProvider } from '../../../modules/blocks/data-blocks/table/TreeRecordProvider';
import { RecordProvider, useRecord } from '../../../record-provider'; import { RecordProvider, useRecord } from '../../../record-provider';
import { useLocalVariables, useVariables } from '../../../variables'; import { useLocalVariables, useVariables } from '../../../variables';
import { SortableItem } from '../../common'; import { SortableItem } from '../../common';
@ -63,6 +64,7 @@ export const Action: ComposedAction = withDynamicSchemaProps(
const compile = useCompile(); const compile = useCompile();
const form = useForm(); const form = useForm();
const record = useRecord(); const record = useRecord();
const parentRecordData = useCollectionParentRecordData();
const designerProps = fieldSchema['x-designer-props']; const designerProps = fieldSchema['x-designer-props'];
const openMode = fieldSchema?.['x-component-props']?.['openMode']; const openMode = fieldSchema?.['x-component-props']?.['openMode'];
const openSize = fieldSchema?.['x-component-props']?.['openSize']; const openSize = fieldSchema?.['x-component-props']?.['openSize'];
@ -202,8 +204,9 @@ export const Action: ComposedAction = withDynamicSchemaProps(
// fix https://nocobase.height.app/T-3235/description // fix https://nocobase.height.app/T-3235/description
if (addChild) { if (addChild) {
return wrapSSR( return wrapSSR(
<RecordProvider record={null} parent={record}> // fix https://nocobase.height.app/T-3966
{result} <RecordProvider record={null} parent={parentRecordData}>
<TreeRecordProvider parent={record}>{result}</TreeRecordProvider>
</RecordProvider>, </RecordProvider>,
); );
} }