mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 09:29:16 +00:00
fix(TreeTable): add child error (#4008)
* fix(TreeTable): add new error * test: add e2e for T-3235 * fix: parentId
This commit is contained in:
parent
6d7ecba59e
commit
fa815aeb3c
@ -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;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -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,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
};
|
@ -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();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { useCollectionRecordData } from '../../data-source/collection-record/Col
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
* 大部分区块(除了详情和编辑表单)都适用的获取 sourceId 的 hook
|
* 大部分区块(除了详情和编辑表单)都适用的获取 sourceRecord 的 hook
|
||||||
* @param association
|
* @param association
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
|
@ -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>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user