Feat: Add Sessions component #3221 (#4865)

### What problem does this PR solve?

Feat: Add Sessions component #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2025-02-11 13:11:15 +08:00 committed by GitHub
parent 0d3ed37b48
commit f34b913bd8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 130 additions and 9 deletions

View File

@ -0,0 +1,26 @@
import { ArrowLeft } from 'lucide-react';
import { PropsWithChildren, ReactNode } from 'react';
import { Button } from './ui/button';
interface IPageHeaderProps extends PropsWithChildren {
back(): void;
title: ReactNode;
}
export function PageHeader({ back, title, children }: IPageHeaderProps) {
return (
<header className="flex justify-between items-center border-b pr-9">
<div className="flex items-center ">
<div className="flex items-center border-r p-1.5">
<Button variant="ghost" size="icon" onClick={back}>
<ArrowLeft className="w-5 h-5" />
</Button>
</div>
<div className="p-4">
<h1 className="text-2xl font-semibold tracking-tight">{title}</h1>
</div>
</div>
{children}
</header>
);
}

View File

@ -21,10 +21,20 @@ export const useNavigatePage = () => {
navigate(Routes.ProfileSetting); navigate(Routes.ProfileSetting);
}, [navigate]); }, [navigate]);
const navigateToChatList = useCallback(() => {
navigate(Routes.Chats);
}, [navigate]);
const navigateToChat = useCallback(() => {
navigate(Routes.Chat);
}, [navigate]);
return { return {
navigateToDatasetList, navigateToDatasetList,
navigateToDataset, navigateToDataset,
navigateToHome, navigateToHome,
navigateToProfile, navigateToProfile,
navigateToChatList,
navigateToChat,
}; };
}; };

View File

@ -31,7 +31,7 @@ export function Header() {
const tagsData = useMemo( const tagsData = useMemo(
() => [ () => [
{ path: Routes.Datasets, name: t('knowledgeBase'), icon: Library }, { path: Routes.Datasets, name: t('knowledgeBase'), icon: Library },
{ path: Routes.Chat, name: t('chat'), icon: MessageSquareText }, { path: Routes.Chats, name: t('chat'), icon: MessageSquareText },
{ path: Routes.Search, name: t('search'), icon: Search }, { path: Routes.Search, name: t('search'), icon: Search },
{ path: Routes.Agent, name: t('flow'), icon: Cpu }, { path: Routes.Agent, name: t('flow'), icon: Cpu },
{ path: Routes.Files, name: t('fileManager'), icon: File }, { path: Routes.Files, name: t('fileManager'), icon: File },

View File

@ -1,6 +1,7 @@
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card'; import { Card, CardContent } from '@/components/ui/card';
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
import { IDialog } from '@/interfaces/database/chat'; import { IDialog } from '@/interfaces/database/chat';
import { formatPureDate } from '@/utils/date'; import { formatPureDate } from '@/utils/date';
import { ChevronRight, Trash2 } from 'lucide-react'; import { ChevronRight, Trash2 } from 'lucide-react';
@ -10,6 +11,8 @@ interface IProps {
} }
export function ChatCard({ data }: IProps) { export function ChatCard({ data }: IProps) {
const { navigateToChat } = useNavigatePage();
return ( return (
<Card className="bg-colors-background-inverse-weak border-colors-outline-neutral-standard"> <Card className="bg-colors-background-inverse-weak border-colors-outline-neutral-standard">
<CardContent className="p-4"> <CardContent className="p-4">
@ -36,7 +39,7 @@ export function ChatCard({ data }: IProps) {
</p> </p>
</div> </div>
<div className="space-x-2"> <div className="space-x-2">
<Button variant="icon" size="icon"> <Button variant="icon" size="icon" onClick={navigateToChat}>
<ChevronRight className="h-6 w-6" /> <ChevronRight className="h-6 w-6" />
</Button> </Button>
<Button variant="icon" size="icon"> <Button variant="icon" size="icon">

View File

@ -0,0 +1,3 @@
export function AppSettings() {
return <section className="p-6 w-[400px] max-w-[20%]">app-settings</section>;
}

View File

@ -0,0 +1,3 @@
export function ChatBox() {
return <section className="border-x flex-1">ChatBox</section>;
}

View File

@ -0,0 +1,31 @@
import { PageHeader } from '@/components/page-header';
import { Button } from '@/components/ui/button';
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
import { EllipsisVertical } from 'lucide-react';
import { AppSettings } from './app-settings';
import { ChatBox } from './chat-box';
import { Sessions } from './sessions';
export default function Chat() {
const { navigateToChatList } = useNavigatePage();
return (
<section className="h-full flex flex-col">
<PageHeader back={navigateToChatList} title="Chat app 01">
<div className="flex items-center gap-2">
<Button variant={'icon'} size={'icon'}>
<EllipsisVertical />
</Button>
<Button variant={'tertiary'} size={'sm'}>
Publish
</Button>
</div>
</PageHeader>
<div className="flex flex-1">
<Sessions></Sessions>
<ChatBox></ChatBox>
<AppSettings></AppSettings>
</div>
</section>
);
}

View File

@ -0,0 +1,38 @@
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { EllipsisVertical, Plus } from 'lucide-react';
function SessionCard() {
return (
<Card className="bg-colors-background-inverse-weak border-colors-outline-neutral-standard">
<CardContent className="px-3 py-2 flex justify-between items-center">
xxx
<Button variant={'icon'} size={'icon'}>
<EllipsisVertical />
</Button>
</CardContent>
</Card>
);
}
export function Sessions() {
const sessionList = new Array(10).fill(1);
return (
<section className="p-6 w-[400px] max-w-[20%]">
<div className="flex justify-between items-center mb-4">
<span className="text-colors-text-neutral-strong text-2xl font-bold">
Sessions
</span>
<Button variant={'icon'} size={'icon'}>
<Plus></Plus>
</Button>
</div>
<div className="space-y-4">
{sessionList.map((x) => (
<SessionCard key={x.id}></SessionCard>
))}
</div>
</section>
);
}

View File

@ -1,6 +1,5 @@
import { Button } from '@/components/ui/button'; import { PageHeader } from '@/components/page-header';
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks'; import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
import { ArrowLeft } from 'lucide-react';
import { Outlet } from 'umi'; import { Outlet } from 'umi';
import { SideBar } from './sidebar'; import { SideBar } from './sidebar';
@ -9,7 +8,7 @@ export default function ProfileSetting() {
return ( return (
<div className="flex flex-col w-full h-screen bg-background text-foreground"> <div className="flex flex-col w-full h-screen bg-background text-foreground">
<header className="flex items-center border-b"> {/* <header className="flex items-center border-b">
<div className="flex items-center border-r p-1.5"> <div className="flex items-center border-r p-1.5">
<Button variant="ghost" size="icon" onClick={navigateToHome}> <Button variant="ghost" size="icon" onClick={navigateToHome}>
<ArrowLeft className="w-5 h-5" /> <ArrowLeft className="w-5 h-5" />
@ -20,7 +19,9 @@ export default function ProfileSetting() {
Profile & settings Profile & settings
</h1> </h1>
</div> </div>
</header> </header> */}
<PageHeader title="Profile & settings" back={navigateToHome}></PageHeader>
<div className="flex flex-1 bg-muted/50"> <div className="flex flex-1 bg-muted/50">
<SideBar></SideBar> <SideBar></SideBar>

View File

@ -6,6 +6,7 @@ export enum Routes {
Dataset = `${Routes.DatasetBase}${Routes.DatasetBase}`, Dataset = `${Routes.DatasetBase}${Routes.DatasetBase}`,
Agent = '/agent', Agent = '/agent',
Search = '/next-search', Search = '/next-search',
Chats = '/next-chats',
Chat = '/next-chat', Chat = '/next-chat',
Files = '/files', Files = '/files',
ProfileSetting = '/profile-setting', ProfileSetting = '/profile-setting',
@ -162,16 +163,21 @@ const routes = [
], ],
}, },
{ {
path: Routes.Chat, path: Routes.Chats,
layout: false, layout: false,
component: '@/layouts/next', component: '@/layouts/next',
routes: [ routes: [
{ {
path: Routes.Chat, path: Routes.Chats,
component: `@/pages${Routes.Chat}`, component: `@/pages${Routes.Chats}`,
}, },
], ],
}, },
{
path: Routes.Chat,
layout: false,
component: `@/pages${Routes.Chats}/chat`,
},
{ {
path: Routes.Search, path: Routes.Search,
layout: false, layout: false,