diff --git a/web/src/constants/knowledge.ts b/web/src/constants/knowledge.ts
index fe82e5e59..2bcf19a19 100644
--- a/web/src/constants/knowledge.ts
+++ b/web/src/constants/knowledge.ts
@@ -4,6 +4,8 @@ export enum KnowledgeRouteKey {
Configuration = 'configuration',
}
+export const DatasetBaseKey = 'dataset';
+
export enum RunningStatus {
UNSTART = '0', // need to run
RUNNING = '1', // need to cancel
diff --git a/web/src/layouts/next-header.tsx b/web/src/layouts/next-header.tsx
new file mode 100644
index 000000000..fd4d35a5d
--- /dev/null
+++ b/web/src/layouts/next-header.tsx
@@ -0,0 +1,113 @@
+import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
+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 { useNavigateWithFromState } from '@/hooks/route-hook';
+import {
+ ChevronDown,
+ Cpu,
+ Github,
+ Library,
+ MessageSquareText,
+ Search,
+ Star,
+ Zap,
+} from 'lucide-react';
+import { useCallback, useMemo, useState } 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 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: '/file', name: t('fileManager'), icon: FileIcon },
+ ],
+ [t],
+ );
+
+ const options = useMemo(() => {
+ return tagsData.map((tag) => {
+ const HeaderIcon = tag.icon;
+
+ return {
+ label: (
+
+
+ {tag.name}
+
+ ),
+ value: tag.path,
+ };
+ });
+ }, [tagsData]);
+
+ // const currentPath = useMemo(() => {
+ // return tagsData.find((x) => pathname.startsWith(x.path))?.name || 'home';
+ // }, [pathname, tagsData]);
+
+ const handleChange = (path: SegmentedValue) => {
+ // navigate(path as string);
+ setCurrentPath(path as string);
+ };
+
+ const handleLogoClick = useCallback(() => {
+ navigate('/');
+ }, [navigate]);
+
+ return (
+
+
+

+
+
+
+
+
+
+
+ V 0.13.0
+
+
+
+
+
+ CN
+
+ yifanwu92@gmail.com
+
+
+
+
+ );
+}
diff --git a/web/src/layouts/next.tsx b/web/src/layouts/next.tsx
new file mode 100644
index 000000000..a4fbef17d
--- /dev/null
+++ b/web/src/layouts/next.tsx
@@ -0,0 +1,11 @@
+import { Outlet } from 'umi';
+import { Header } from './next-header';
+
+export default function NextLayout() {
+ return (
+
+ );
+}
diff --git a/web/src/pages/dataset/dataset/index.tsx b/web/src/pages/dataset/dataset/index.tsx
new file mode 100644
index 000000000..914ef81d3
--- /dev/null
+++ b/web/src/pages/dataset/dataset/index.tsx
@@ -0,0 +1,3 @@
+export default function Dataset() {
+ return Outset
;
+}
diff --git a/web/src/pages/dataset/index.tsx b/web/src/pages/dataset/index.tsx
new file mode 100644
index 000000000..bd4ab0cc9
--- /dev/null
+++ b/web/src/pages/dataset/index.tsx
@@ -0,0 +1,13 @@
+import { Outlet } from 'umi';
+import { SideBar } from './sidebar';
+
+export default function DatasetWrapper() {
+ return (
+
+ );
+}
diff --git a/web/src/pages/dataset/settings/index.tsx b/web/src/pages/dataset/settings/index.tsx
new file mode 100644
index 000000000..26c27a1ec
--- /dev/null
+++ b/web/src/pages/dataset/settings/index.tsx
@@ -0,0 +1,3 @@
+export default function DatasetSettings() {
+ return DatasetSettings
;
+}
diff --git a/web/src/pages/dataset/sidebar/hooks.tsx b/web/src/pages/dataset/sidebar/hooks.tsx
new file mode 100644
index 000000000..4f90e1916
--- /dev/null
+++ b/web/src/pages/dataset/sidebar/hooks.tsx
@@ -0,0 +1,16 @@
+import { DatasetBaseKey, KnowledgeRouteKey } from '@/constants/knowledge';
+import { useCallback } from 'react';
+import { useNavigate } from 'umi';
+
+export const useHandleMenuClick = () => {
+ const navigate = useNavigate();
+
+ const handleMenuClick = useCallback(
+ (key: KnowledgeRouteKey) => () => {
+ navigate(`/${DatasetBaseKey}/${key}`);
+ },
+ [navigate],
+ );
+
+ return { handleMenuClick };
+};
diff --git a/web/src/pages/dataset/sidebar/index.tsx b/web/src/pages/dataset/sidebar/index.tsx
new file mode 100644
index 000000000..2fb76f972
--- /dev/null
+++ b/web/src/pages/dataset/sidebar/index.tsx
@@ -0,0 +1,66 @@
+import { Button } from '@/components/ui/button';
+import { KnowledgeRouteKey } from '@/constants/knowledge';
+import { useSecondPathName } from '@/hooks/route-hook';
+import { cn } from '@/lib/utils';
+import { Banknote, LayoutGrid, User } from 'lucide-react';
+import { useHandleMenuClick } from './hooks';
+
+const items = [
+ { icon: User, label: 'Dataset', key: KnowledgeRouteKey.Dataset },
+ {
+ icon: LayoutGrid,
+ label: 'Retrieval testing',
+ key: KnowledgeRouteKey.Testing,
+ },
+ { icon: Banknote, label: 'Settings', key: KnowledgeRouteKey.Configuration },
+];
+
+const dataset = {
+ id: 1,
+ title: 'Legal knowledge base',
+ files: '1,242 files',
+ size: '152 MB',
+ created: '12.02.2024',
+ image: 'https://github.com/shadcn.png',
+};
+
+export function SideBar() {
+ const pathName = useSecondPathName();
+ const { handleMenuClick } = useHandleMenuClick();
+
+ return (
+
+ );
+}
diff --git a/web/src/pages/dataset/testing/index.tsx b/web/src/pages/dataset/testing/index.tsx
new file mode 100644
index 000000000..9d89a4073
--- /dev/null
+++ b/web/src/pages/dataset/testing/index.tsx
@@ -0,0 +1,3 @@
+export default function RetrievalTesting() {
+ return Retrieval testing
;
+}
diff --git a/web/src/routes.ts b/web/src/routes.ts
index b7d68168b..ead85a006 100644
--- a/web/src/routes.ts
+++ b/web/src/routes.ts
@@ -134,7 +134,39 @@ const routes = [
{
path: '/datasets',
layout: false,
- component: '@/pages/datasets',
+ component: '@/layouts/next',
+ routes: [
+ {
+ path: '/datasets',
+ component: '@/pages/datasets',
+ },
+ ],
+ },
+ {
+ path: '/dataset',
+ layout: false,
+ component: '@/layouts/next',
+ routes: [
+ { path: '/dataset', redirect: '/dataset/dataset' },
+ {
+ path: '/dataset',
+ component: '@/pages/dataset',
+ routes: [
+ {
+ path: '/dataset/dataset',
+ component: '@/pages/dataset/dataset',
+ },
+ {
+ path: '/dataset/configuration',
+ component: '@/pages/dataset/settings',
+ },
+ {
+ path: '/dataset/testing',
+ component: '@/pages/dataset/testing',
+ },
+ ],
+ },
+ ],
},
{
path: '/profile-setting',