fix(filterBlocks): make e2e tests pass

This commit is contained in:
Zeke Zhang 2024-11-02 12:15:45 +08:00
parent fee1c2999c
commit 4d709fa9e9
6 changed files with 58 additions and 27 deletions

View File

@ -497,7 +497,11 @@ const useDoFilter = () => {
// 这里的代码是为了实现:筛选表单的筛选操作在首次渲染时自动执行一次
useEffect(() => {
doFilter({ doNothingWhenFilterIsEmpty: true });
// 使用 setTimeout 是为了等待筛选表单的变量解析完成,否则会因为获取的 filter 为空而导致筛选表单的筛选操作不执行。
// 另外,如果不加 100 毫秒的延迟,会导致数据区块列表更新后,不触发筛选操作的问题。
setTimeout(() => {
doFilter({ doNothingWhenFilterIsEmpty: true });
}, 100);
}, [getDataBlocks().length]);
return {

View File

@ -7,7 +7,8 @@
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import React, { FC, ReactNode, createContext, useContext } from 'react';
import React, { FC, ReactNode, createContext, useCallback, useContext } from 'react';
import { InheritanceCollectionMixin } from '../../collection-manager/mixins/InheritanceCollectionMixin';
import type { DataSourceManager } from './DataSourceManager';
export const DataSourceManagerContext = createContext<DataSourceManager>(null);
@ -26,3 +27,22 @@ export function useDataSourceManager() {
const context = useContext<DataSourceManager>(DataSourceManagerContext);
return context;
}
/**
* collection collection
* @returns
*/
export function useAllCollectionsInheritChainGetter() {
const dm = useDataSourceManager();
const getAllCollectionsInheritChain = useCallback(
(collectionName: string, customDataSource?: string) => {
return dm
?.getDataSource(customDataSource)
?.collectionManager?.getCollection<InheritanceCollectionMixin>(collectionName)
?.getAllCollectionsInheritChain();
},
[dm],
);
return { getAllCollectionsInheritChain };
}

View File

@ -18,7 +18,7 @@ import { removeNullCondition } from '../schema-component';
import { mergeFilter, useAssociatedFields } from './utils';
// @ts-ignore
import React, { createContext, useCallback, useEffect, useMemo, useRef } from 'react';
import React, { createContext, useCallback, useLayoutEffect, useMemo, useRef } from 'react';
enum FILTER_OPERATOR {
AND = '$and',
@ -177,7 +177,7 @@ export const DataBlockCollector = ({
getDataBlockRequest,
]);
useEffect(() => {
useLayoutEffect(() => {
if (shouldApplyFilter) addBlockToDataBlocks();
}, [addBlockToDataBlocks, shouldApplyFilter]);

View File

@ -12,10 +12,10 @@ import { flatten, getValuesByPath } from '@nocobase/utils/client';
import _ from 'lodash';
import { useCallback, useEffect, useState } from 'react';
import { FilterTarget, findFilterTargets } from '../block-provider/hooks';
import { CollectionFieldOptions_deprecated, FieldOptions, InheritanceCollectionMixin } from '../collection-manager';
import { CollectionFieldOptions_deprecated, FieldOptions } from '../collection-manager';
import { Collection } from '../data-source/collection/Collection';
import { useCollection } from '../data-source/collection/CollectionProvider';
import { useDataSourceManager } from '../data-source/data-source/DataSourceManagerProvider';
import { useAllCollectionsInheritChainGetter } from '../data-source/data-source/DataSourceManagerProvider';
import { removeNullCondition } from '../schema-component';
import { DataBlock, useFilterBlock } from './FilterProvider';
@ -61,21 +61,10 @@ export const getSupportFieldsByForeignKey = (filterBlockCollection: Collection,
* @returns
*/
export const useSupportedBlocks = (filterBlockType: FilterBlockType) => {
const dm = useDataSourceManager();
const { getDataBlocks } = useFilterBlock();
const fieldSchema = useFieldSchema();
const collection = useCollection();
// 获取当前 collection 继承链路上的所有 collection
const getAllCollectionsInheritChain = useCallback(
(collectionName: string, customDataSource?: string) => {
return dm
?.getDataSource(customDataSource)
?.collectionManager?.getCollection<InheritanceCollectionMixin>(collectionName)
?.getAllCollectionsInheritChain();
},
[dm],
);
const { getAllCollectionsInheritChain } = useAllCollectionsInheritChainGetter();
// Form 和 Collapse 仅支持同表的数据区块
if (filterBlockType === FilterBlockType.FORM || filterBlockType === FilterBlockType.COLLAPSE) {

View File

@ -33,12 +33,12 @@ import React, {
FC,
ReactNode,
createContext,
// @ts-ignore
startTransition,
useCallback,
useContext,
useEffect,
useMemo,
// @ts-ignore
useTransition as useReactTransition,
useState,
} from 'react';
import { createPortal } from 'react-dom';
@ -157,22 +157,40 @@ export const SchemaSettingsDropdown: React.FC<SchemaSettingsProps> = React.memo(
const { title, dn, ...others } = props;
const [visible, setVisible] = useState(false);
const { Component, getMenuItems } = useMenuItem();
const [, startTransition] = useReactTransition();
const dropdownMaxHeight = useNiceDropdownMaxHeight([visible]);
const [openDropdown, setOpenDropdown] = useState(false);
const changeMenu: DropdownProps['onOpenChange'] = useCallback((nextOpen: boolean, info) => {
const setDropdownVisible = (visible: boolean) => {
setVisible(visible);
// 延迟 300ms 是为了避免对动画造成影响
setTimeout(() => {
setOpenDropdown(visible);
}, 300);
};
const changeMenu: DropdownProps['onOpenChange'] = (nextOpen: boolean, info) => {
if (info.source === 'trigger' || nextOpen) {
// 当鼠标快速滑过时,终止菜单的渲染,防止卡顿
startTransition(() => {
setVisible(nextOpen);
setDropdownVisible(nextOpen);
});
}
}, []);
};
// 从这里截断,可以保证每次显示时都是最新的菜单列表
if (!openDropdown) {
return (
<div onMouseEnter={() => setOpenDropdown(true)} data-testid={props['data-testid']}>
{typeof title === 'string' ? <span>{title}</span> : title}
</div>
);
}
const items = getMenuItems(() => props.children);
return (
<SchemaSettingsProvider visible={visible} setVisible={setVisible} dn={dn} {...others}>
<SchemaSettingsProvider visible={visible} setVisible={setDropdownVisible} dn={dn} {...others}>
<Component />
<Dropdown
open={visible}

View File

@ -13,8 +13,8 @@ import { Empty } from 'antd';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { findFilterTargets, updateFilterTargets } from '../block-provider/hooks';
import { useCollectionManager_deprecated } from '../collection-manager/hooks/useCollectionManager_deprecated';
import { useCollection } from '../data-source/collection/CollectionProvider';
import { useAllCollectionsInheritChainGetter } from '../data-source/data-source/DataSourceManagerProvider';
import { useFilterBlock } from '../filter-provider/FilterProvider';
import {
getSupportFieldsByAssociation,
@ -43,7 +43,7 @@ export function SchemaSettingsConnectDataBlocks(props) {
// eslint-disable-next-line prefer-const
let { targets = [], uid } = findFilterTargets(fieldSchema);
const compile = useCompile();
const { getAllCollectionsInheritChain } = useCollectionManager_deprecated();
const { getAllCollectionsInheritChain } = useAllCollectionsInheritChainGetter();
if (!inProvider) {
return null;