From ca4ad2877b5a57720a9026333b64a67d3952d803 Mon Sep 17 00:00:00 2001 From: Zeke Zhang <958414905@qq.com> Date: Sun, 3 Nov 2024 08:23:34 +0800 Subject: [PATCH] fix: fix e2e error --- .../schema-settings/GeneralSchemaDesigner.tsx | 24 +++++++- .../src/schema-settings/SchemaSettings.tsx | 59 +++++++++++-------- 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/packages/core/client/src/schema-settings/GeneralSchemaDesigner.tsx b/packages/core/client/src/schema-settings/GeneralSchemaDesigner.tsx index 68a5fddbb9..0821adec40 100644 --- a/packages/core/client/src/schema-settings/GeneralSchemaDesigner.tsx +++ b/packages/core/client/src/schema-settings/GeneralSchemaDesigner.tsx @@ -12,7 +12,7 @@ import { css } from '@emotion/css'; import { useField, useFieldSchema } from '@formily/react'; import { Space } from 'antd'; import classNames from 'classnames'; -import React, { FC, useEffect, useMemo, useRef } from 'react'; +import React, { createContext, FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { SchemaInitializer, SchemaSettings, SchemaToolbarProvider, useSchemaInitializerRender } from '../application'; import { useSchemaSettingsRender } from '../application/schema-settings/hooks/useSchemaSettingsRender'; @@ -195,6 +195,7 @@ export interface SchemaToolbarProps { spaceWrapperStyle?: React.CSSProperties; spaceClassName?: string; spaceStyle?: React.CSSProperties; + onVisibleChange?: (nextVisible: boolean) => void; } const InternalSchemaToolbar: FC = (props) => { @@ -283,6 +284,7 @@ const InternalSchemaToolbar: FC = (props) => { return settings !== false && schemaSettingsExists ? schemaSettingsRender() : null; }, [schemaSettingsExists, schemaSettingsRender, settings]); const toolbarRef = useRef(null); + useEffect(() => { const toolbarElement = toolbarRef.current; let parentElement = toolbarElement?.parentElement; @@ -296,12 +298,14 @@ const InternalSchemaToolbar: FC = (props) => { function show() { if (toolbarElement) { toolbarElement.style.display = 'block'; + props.onVisibleChange?.(true); } } function hide() { if (toolbarElement) { toolbarElement.style.display = 'none'; + props.onVisibleChange?.(false); } } @@ -316,7 +320,7 @@ const InternalSchemaToolbar: FC = (props) => { parentElement.removeEventListener('mouseenter', show); parentElement.removeEventListener('mouseleave', hide); }; - }, []); + }, [props.onVisibleChange]); return (
= (props) => { ); }; +/** + * @internal + */ +export const SchemaToolbarVisibleContext = createContext(false); + export const SchemaToolbar: FC = React.memo((props) => { const { designable } = useDesignable(); + const [visible, setVisible] = useState(false); + + const onVisibleChange = useCallback((nextVisible: boolean) => { + setVisible(nextVisible); + }, []); if (!designable) { return null; } - return ; + return ( + + + + ); }); SchemaToolbar.displayName = 'SchemaToolbar'; diff --git a/packages/core/client/src/schema-settings/SchemaSettings.tsx b/packages/core/client/src/schema-settings/SchemaSettings.tsx index 2304da8b31..55ad75b461 100644 --- a/packages/core/client/src/schema-settings/SchemaSettings.tsx +++ b/packages/core/client/src/schema-settings/SchemaSettings.tsx @@ -38,12 +38,19 @@ import React, { useCallback, useContext, useEffect, + useLayoutEffect, useMemo, useState, } from 'react'; import { createPortal } from 'react-dom'; import { useTranslation } from 'react-i18next'; -import { SchemaSettingsItemType, VariablesContext } from '../'; +import { + SchemaSettingsItemType, + SchemaToolbarVisibleContext, + VariablesContext, + useCollection, + useCollectionManager, +} from '../'; import { APIClientProvider } from '../api-client/APIClientProvider'; import { useAPIClient } from '../api-client/hooks/useAPIClient'; import { ApplicationContext, LocationSearchContext, useApp, useLocationSearch } from '../application'; @@ -63,7 +70,6 @@ import { import { FormActiveFieldsProvider, useFormActiveFields } from '../block-provider/hooks'; import { useLinkageCollectionFilterOptions, useSortFields } from '../collection-manager/action-hooks'; import { useCollectionManager_deprecated } from '../collection-manager/hooks/useCollectionManager_deprecated'; -import { useCollection_deprecated } from '../collection-manager/hooks/useCollection_deprecated'; import { CollectionFieldOptions_deprecated } from '../collection-manager/types'; import { SelectWithTitle, SelectWithTitleProps } from '../common/SelectWithTitle'; import { useNiceDropdownMaxHeight } from '../common/useNiceDropdownHeight'; @@ -142,15 +148,20 @@ interface SchemaSettingsProviderProps { } export const SchemaSettingsProvider: React.FC = (props) => { - const { children, fieldSchema, ...others } = props; + const { children, fieldSchema } = props; const { getTemplateBySchema } = useSchemaTemplateManager(); - const { name } = useCollection_deprecated(); + const collection = useCollection(); const template = getTemplateBySchema(fieldSchema); - return ( - - {children} - + const value = useMemo( + () => ({ + ...props, + collectionName: collection?.name, + template, + fieldSchema, + }), + [collection?.name, fieldSchema, props, template], ); + return {children}; }; export const SchemaSettingsDropdown: React.FC = React.memo((props) => { @@ -159,26 +170,24 @@ export const SchemaSettingsDropdown: React.FC = React.memo( const { Component, getMenuItems } = useMenuItem(); const dropdownMaxHeight = useNiceDropdownMaxHeight([visible]); const [openDropdown, setOpenDropdown] = useState(false); + const toolbarVisible = useContext(SchemaToolbarVisibleContext); - const setDropdownVisible = (visible: boolean) => { - setVisible(visible); - - // 延迟 300ms 是为了避免对动画造成影响 - setTimeout(() => { - setOpenDropdown(visible); - }, 300); - }; + useLayoutEffect(() => { + if (toolbarVisible) { + setOpenDropdown(false); + } + }, [toolbarVisible]); const changeMenu: DropdownProps['onOpenChange'] = (nextOpen: boolean, info) => { if (info.source === 'trigger' || nextOpen) { // 当鼠标快速滑过时,终止菜单的渲染,防止卡顿 startTransition(() => { - setDropdownVisible(nextOpen); + setVisible(nextOpen); }); } }; - // 从这里截断,可以保证每次显示时都是最新的菜单列表 + // 从这里截断,可以保证每次显示时都是最新状态的菜单列表 if (!openDropdown) { return (
setOpenDropdown(true)} data-testid={props['data-testid']}> @@ -190,7 +199,7 @@ export const SchemaSettingsDropdown: React.FC = React.memo( const items = getMenuItems(() => props.children); return ( - + { setVisible(false); - const collection = collectionName && getCollection(collectionName); + const collection = collectionName && cm?.getCollection(collectionName); const gridSchema = findGridSchema(fieldSchema); const values = await FormDialog( t('Save as template'), @@ -785,7 +794,7 @@ export const SchemaSettingsModalItem: FC = (props) ...others } = props; const options = useContext(SchemaOptionsContext); - const collection = useCollection_deprecated(); + const collection = useCollection(); const apiClient = useAPIClient(); const app = useApp(); const { theme } = useGlobalTheme(); @@ -848,7 +857,7 @@ export const SchemaSettingsModalItem: FC = (props) @@ -922,7 +931,7 @@ export const SchemaSettingsDefaultSortingRules = function DefaultSortingRules(pr const fieldSchema = useFieldSchema(); const field = useField(); const title = props.title || t('Set default sorting rules'); - const { name } = useCollection_deprecated(); + const collection = useCollection(); const defaultSort = get(fieldSchema, path) || []; const sort = defaultSort?.map((item: string) => { return item.startsWith('-') @@ -935,7 +944,7 @@ export const SchemaSettingsDefaultSortingRules = function DefaultSortingRules(pr direction: 'asc', }; }); - const sortFields = useSortFields(props.name || name); + const sortFields = useSortFields(props.name || collection?.name); const onSubmit = async ({ sort }) => { if (props?.onSubmit) {