mirror of
https://github.com/labring/FastGPT.git
synced 2025-10-16 08:01:18 +00:00
optimize ParentPaths component (#5179)
* optimize ParentPaths component * fix dataset list diaplay * component
This commit is contained in:
@@ -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'),
|
||||
|
@@ -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 |
@@ -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}
|
||||
|
@@ -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);
|
@@ -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>
|
||||
);
|
||||
};
|
||||
|
@@ -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' }}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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}`);
|
||||
|
@@ -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}
|
||||
|
@@ -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'}>
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user