mirror of
https://github.com/labring/FastGPT.git
synced 2025-10-15 15:41:05 +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/download': () => import('./icons/common/download.svg'),
|
||||||
'common/edit': () => import('./icons/common/edit.svg'),
|
'common/edit': () => import('./icons/common/edit.svg'),
|
||||||
'common/editor/resizer': () => import('./icons/common/editor/resizer.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/enable': () => import('./icons/common/enable.svg'),
|
||||||
'common/errorFill': () => import('./icons/common/errorFill.svg'),
|
'common/errorFill': () => import('./icons/common/errorFill.svg'),
|
||||||
'common/file/move': () => import('./icons/common/file/move.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
|
<Box
|
||||||
w={'100%'}
|
w={'100%'}
|
||||||
color={child.description ? 'myGray.900' : 'inherit'}
|
color={child.description ? 'myGray.900' : 'inherit'}
|
||||||
|
pr={child.icon ? 4 : 0}
|
||||||
{...sizeMapStyle[size].labelStyle}
|
{...sizeMapStyle[size].labelStyle}
|
||||||
>
|
>
|
||||||
{child.label}
|
{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 React, { useMemo } from 'react';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
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: {
|
const FolderPath = (props: {
|
||||||
paths: ParentTreePathItemType[];
|
paths: ParentTreePathItemType[];
|
||||||
@@ -35,50 +37,116 @@ const FolderPath = (props: {
|
|||||||
[rootName, paths]
|
[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 ? (
|
return paths.length === 0 && !!FirstPathDom ? (
|
||||||
<>{FirstPathDom}</>
|
<>{FirstPathDom}</>
|
||||||
) : (
|
) : (
|
||||||
<Flex flex={1}>
|
<Flex flex={1} ml={-2}>
|
||||||
{concatPaths.map((item, i) => {
|
{displayPaths.map((item, index) => renderPathItem(item, index))}
|
||||||
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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -51,7 +51,14 @@ const FolderSlideCard = ({
|
|||||||
<Box>
|
<Box>
|
||||||
<HStack>
|
<HStack>
|
||||||
<MyIcon name={FolderIcon} w={'1.5rem'} />
|
<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
|
<MyIcon
|
||||||
name={'edit'}
|
name={'edit'}
|
||||||
_hover={{ color: 'primary.600' }}
|
_hover={{ color: 'primary.600' }}
|
||||||
|
@@ -4,7 +4,7 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
import React, { type Dispatch, useMemo, useState } from 'react';
|
import React, { type Dispatch, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { Box } from '@chakra-ui/react';
|
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 MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ const DatasetSelectContainer = ({
|
|||||||
iconSrc="/imgs/workflow/db.png"
|
iconSrc="/imgs/workflow/db.png"
|
||||||
title={
|
title={
|
||||||
<Box fontWeight={'normal'}>
|
<Box fontWeight={'normal'}>
|
||||||
<ParentPaths
|
<FolderPath
|
||||||
paths={paths.map((path, i) => ({
|
paths={paths.map((path, i) => ({
|
||||||
parentId: path.parentId,
|
parentId: path.parentId,
|
||||||
parentName: path.parentName
|
parentName: path.parentName
|
||||||
|
@@ -22,7 +22,7 @@ import {
|
|||||||
} from '@fastgpt/global/core/dataset/constants';
|
} from '@fastgpt/global/core/dataset/constants';
|
||||||
import EditFolderModal, { useEditFolder } from '../../EditFolderModal';
|
import EditFolderModal, { useEditFolder } from '../../EditFolderModal';
|
||||||
import { TabEnum } from '../../../../pages/dataset/detail/index';
|
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 dynamic from 'next/dynamic';
|
||||||
|
|
||||||
import { ImportDataSourceEnum } from '@fastgpt/global/core/dataset/constants';
|
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}>
|
<MyBox display={['block', 'flex']} alignItems={'center'} gap={2}>
|
||||||
<HStack flex={1}>
|
<HStack flex={1}>
|
||||||
<Box flex={1} fontWeight={'500'} color={'myGray.900'} whiteSpace={'nowrap'}>
|
<Box flex={1} fontWeight={'500'} color={'myGray.900'} whiteSpace={'nowrap'}>
|
||||||
<ParentPath
|
<FolderPath
|
||||||
paths={paths.map((path, i) => ({
|
paths={paths.map((path, i) => ({
|
||||||
parentId: path.parentId,
|
parentId: path.parentId,
|
||||||
parentName: i === paths.length - 1 ? `${path.parentName}` : path.parentName
|
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 LightRowTabs from '@fastgpt/web/components/common/Tabs/LightRowTabs';
|
||||||
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
||||||
import MyPopover from '@fastgpt/web/components/common/MyPopover';
|
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 { getTrainingQueueLen } from '@/web/core/dataset/api';
|
||||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
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}>
|
<Flex py={'0.38rem'} px={2} h={10} ml={0.5}>
|
||||||
<ParentPaths
|
<FolderPath
|
||||||
paths={paths}
|
paths={paths}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
router.push(`/dataset/list?parentId=${e}`);
|
router.push(`/dataset/list?parentId=${e}`);
|
||||||
|
@@ -219,14 +219,14 @@ function List() {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<HStack>
|
<Flex w="100%">
|
||||||
<Avatar src={dataset.avatar} borderRadius={6} w={'28px'} />
|
<Avatar src={dataset.avatar} borderRadius={6} w={'28px'} flexShrink={0} />
|
||||||
<Box flex={'1 0 0'} className="textEllipsis3" color={'myGray.900'}>
|
<Box width="0" flex="1" className="textEllipsis" color={'myGray.900'} ml={2}>
|
||||||
{dataset.name}
|
{dataset.name}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box mr={'-1.25rem'}>
|
{dataset.type !== DatasetTypeEnum.folder && (
|
||||||
{dataset.type !== DatasetTypeEnum.folder && (
|
<Box flexShrink={0} ml={2}>
|
||||||
<SideTag
|
<SideTag
|
||||||
type={dataset.type}
|
type={dataset.type}
|
||||||
py={0.5}
|
py={0.5}
|
||||||
@@ -234,9 +234,9 @@ function List() {
|
|||||||
borderLeftRadius={'sm'}
|
borderLeftRadius={'sm'}
|
||||||
borderRightRadius={0}
|
borderRightRadius={0}
|
||||||
/>
|
/>
|
||||||
)}
|
</Box>
|
||||||
</Box>
|
)}
|
||||||
</HStack>
|
</Flex>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
flex={1}
|
flex={1}
|
||||||
|
@@ -4,7 +4,7 @@ import { Box, Flex, Button, InputGroup, InputLeftElement, Input } from '@chakra-
|
|||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { serviceSideProps } from '@/web/common/i18n/utils';
|
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 List from '@/pageComponents/dataset/list/List';
|
||||||
import { DatasetsContext } from './context';
|
import { DatasetsContext } from './context';
|
||||||
import DatasetContextProvider 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 pt={[4, 6]} pl={3} pr={folderDetail ? [3, 6] : [3, 8]}>
|
||||||
<Flex flexGrow={1} flexDirection="column">
|
<Flex flexGrow={1} flexDirection="column">
|
||||||
<Flex alignItems={'center'} justifyContent={'space-between'}>
|
<Flex alignItems={'center'} justifyContent={'space-between'}>
|
||||||
<ParentPaths
|
<FolderPath
|
||||||
paths={paths}
|
paths={paths}
|
||||||
FirstPathDom={
|
FirstPathDom={
|
||||||
<Flex flex={1} alignItems={'center'}>
|
<Flex flex={1} alignItems={'center'}>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
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 { useRequest, useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import { getDatasetCollectionPathById, getDatasetCollections } from '@/web/core/dataset/api';
|
import { getDatasetCollectionPathById, getDatasetCollections } from '@/web/core/dataset/api';
|
||||||
import { Box, Flex, ModalFooter, Button, useTheme, Grid, Card, ModalBody } from '@chakra-ui/react';
|
import { Box, Flex, ModalFooter, Button, useTheme, Grid, Card, ModalBody } from '@chakra-ui/react';
|
||||||
@@ -114,7 +114,7 @@ const SelectCollections = ({
|
|||||||
iconSrc="/imgs/modal/move.svg"
|
iconSrc="/imgs/modal/move.svg"
|
||||||
title={
|
title={
|
||||||
<Box>
|
<Box>
|
||||||
<ParentPaths
|
<FolderPath
|
||||||
paths={paths.map((path) => ({
|
paths={paths.map((path) => ({
|
||||||
parentId: path.parentId,
|
parentId: path.parentId,
|
||||||
parentName: path.parentName
|
parentName: path.parentName
|
||||||
|
Reference in New Issue
Block a user