mirror of
https://github.com/nocobase/nocobase
synced 2024-11-16 02:45:14 +00:00
fix: fix e2e error
This commit is contained in:
parent
b3a4201a82
commit
ca4ad2877b
@ -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<SchemaToolbarProps> = (props) => {
|
||||
@ -283,6 +284,7 @@ const InternalSchemaToolbar: FC<SchemaToolbarProps> = (props) => {
|
||||
return settings !== false && schemaSettingsExists ? schemaSettingsRender() : null;
|
||||
}, [schemaSettingsExists, schemaSettingsRender, settings]);
|
||||
const toolbarRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const toolbarElement = toolbarRef.current;
|
||||
let parentElement = toolbarElement?.parentElement;
|
||||
@ -296,12 +298,14 @@ const InternalSchemaToolbar: FC<SchemaToolbarProps> = (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<SchemaToolbarProps> = (props) => {
|
||||
parentElement.removeEventListener('mouseenter', show);
|
||||
parentElement.removeEventListener('mouseleave', hide);
|
||||
};
|
||||
}, []);
|
||||
}, [props.onVisibleChange]);
|
||||
|
||||
return (
|
||||
<div
|
||||
@ -349,14 +353,28 @@ const InternalSchemaToolbar: FC<SchemaToolbarProps> = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const SchemaToolbarVisibleContext = createContext(false);
|
||||
|
||||
export const SchemaToolbar: FC<SchemaToolbarProps> = React.memo((props) => {
|
||||
const { designable } = useDesignable();
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
const onVisibleChange = useCallback((nextVisible: boolean) => {
|
||||
setVisible(nextVisible);
|
||||
}, []);
|
||||
|
||||
if (!designable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <InternalSchemaToolbar {...props} />;
|
||||
return (
|
||||
<SchemaToolbarVisibleContext.Provider value={visible}>
|
||||
<InternalSchemaToolbar {...props} onVisibleChange={onVisibleChange} />
|
||||
</SchemaToolbarVisibleContext.Provider>
|
||||
);
|
||||
});
|
||||
|
||||
SchemaToolbar.displayName = 'SchemaToolbar';
|
||||
|
@ -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<SchemaSettingsProviderProps> = (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 (
|
||||
<SchemaSettingsContext.Provider value={{ collectionName: name, template, fieldSchema, ...others }}>
|
||||
{children}
|
||||
</SchemaSettingsContext.Provider>
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
...props,
|
||||
collectionName: collection?.name,
|
||||
template,
|
||||
fieldSchema,
|
||||
}),
|
||||
[collection?.name, fieldSchema, props, template],
|
||||
);
|
||||
return <SchemaSettingsContext.Provider value={value}>{children}</SchemaSettingsContext.Provider>;
|
||||
};
|
||||
|
||||
export const SchemaSettingsDropdown: React.FC<SchemaSettingsProps> = React.memo((props) => {
|
||||
@ -159,26 +170,24 @@ export const SchemaSettingsDropdown: React.FC<SchemaSettingsProps> = 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 (
|
||||
<div onMouseEnter={() => setOpenDropdown(true)} data-testid={props['data-testid']}>
|
||||
@ -190,7 +199,7 @@ export const SchemaSettingsDropdown: React.FC<SchemaSettingsProps> = React.memo(
|
||||
const items = getMenuItems(() => props.children);
|
||||
|
||||
return (
|
||||
<SchemaSettingsProvider visible={visible} setVisible={setDropdownVisible} dn={dn} {...others}>
|
||||
<SchemaSettingsProvider visible={visible} setVisible={setVisible} dn={dn} {...others}>
|
||||
<Component />
|
||||
<Dropdown
|
||||
open={visible}
|
||||
@ -255,7 +264,7 @@ export const SchemaSettingsFormItemTemplate = function FormItemTemplate(props) {
|
||||
const { insertAdjacentPosition = 'afterBegin', componentName, collectionName, resourceName } = props;
|
||||
const { t } = useTranslation();
|
||||
const compile = useCompile();
|
||||
const { getCollection } = useCollectionManager_deprecated();
|
||||
const cm = useCollectionManager();
|
||||
const { dn, setVisible, template, fieldSchema } = useSchemaSettings();
|
||||
const api = useAPIClient();
|
||||
const { saveAsTemplate, copyTemplateSchema } = useSchemaTemplateManager();
|
||||
@ -307,7 +316,7 @@ export const SchemaSettingsFormItemTemplate = function FormItemTemplate(props) {
|
||||
title="Save as block template"
|
||||
onClick={async () => {
|
||||
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<SchemaSettingsModalItemProps> = (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<SchemaSettingsModalItemProps> = (props)
|
||||
<DataSourceApplicationProvider dataSourceManager={dm} dataSource={dataSourceKey}>
|
||||
<AssociationOrCollectionProvider
|
||||
allowNull
|
||||
collection={collection.name}
|
||||
collection={collection?.name}
|
||||
association={association}
|
||||
>
|
||||
<SchemaComponentOptions scope={options.scope} components={options.components}>
|
||||
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user