optimize ParentPaths component (#5179)

* optimize ParentPaths component

* fix dataset list diaplay

* component
This commit is contained in:
heheer
2025-07-10 18:16:03 +08:00
committed by GitHub
parent ac493db00f
commit 7a6a396f2a
12 changed files with 141 additions and 127 deletions

View File

@@ -45,6 +45,7 @@ export const iconPaths = {
'common/download': () => import('./icons/common/download.svg'),
'common/edit': () => import('./icons/common/edit.svg'),
'common/editor/resizer': () => import('./icons/common/editor/resizer.svg'),
'common/ellipsis': () => import('./icons/common/ellipsis.svg'),
'common/enable': () => import('./icons/common/enable.svg'),
'common/errorFill': () => import('./icons/common/errorFill.svg'),
'common/file/move': () => import('./icons/common/file/move.svg'),

View File

@@ -0,0 +1,4 @@
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" >
<path d="M221 592c-44.183 0-80-35.817-80-80s35.817-80 80-80 80 35.817 80 80-35.817 80-80 80z m291 0c-44.183 0-80-35.817-80-80s35.817-80 80-80 80 35.817 80 80-35.817 80-80 80z m291 0c-44.183 0-80-35.817-80-80s35.817-80 80-80 80 35.817 80 80-35.817 80-80 80z">
</path>
</svg>

After

Width:  |  Height:  |  Size: 362 B

View File

@@ -326,6 +326,7 @@ const MyMenu = ({
<Box
w={'100%'}
color={child.description ? 'myGray.900' : 'inherit'}
pr={child.icon ? 4 : 0}
{...sizeMapStyle[size].labelStyle}
>
{child.label}

View File

@@ -1,67 +0,0 @@
import { Box, Flex } from '@chakra-ui/react';
import { type ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type';
import React, { useMemo } from 'react';
import { useTranslation } from 'next-i18next';
const ParentPaths = (props: {
paths?: ParentTreePathItemType[];
rootName?: string;
FirstPathDom?: React.ReactNode;
onClick: (parentId: string) => void;
fontSize?: string;
}) => {
const { t } = useTranslation();
const { paths = [], rootName = t('common:root_folder'), FirstPathDom, onClick, fontSize } = props;
const concatPaths = useMemo(
() => [
{
parentId: '',
parentName: rootName
},
...paths
],
[rootName, paths]
);
return paths.length === 0 && !!FirstPathDom ? (
<>{FirstPathDom}</>
) : (
<Flex flex={1} ml={-2}>
{concatPaths.map((item, i) => (
<Flex key={item.parentId || i} alignItems={'center'}>
<Box
fontSize={['sm', fontSize || 'sm']}
py={0.5}
px={1.5}
borderRadius={'md'}
{...(i === concatPaths.length - 1
? {
cursor: 'default',
color: 'myGray.700',
fontWeight: 'bold'
}
: {
cursor: 'pointer',
color: 'myGray.600',
_hover: {
bg: 'myGray.100'
},
onClick: () => {
onClick(item.parentId);
}
})}
>
{item.parentName}
</Box>
{i !== concatPaths.length - 1 && (
<Box mx={1} color={'myGray.500'}>
/
</Box>
)}
</Flex>
))}
</Flex>
);
};
export default React.memo(ParentPaths);

View File

@@ -3,6 +3,8 @@ import { type ParentTreePathItemType } from '@fastgpt/global/common/parentFolder
import React, { useMemo } from 'react';
import { useTranslation } from 'next-i18next';
import MyIcon from '@fastgpt/web/components/common/Icon';
import MyMenu from '@fastgpt/web/components/common/MyMenu';
import MyTooltip from '@fastgpt/web/components/common/MyTooltip';
const FolderPath = (props: {
paths: ParentTreePathItemType[];
@@ -35,50 +37,116 @@ const FolderPath = (props: {
[rootName, paths]
);
const displayPaths = useMemo(() => {
if (concatPaths.length <= 3) {
return concatPaths;
} else {
return [
concatPaths[0],
null,
concatPaths[concatPaths.length - 2],
concatPaths[concatPaths.length - 1]
];
}
}, [concatPaths]);
const renderPathItem = (item: (typeof concatPaths)[0] | null, index: number) => {
if (item === null) {
const middlePaths = concatPaths.slice(1, -2);
return (
<Flex alignItems={'center'} key={index}>
<MyMenu
Button={
<Box
fontSize={['sm', fontSize || 'sm']}
py={0.5}
px={1}
color={'myGray.600'}
borderRadius={'sm'}
cursor="pointer"
display={'flex'}
alignItems={'center'}
_hover={{
bg: 'myGray.200'
}}
>
<MyIcon name={'common/ellipsis'} color={'myGray.500'} width={'12px'} />
</Box>
}
trigger={'hover'}
size={'xs'}
menuList={[
{
children: middlePaths.map((pathItem) => ({
label: (
<Box overflow={'hidden'} textOverflow={'ellipsis'} whiteSpace={'nowrap'}>
{pathItem.parentName}
</Box>
),
icon: 'file/fill/folder',
onClick: () => onClick(pathItem.parentId)
}))
}
]}
/>
<MyIcon name={'common/line'} color={'myGray.500'} mx={1} width={'5px'} />
</Flex>
);
}
const isLast = index === displayPaths.length - 1;
const clickStyles = {
cursor: 'pointer',
_hover: {
bg: 'myGray.100',
...hoverStyle
},
onClick: () => {
onClick(item.parentId);
}
};
const shouldTruncate = !isLast && item.parentName.length > 10;
const displayName = shouldTruncate ? `${item.parentName.slice(0, 10)}...` : item.parentName;
const pathBox = (
<Box
fontSize={['xs', fontSize || 'sm']}
py={0.5}
px={1.5}
borderRadius={'sm'}
maxW={'45vw'}
className={'textEllipsis'}
{...(isLast && concatPaths.length > 1
? {
color: 'myGray.700',
fontWeight: 'bold'
}
: {
fontWeight: 'medium',
color: 'myGray.500',
...clickStyles
})}
{...(isLast && !forbidLastClick && clickStyles)}
>
{displayName}
</Box>
);
return (
<Flex key={item.parentId || index} alignItems={'center'}>
{shouldTruncate ? <MyTooltip label={item.parentName}>{pathBox}</MyTooltip> : pathBox}
{!isLast && <MyIcon name={'common/line'} color={'myGray.500'} mx={1} width={'5px'} />}
</Flex>
);
};
return paths.length === 0 && !!FirstPathDom ? (
<>{FirstPathDom}</>
) : (
<Flex flex={1}>
{concatPaths.map((item, i) => {
const clickStyles = {
cursor: 'pointer',
_hover: {
bg: 'myGray.100',
...hoverStyle
},
onClick: () => {
onClick(item.parentId);
}
};
return (
<Flex key={item.parentId || i} alignItems={'center'}>
<Box
fontSize={['xs', fontSize || 'sm']}
py={0.5}
px={1.5}
borderRadius={'md'}
maxW={'45vw'}
className={'textEllipsis'}
{...(i === concatPaths.length - 1 && concatPaths.length > 1
? {
color: 'myGray.700',
fontWeight: 'bold'
}
: {
fontWeight: 'medium',
color: 'myGray.500',
...clickStyles
})}
{...(i === concatPaths.length - 1 && !forbidLastClick && clickStyles)}
>
{item.parentName}
</Box>
{i !== concatPaths.length - 1 && (
<MyIcon name={'common/line'} color={'myGray.500'} mx={1} width={'5px'} />
)}
</Flex>
);
})}
<Flex flex={1} ml={-2}>
{displayPaths.map((item, index) => renderPathItem(item, index))}
</Flex>
);
};

View File

@@ -51,7 +51,14 @@ const FolderSlideCard = ({
<Box>
<HStack>
<MyIcon name={FolderIcon} w={'1.5rem'} />
<Box color={'myGray.900'}>{name}</Box>
<Box
color={'myGray.900'}
overflow={'hidden'}
textOverflow={'ellipsis'}
whiteSpace={'nowrap'}
>
{name}
</Box>
<MyIcon
name={'edit'}
_hover={{ color: 'primary.600' }}

View File

@@ -4,7 +4,7 @@ import { useQuery } from '@tanstack/react-query';
import React, { type Dispatch, useMemo, useState } from 'react';
import { useTranslation } from 'next-i18next';
import { Box } from '@chakra-ui/react';
import ParentPaths from '@/components/common/ParentPaths';
import FolderPath from '@/components/common/folder/Path';
import MyBox from '@fastgpt/web/components/common/MyBox';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
@@ -37,7 +37,7 @@ const DatasetSelectContainer = ({
iconSrc="/imgs/workflow/db.png"
title={
<Box fontWeight={'normal'}>
<ParentPaths
<FolderPath
paths={paths.map((path, i) => ({
parentId: path.parentId,
parentName: path.parentName

View File

@@ -22,7 +22,7 @@ import {
} from '@fastgpt/global/core/dataset/constants';
import EditFolderModal, { useEditFolder } from '../../EditFolderModal';
import { TabEnum } from '../../../../pages/dataset/detail/index';
import ParentPath from '@/components/common/ParentPaths';
import FolderPath from '@/components/common/folder/Path';
import dynamic from 'next/dynamic';
import { ImportDataSourceEnum } from '@fastgpt/global/core/dataset/constants';
@@ -117,7 +117,7 @@ const Header = ({ hasTrainingData }: { hasTrainingData: boolean }) => {
<MyBox display={['block', 'flex']} alignItems={'center'} gap={2}>
<HStack flex={1}>
<Box flex={1} fontWeight={'500'} color={'myGray.900'} whiteSpace={'nowrap'}>
<ParentPath
<FolderPath
paths={paths.map((path, i) => ({
parentId: path.parentId,
parentName: i === paths.length - 1 ? `${path.parentName}` : path.parentName

View File

@@ -8,7 +8,7 @@ import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContex
import LightRowTabs from '@fastgpt/web/components/common/Tabs/LightRowTabs';
import { useSystem } from '@fastgpt/web/hooks/useSystem';
import MyPopover from '@fastgpt/web/components/common/MyPopover';
import ParentPaths from '@/components/common/ParentPaths';
import FolderPath from '@/components/common/folder/Path';
import { getTrainingQueueLen } from '@/web/core/dataset/api';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
@@ -166,7 +166,7 @@ const NavBar = ({ currentTab }: { currentTab: TabEnum }) => {
</>
) : (
<Flex py={'0.38rem'} px={2} h={10} ml={0.5}>
<ParentPaths
<FolderPath
paths={paths}
onClick={(e) => {
router.push(`/dataset/list?parentId=${e}`);

View File

@@ -219,14 +219,14 @@ function List() {
}
}}
>
<HStack>
<Avatar src={dataset.avatar} borderRadius={6} w={'28px'} />
<Box flex={'1 0 0'} className="textEllipsis3" color={'myGray.900'}>
<Flex w="100%">
<Avatar src={dataset.avatar} borderRadius={6} w={'28px'} flexShrink={0} />
<Box width="0" flex="1" className="textEllipsis" color={'myGray.900'} ml={2}>
{dataset.name}
</Box>
<Box mr={'-1.25rem'}>
{dataset.type !== DatasetTypeEnum.folder && (
{dataset.type !== DatasetTypeEnum.folder && (
<Box flexShrink={0} ml={2}>
<SideTag
type={dataset.type}
py={0.5}
@@ -234,9 +234,9 @@ function List() {
borderLeftRadius={'sm'}
borderRightRadius={0}
/>
)}
</Box>
</HStack>
</Box>
)}
</Flex>
<Box
flex={1}

View File

@@ -4,7 +4,7 @@ import { Box, Flex, Button, InputGroup, InputLeftElement, Input } from '@chakra-
import { useRouter } from 'next/router';
import { useTranslation } from 'next-i18next';
import { serviceSideProps } from '@/web/common/i18n/utils';
import ParentPaths from '@/components/common/folder/Path';
import FolderPath from '@/components/common/folder/Path';
import List from '@/pageComponents/dataset/list/List';
import { DatasetsContext } from './context';
import DatasetContextProvider from './context';
@@ -108,7 +108,7 @@ const Dataset = () => {
<Flex pt={[4, 6]} pl={3} pr={folderDetail ? [3, 6] : [3, 8]}>
<Flex flexGrow={1} flexDirection="column">
<Flex alignItems={'center'} justifyContent={'space-between'}>
<ParentPaths
<FolderPath
paths={paths}
FirstPathDom={
<Flex flex={1} alignItems={'center'}>

View File

@@ -1,6 +1,6 @@
import MyIcon from '@fastgpt/web/components/common/Icon';
import MyModal from '@fastgpt/web/components/common/MyModal';
import ParentPaths from '@/components/common/ParentPaths';
import FolderPath from '@/components/common/folder/Path';
import { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { getDatasetCollectionPathById, getDatasetCollections } from '@/web/core/dataset/api';
import { Box, Flex, ModalFooter, Button, useTheme, Grid, Card, ModalBody } from '@chakra-ui/react';
@@ -114,7 +114,7 @@ const SelectCollections = ({
iconSrc="/imgs/modal/move.svg"
title={
<Box>
<ParentPaths
<FolderPath
paths={paths.map((path) => ({
parentId: path.parentId,
parentName: path.parentName