From 84afb4259ca5489c8cc3ed66643b442fbdff57ad Mon Sep 17 00:00:00 2001 From: balibabu Date: Wed, 4 Dec 2024 19:10:08 +0800 Subject: [PATCH] Feat: Bind the route to the navigation bar in the head #3221 (#3863) ### What problem does this PR solve? Feat: Bind the route to the navigation bar in the head #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- web/src/components/knowledge-base-item.tsx | 4 +- web/src/components/ui/skeleton.tsx | 39 +++++ web/src/hooks/knowledge-hooks.ts | 2 +- web/src/hooks/logic-hooks/navigate-hooks.ts | 21 +++ web/src/layouts/next-header.tsx | 54 +++++-- web/src/pages/agent/index.tsx | 3 + .../connect-to-knowledge-modal/index.tsx | 4 +- .../pages/flow/canvas/node/retrieval-node.tsx | 4 +- web/src/pages/home/datasets.tsx | 138 +++++++++--------- web/src/pages/next-chat/index.tsx | 3 + web/src/pages/next-search/index.tsx | 3 + web/src/pages/search/index.tsx | 4 +- web/src/pages/search/sidebar.tsx | 4 +- web/src/routes.ts | 76 ++++++++-- 14 files changed, 246 insertions(+), 113 deletions(-) create mode 100644 web/src/components/ui/skeleton.tsx create mode 100644 web/src/hooks/logic-hooks/navigate-hooks.ts create mode 100644 web/src/pages/agent/index.tsx create mode 100644 web/src/pages/next-chat/index.tsx create mode 100644 web/src/pages/next-search/index.tsx diff --git a/web/src/components/knowledge-base-item.tsx b/web/src/components/knowledge-base-item.tsx index 331da8e6..57fcfef3 100644 --- a/web/src/components/knowledge-base-item.tsx +++ b/web/src/components/knowledge-base-item.tsx @@ -1,12 +1,12 @@ import { useTranslate } from '@/hooks/common-hooks'; -import { useNextFetchKnowledgeList } from '@/hooks/knowledge-hooks'; +import { useFetchKnowledgeList } from '@/hooks/knowledge-hooks'; import { UserOutlined } from '@ant-design/icons'; import { Avatar, Form, Select, Space } from 'antd'; const KnowledgeBaseItem = () => { const { t } = useTranslate('chat'); - const { list: knowledgeList } = useNextFetchKnowledgeList(true); + const { list: knowledgeList } = useFetchKnowledgeList(true); const knowledgeOptions = knowledgeList.map((x) => ({ label: ( diff --git a/web/src/components/ui/skeleton.tsx b/web/src/components/ui/skeleton.tsx new file mode 100644 index 00000000..c896c7e4 --- /dev/null +++ b/web/src/components/ui/skeleton.tsx @@ -0,0 +1,39 @@ +import { cn } from '@/lib/utils'; + +function Skeleton({ + className, + ...props +}: React.HTMLAttributes) { + return ( +
+ ); +} + +function ParagraphSkeleton() { + return ( +
+ +
+ + +
+
+ ); +} + +function CardSkeleton() { + return ( +
+ +
+ + +
+
+ ); +} + +export { CardSkeleton, ParagraphSkeleton, Skeleton }; diff --git a/web/src/hooks/knowledge-hooks.ts b/web/src/hooks/knowledge-hooks.ts index 1e00e8c0..6f972f5b 100644 --- a/web/src/hooks/knowledge-hooks.ts +++ b/web/src/hooks/knowledge-hooks.ts @@ -41,7 +41,7 @@ export const useFetchKnowledgeBaseConfiguration = () => { return { data, loading }; }; -export const useNextFetchKnowledgeList = ( +export const useFetchKnowledgeList = ( shouldFilterListWithoutDocument: boolean = false, ): { list: IKnowledge[]; diff --git a/web/src/hooks/logic-hooks/navigate-hooks.ts b/web/src/hooks/logic-hooks/navigate-hooks.ts new file mode 100644 index 00000000..3ad02f08 --- /dev/null +++ b/web/src/hooks/logic-hooks/navigate-hooks.ts @@ -0,0 +1,21 @@ +import { Routes } from '@/routes'; +import { useCallback } from 'react'; +import { useNavigate } from 'umi'; + +export const useNavigatePage = () => { + const navigate = useNavigate(); + + const navigateToDatasetList = useCallback(() => { + navigate(Routes.Datasets); + }, [navigate]); + + const navigateToDataset = useCallback(() => { + navigate(Routes.Dataset); + }, [navigate]); + + const navigateToHome = useCallback(() => { + navigate(Routes.Home); + }, [navigate]); + + return { navigateToDatasetList, navigateToDataset, navigateToHome }; +}; diff --git a/web/src/layouts/next-header.tsx b/web/src/layouts/next-header.tsx index d65cc116..3692d794 100644 --- a/web/src/layouts/next-header.tsx +++ b/web/src/layouts/next-header.tsx @@ -3,32 +3,37 @@ import { Button } from '@/components/ui/button'; import { Container } from '@/components/ui/container'; import { Segmented, SegmentedValue } from '@/components/ui/segmented '; import { useTranslate } from '@/hooks/common-hooks'; +import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks'; import { useNavigateWithFromState } from '@/hooks/route-hook'; +import { cn } from '@/lib/utils'; +import { Routes } from '@/routes'; import { ChevronDown, Cpu, Github, + House, Library, MessageSquareText, Search, Star, Zap, } from 'lucide-react'; -import { useCallback, useMemo, useState } from 'react'; +import { useCallback, useMemo } from 'react'; import { useLocation } from 'umi'; export function Header() { const { t } = useTranslate('header'); const { pathname } = useLocation(); const navigate = useNavigateWithFromState(); - const [currentPath, setCurrentPath] = useState('/home'); + // const [currentPath, setCurrentPath] = useState(Routes.Home); + const { navigateToHome } = useNavigatePage(); const tagsData = useMemo( () => [ - { path: '/home', name: t('knowledgeBase'), icon: Library }, - { path: '/chat', name: t('chat'), icon: MessageSquareText }, - { path: '/search', name: t('search'), icon: Search }, - { path: '/flow', name: t('flow'), icon: Cpu }, + { path: Routes.Datasets, name: t('knowledgeBase'), icon: Library }, + { path: Routes.Chat, name: t('chat'), icon: MessageSquareText }, + { path: Routes.Search, name: t('search'), icon: Search }, + { path: Routes.Agent, name: t('flow'), icon: Cpu }, // { path: '/file', name: t('fileManager'), icon: FileIcon }, ], [t], @@ -50,17 +55,21 @@ export function Header() { }); }, [tagsData]); - // const currentPath = useMemo(() => { - // return tagsData.find((x) => pathname.startsWith(x.path))?.name || 'home'; - // }, [pathname, tagsData]); + const currentPath = useMemo(() => { + return ( + tagsData.find((x) => pathname.startsWith(x.path))?.path || Routes.Home + ); + }, [pathname, tagsData]); + + const isHome = Routes.Home === currentPath; const handleChange = (path: SegmentedValue) => { - // navigate(path as string); - setCurrentPath(path as string); + navigate(path as Routes); + // setCurrentPath(path as Routes); }; const handleLogoClick = useCallback(() => { - navigate('/'); + navigate(Routes.Home); }, [navigate]); return ( @@ -81,7 +90,22 @@ export function Header() {
-
+
+ +
- + V 0.13.0
; +} diff --git a/web/src/pages/file-manager/connect-to-knowledge-modal/index.tsx b/web/src/pages/file-manager/connect-to-knowledge-modal/index.tsx index c06274a3..d32df359 100644 --- a/web/src/pages/file-manager/connect-to-knowledge-modal/index.tsx +++ b/web/src/pages/file-manager/connect-to-knowledge-modal/index.tsx @@ -1,5 +1,5 @@ import { useTranslate } from '@/hooks/common-hooks'; -import { useNextFetchKnowledgeList } from '@/hooks/knowledge-hooks'; +import { useFetchKnowledgeList } from '@/hooks/knowledge-hooks'; import { IModalProps } from '@/interfaces/common'; import { filterOptionsByInput } from '@/utils/common-util'; import { Form, Modal, Select } from 'antd'; @@ -13,7 +13,7 @@ const ConnectToKnowledgeModal = ({ loading, }: IModalProps & { initialValue: string[] }) => { const [form] = Form.useForm(); - const { list } = useNextFetchKnowledgeList(); + const { list } = useFetchKnowledgeList(); const { t } = useTranslate('fileManager'); const options = list?.map((item) => ({ diff --git a/web/src/pages/flow/canvas/node/retrieval-node.tsx b/web/src/pages/flow/canvas/node/retrieval-node.tsx index 8fce5391..d5d7f3db 100644 --- a/web/src/pages/flow/canvas/node/retrieval-node.tsx +++ b/web/src/pages/flow/canvas/node/retrieval-node.tsx @@ -1,4 +1,4 @@ -import { useNextFetchKnowledgeList } from '@/hooks/knowledge-hooks'; +import { useFetchKnowledgeList } from '@/hooks/knowledge-hooks'; import { UserOutlined } from '@ant-design/icons'; import { Avatar, Flex } from 'antd'; import classNames from 'classnames'; @@ -17,7 +17,7 @@ export function RetrievalNode({ selected, }: NodeProps) { const knowledgeBaseIds: string[] = get(data, 'form.kb_ids', []); - const { list: knowledgeList } = useNextFetchKnowledgeList(true); + const { list: knowledgeList } = useFetchKnowledgeList(true); const knowledgeBases = useMemo(() => { return knowledgeBaseIds.map((x) => { const item = knowledgeList.find((y) => x === y.id); diff --git a/web/src/pages/home/datasets.tsx b/web/src/pages/home/datasets.tsx index c23cbfa5..4d63d0a2 100644 --- a/web/src/pages/home/datasets.tsx +++ b/web/src/pages/home/datasets.tsx @@ -1,82 +1,78 @@ +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; import { Button } from '@/components/ui/button'; import { Card, CardContent } from '@/components/ui/card'; -import { ChevronRight, MoreHorizontal } from 'lucide-react'; - -const datasets = [ - { - id: 1, - title: 'Legal knowledge base', - files: '1,242 files', - size: '152 MB', - created: '12.02.2024', - image: 'https://github.com/shadcn.png', - }, - { - id: 2, - title: 'HR knowledge base', - files: '1,242 files', - size: '152 MB', - created: '12.02.2024', - image: 'https://github.com/shadcn.png', - }, - { - id: 3, - title: 'IT knowledge base', - files: '1,242 files', - size: '152 MB', - created: '12.02.2024', - image: 'https://github.com/shadcn.png', - }, - { - id: 4, - title: 'Legal knowledge base', - files: '1,242 files', - size: '152 MB', - created: '12.02.2024', - image: 'https://github.com/shadcn.png', - }, -]; +import { CardSkeleton } from '@/components/ui/skeleton'; +import { useFetchKnowledgeList } from '@/hooks/knowledge-hooks'; +import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks'; +import { formatDate } from '@/utils/date'; +import { ChevronRight, Trash2 } from 'lucide-react'; export function Datasets() { + const { navigateToDatasetList, navigateToDataset } = useNavigatePage(); + const { list, loading } = useFetchKnowledgeList(); + return (

Datasets

- {datasets.map((dataset) => ( - - -
-
- -
-
-
-

- {dataset.title} -

-

- {dataset.files} | {dataset.size} -

-

- Created {dataset.created} -

-
- -
- - - ))} - +
+
+
+

+ {dataset.name} +

+
+ {dataset.doc_num} files +
+

+ Created {formatDate(dataset.update_time)} +

+
+ +
+
+
+ ))} +
+ )} +
diff --git a/web/src/pages/next-chat/index.tsx b/web/src/pages/next-chat/index.tsx new file mode 100644 index 00000000..1342c631 --- /dev/null +++ b/web/src/pages/next-chat/index.tsx @@ -0,0 +1,3 @@ +export default function Chat() { + return
chat
; +} diff --git a/web/src/pages/next-search/index.tsx b/web/src/pages/next-search/index.tsx new file mode 100644 index 00000000..0d4f3a3f --- /dev/null +++ b/web/src/pages/next-search/index.tsx @@ -0,0 +1,3 @@ +export default function Search() { + return
Search
; +} diff --git a/web/src/pages/search/index.tsx b/web/src/pages/search/index.tsx index f280d33b..aa5f45de 100644 --- a/web/src/pages/search/index.tsx +++ b/web/src/pages/search/index.tsx @@ -6,7 +6,7 @@ import { useClickDrawer } from '@/components/pdf-drawer/hooks'; import RetrievalDocuments from '@/components/retrieval-documents'; import SvgIcon from '@/components/svg-icon'; import { - useNextFetchKnowledgeList, + useFetchKnowledgeList, useSelectTestingResult, } from '@/hooks/knowledge-hooks'; import { useGetPaginationWithRouter } from '@/hooks/logic-hooks'; @@ -45,7 +45,7 @@ const SearchPage = () => { const { t } = useTranslation(); const [checkedList, setCheckedList] = useState([]); const { chunks, total } = useSelectTestingResult(); - const { list: knowledgeList } = useNextFetchKnowledgeList(); + const { list: knowledgeList } = useFetchKnowledgeList(); const checkedWithoutEmbeddingIdList = useMemo(() => { return checkedList.filter((x) => knowledgeList.some((y) => y.id === x)); }, [checkedList, knowledgeList]); diff --git a/web/src/pages/search/sidebar.tsx b/web/src/pages/search/sidebar.tsx index 4641460e..052f4844 100644 --- a/web/src/pages/search/sidebar.tsx +++ b/web/src/pages/search/sidebar.tsx @@ -1,4 +1,4 @@ -import { useNextFetchKnowledgeList } from '@/hooks/knowledge-hooks'; +import { useFetchKnowledgeList } from '@/hooks/knowledge-hooks'; import { UserOutlined } from '@ant-design/icons'; import type { TreeDataNode, TreeProps } from 'antd'; import { Avatar, Layout, Space, Spin, Tree, Typography } from 'antd'; @@ -27,7 +27,7 @@ const SearchSidebar = ({ checkedList, setCheckedList, }: IProps) => { - const { list, loading } = useNextFetchKnowledgeList(); + const { list, loading } = useFetchKnowledgeList(); const groupedList = useMemo(() => { return list.reduce((pre: TreeDataNode[], cur) => { diff --git a/web/src/routes.ts b/web/src/routes.ts index 6a1fdddf..60c527ae 100644 --- a/web/src/routes.ts +++ b/web/src/routes.ts @@ -1,3 +1,14 @@ +export enum Routes { + Login = '/login', + Home = '/home', + Datasets = '/datasets', + DatasetBase = '/dataset', + Dataset = `${Routes.DatasetBase}${Routes.DatasetBase}`, + Agent = '/agent', + Search = '/next-search', + Chat = '/next-chat', +} + const routes = [ { path: '/login', @@ -127,48 +138,81 @@ const routes = [ layout: false, }, { - path: '/home', + path: Routes.Home, layout: false, component: '@/layouts/next', routes: [ { - path: '/home', - component: '@/pages/home', + path: Routes.Home, + component: `@/pages${Routes.Home}`, }, ], }, { - path: '/datasets', + path: Routes.Datasets, layout: false, component: '@/layouts/next', routes: [ { - path: '/datasets', - component: '@/pages/datasets', + path: Routes.Datasets, + component: `@/pages${Routes.Datasets}`, }, ], }, { - path: '/dataset', + path: Routes.Chat, layout: false, component: '@/layouts/next', routes: [ - { path: '/dataset', redirect: '/dataset/dataset' }, { - path: '/dataset', - component: '@/pages/dataset', + path: Routes.Chat, + component: `@/pages${Routes.Chat}`, + }, + ], + }, + { + path: Routes.Search, + layout: false, + component: '@/layouts/next', + routes: [ + { + path: Routes.Search, + component: `@/pages${Routes.Search}`, + }, + ], + }, + { + path: Routes.Agent, + layout: false, + component: '@/layouts/next', + routes: [ + { + path: Routes.Agent, + component: `@/pages${Routes.Agent}`, + }, + ], + }, + { + path: Routes.DatasetBase, + layout: false, + component: '@/layouts/next', + routes: [ + { path: Routes.DatasetBase, redirect: Routes.Dataset }, + { + path: Routes.DatasetBase, + component: `@/pages${Routes.DatasetBase}`, routes: [ { - path: '/dataset/dataset', - component: '@/pages/dataset/dataset', + path: Routes.Dataset, + component: `@/pages${Routes.Dataset}`, }, { - path: '/dataset/configuration', - component: '@/pages/dataset/settings', + path: `${Routes.DatasetBase}/configuration`, + component: `@/pages${Routes.DatasetBase}/settings`, }, { - path: '/dataset/testing', - component: '@/pages/dataset/testing', + path: `${Routes.DatasetBase}/testing`, + component: `@/pages${Routes.DatasetBase}/testing`, }, ], },