Skip to content

Commit 06d2346

Browse files
authored
feat(toolkit): show conversation list on with agents list (#231)
1 parent 4db13fd commit 06d2346

File tree

6 files changed

+173
-105
lines changed

6 files changed

+173
-105
lines changed

src/interfaces/coral_web/src/components/Agents/AgentsSidePanel.tsx

Lines changed: 83 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Link from 'next/link';
44
import { IconButton } from '@/components/IconButton';
55
import { Button, Icon, IconProps, Logo, Tooltip } from '@/components/Shared';
66
import { env } from '@/env.mjs';
7+
import { useIsDesktop } from '@/hooks/breakpoint';
78
import { useSettingsStore } from '@/stores';
89
import { cn } from '@/utils';
910

@@ -18,6 +19,9 @@ export const AgentsSidePanel: React.FC<React.PropsWithChildren> = ({ children })
1819
setIsAgentsSidePanelOpen,
1920
} = useSettingsStore();
2021

22+
const isDesktop = useIsDesktop();
23+
const isMobile = !isDesktop;
24+
2125
const navigationItems: {
2226
label: string;
2327
icon: IconProps['name'];
@@ -29,78 +33,93 @@ export const AgentsSidePanel: React.FC<React.PropsWithChildren> = ({ children })
2933
];
3034

3135
return (
32-
<div
33-
className={cn(
34-
'box-content px-4 py-6',
35-
'flex flex-grow flex-col gap-y-8 rounded-lg border',
36-
'border-marble-400 bg-marble-100',
37-
'transition-[min-width,max-width]',
38-
{
39-
'min-w-12 max-w-12': !isAgentsSidePanelOpen,
40-
'min-w-64 max-w-64': isAgentsSidePanelOpen,
41-
}
42-
)}
36+
<Transition
37+
show={isAgentsSidePanelOpen || isDesktop}
38+
as="div"
39+
className={cn('absolute bottom-0 left-0 top-0 z-30 lg:static', {
40+
'right-1/4': isAgentsSidePanelOpen,
41+
})}
42+
enter="transition-all transform ease-in-out duration-500"
43+
enterFrom="-translate-x-full"
44+
enterTo="translate-x-0"
45+
leave="transition-all transform ease-in-out duration-500"
46+
leaveFrom="translate-x-0 opacity-100"
47+
leaveTo="-translate-x-full opacity-0"
4348
>
4449
<div
45-
className={cn('flex flex-shrink-0 items-center', {
46-
'justify-between gap-x-3': isAgentsSidePanelOpen,
47-
'justify-center': !isAgentsSidePanelOpen,
48-
})}
50+
className={cn(
51+
'box-content h-full px-4 py-6',
52+
'flex flex-grow flex-col gap-y-8 rounded-lg border',
53+
'border-marble-400 bg-marble-100',
54+
'transition-[min-width,max-width]',
55+
{
56+
'min-w-12 max-w-12': !isAgentsSidePanelOpen,
57+
'min-w-64 max-w-64': isAgentsSidePanelOpen,
58+
}
59+
)}
4960
>
50-
<Transition
51-
show={isAgentsSidePanelOpen}
52-
as="div"
53-
enter="transition-all transform ease-in-out duration-200"
54-
enterFrom="-translate-x-full"
55-
enterTo="translate-x-0"
61+
<div
62+
className={cn('flex flex-shrink-0 items-center', {
63+
'justify-between gap-x-3': isAgentsSidePanelOpen || isMobile,
64+
'justify-center': !isAgentsSidePanelOpen && isDesktop,
65+
})}
5666
>
57-
<Link href="/" shallow>
58-
<div className="mr-3 flex items-baseline">
59-
<Logo hasCustomLogo={env.NEXT_PUBLIC_HAS_CUSTOM_LOGO === 'true'} />
60-
</div>
61-
</Link>
62-
</Transition>
67+
<Transition
68+
show={isAgentsSidePanelOpen || isMobile}
69+
appear
70+
as="div"
71+
enter="transition-all transform ease-in-out duration-200"
72+
enterFrom="-translate-x-full"
73+
enterTo="translate-x-0"
74+
>
75+
<Link href="/" shallow>
76+
<div className="mr-3 flex items-baseline">
77+
<Logo hasCustomLogo={env.NEXT_PUBLIC_HAS_CUSTOM_LOGO === 'true'} />
78+
</div>
79+
</Link>
80+
</Transition>
6381

64-
<IconButton
65-
iconName="close-drawer"
66-
onClick={() => setIsAgentsSidePanelOpen(!isAgentsSidePanelOpen)}
67-
className={cn('transition delay-100 duration-200 ease-in-out', {
68-
'rotate-180 transform text-secondary-700': isAgentsSidePanelOpen,
69-
})}
70-
/>
71-
</div>
72-
<div className="flex-grow overflow-y-auto">{children}</div>
73-
{isAgentsSidePanelOpen ? (
74-
<div className="flex flex-shrink-0 flex-col gap-y-4">
75-
{navigationItems.map(({ label, icon, href, onClick }) => (
76-
<Button
77-
key={label}
78-
kind="secondary"
79-
className="truncate text-secondary-900"
80-
startIcon={<Icon name={icon} kind="outline" className="text-secondary-900" />}
81-
label={label}
82-
href={href}
83-
shallow
84-
onClick={onClick}
85-
/>
86-
))}
82+
<IconButton
83+
iconName="close-drawer"
84+
onClick={() => setIsAgentsSidePanelOpen(!isAgentsSidePanelOpen)}
85+
className={cn('transition delay-100 duration-200 ease-in-out', {
86+
'rotate-180 transform text-secondary-700': isAgentsSidePanelOpen || isMobile,
87+
})}
88+
/>
8789
</div>
88-
) : (
89-
<div className="flex flex-shrink-0 flex-col gap-y-4">
90-
{navigationItems.map(({ label, icon, href, onClick }) => (
91-
<Tooltip key={label} label={label} hover placement="right">
92-
<IconButton
93-
iconName={icon}
94-
iconClassName="text-secondary-900"
90+
<div className="flex-grow overflow-y-auto">{children}</div>
91+
{isAgentsSidePanelOpen || isMobile ? (
92+
<div className="flex flex-shrink-0 flex-col gap-y-4">
93+
{navigationItems.map(({ label, icon, href, onClick }) => (
94+
<Button
95+
key={label}
96+
kind="secondary"
97+
className="truncate text-secondary-900"
98+
startIcon={<Icon name={icon} kind="outline" className="text-secondary-900" />}
99+
label={label}
100+
href={href}
95101
shallow
96102
onClick={onClick}
97-
href={href}
98-
className="w-full text-secondary-900"
99103
/>
100-
</Tooltip>
101-
))}
102-
</div>
103-
)}
104-
</div>
104+
))}
105+
</div>
106+
) : (
107+
<div className="flex flex-shrink-0 flex-col gap-y-4">
108+
{navigationItems.map(({ label, icon, href, onClick }) => (
109+
<Tooltip key={label} label={label} hover placement="right">
110+
<IconButton
111+
iconName={icon}
112+
iconClassName="text-secondary-900"
113+
shallow
114+
onClick={onClick}
115+
href={href}
116+
className="w-full text-secondary-900"
117+
/>
118+
</Tooltip>
119+
))}
120+
</div>
121+
)}
122+
</div>
123+
</Transition>
105124
);
106125
};

src/interfaces/coral_web/src/components/Agents/Layout.tsx

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
import { Transition } from '@headlessui/react';
21
import { capitalize } from 'lodash';
32
import React, { Children, PropsWithChildren } from 'react';
43

54
import { AgentsSidePanel } from '@/components/Agents/AgentsSidePanel';
5+
import { MobileHeader } from '@/components/Agents/MobileHeader';
66
import { ConfigurationDrawer } from '@/components/Conversation/ConfigurationDrawer';
77
import { PageHead } from '@/components/Shared/PageHead';
8-
import { useIsDesktop } from '@/hooks/breakpoint';
9-
import { useSettingsStore } from '@/stores';
108
import { cn } from '@/utils/cn';
119

1210
export const LeftSection: React.FC<React.PropsWithChildren> = ({ children }) => <>{children}</>;
@@ -22,11 +20,6 @@ type Props = {
2220
On small devices (e.g. mobile), the left drawer and main section are stacked vertically.
2321
*/
2422
export const Layout: React.FC<Props> = ({ title = 'Chat', children }) => {
25-
const {
26-
settings: { isMobileConvListPanelOpen },
27-
} = useSettingsStore();
28-
const isDesktop = useIsDesktop();
29-
3023
let leftElement: React.ReactNode = null;
3124
let mainElement: React.ReactNode = null;
3225

@@ -47,32 +40,23 @@ export const Layout: React.FC<Props> = ({ title = 'Chat', children }) => {
4740
<>
4841
<PageHead title={capitalize(title)} />
4942
<div className="flex h-screen w-full flex-1 flex-col gap-3 bg-secondary-100 p-3">
50-
<div className={cn('relative flex h-full flex-grow flex-nowrap gap-3 overflow-hidden')}>
43+
<div
44+
className={cn(
45+
'relative flex h-full flex-grow flex-col flex-nowrap gap-3 overflow-hidden lg:flex-row'
46+
)}
47+
>
48+
<MobileHeader />
5149
<AgentsSidePanel>{leftElement}</AgentsSidePanel>
52-
<Transition
53-
as="main"
54-
show={!isMobileConvListPanelOpen || isDesktop}
55-
enterFrom="translate-x-full lg:translate-x-0"
56-
enterTo="translate-x-0"
57-
leaveFrom="translate-x-0"
58-
leaveTo="translate-x-full lg:translate-x-0"
50+
<section
5951
className={cn(
60-
'z-main-section flex flex-grow lg:min-w-0',
61-
'absolute h-full w-full lg:static lg:h-auto',
62-
'transition-transform duration-500 ease-in-out lg:transition-none'
52+
'relative flex h-full min-w-0 flex-grow flex-col',
53+
'rounded-lg border',
54+
'border-marble-400 bg-marble-100',
55+
'overflow-hidden'
6356
)}
6457
>
65-
<section
66-
className={cn(
67-
'relative flex h-full min-w-0 flex-grow flex-col',
68-
'rounded-lg border',
69-
'border-marble-400 bg-marble-100',
70-
'overflow-hidden'
71-
)}
72-
>
73-
{mainElement}
74-
</section>
75-
</Transition>
58+
{mainElement}
59+
</section>
7660
<ConfigurationDrawer />
7761
</div>
7862
</div>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Logo } from '@/components/Shared';
2+
import { useSettingsStore } from '@/stores';
3+
4+
export const MobileHeader: React.FC = () => {
5+
const {
6+
settings: { isAgentsSidePanelOpen },
7+
setIsAgentsSidePanelOpen,
8+
} = useSettingsStore();
9+
10+
const onToggleAgentsSidePanel = () => {
11+
setIsAgentsSidePanelOpen(!isAgentsSidePanelOpen);
12+
};
13+
14+
return (
15+
<header className="flex h-11 items-center justify-start rounded-lg border border-marble-400 bg-marble-200 px-4 lg:hidden">
16+
<button onClick={onToggleAgentsSidePanel}>
17+
<Logo />
18+
</button>
19+
</header>
20+
);
21+
};

src/interfaces/coral_web/src/components/Conversation/Header.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const useHeaderMenu = ({ conversationId }: { conversationId?: string }) => {
1919
const { resetConversation } = useConversationStore();
2020
const { resetCitations } = useCitationsStore();
2121

22-
const { settings, setSettings } = useSettingsStore();
22+
const { setSettings } = useSettingsStore();
2323
const { resetFileParams } = useParamsStore();
2424
const router = useRouter();
2525
const { welcomeGuideState, progressWelcomeGuideStep, finishWelcomeGuide } =
@@ -79,6 +79,7 @@ export const Header: React.FC<Props> = ({ isStreaming }) => {
7979
const { welcomeGuideState } = useWelcomeGuideState();
8080

8181
const isDesktop = useIsDesktop();
82+
const isMobile = !isDesktop;
8283
const { menuItems, handleNewChat, handleOpenSettings } = useHeaderMenu({
8384
conversationId: id,
8485
});
@@ -93,7 +94,7 @@ export const Header: React.FC<Props> = ({ isStreaming }) => {
9394
'relative flex min-w-0 flex-grow items-center gap-x-1 overflow-hidden py-4'
9495
)}
9596
>
96-
{(!isDesktop || !isConvListPanelOpen) && (
97+
{(isMobile || !isConvListPanelOpen) && (
9798
<Transition
9899
show={true}
99100
appear
@@ -104,14 +105,11 @@ export const Header: React.FC<Props> = ({ isStreaming }) => {
104105
leaveFrom="translate-x-0"
105106
leaveTo="-translate-x-full"
106107
as="div"
107-
className={cn({
108-
'lg:hidden': isConvListPanelOpen,
109-
})}
110108
>
111109
<IconButton
112110
iconName="side-panel"
113111
onClick={() => {
114-
setSettings({ isConfigDrawerOpen: false });
112+
setSettings({ isConfigDrawerOpen: false, isAgentsSidePanelOpen: false });
115113
setIsConvListPanelOpen(true);
116114
}}
117115
/>

src/interfaces/coral_web/src/components/ConversationList/ConversationListPanel.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,10 @@ export const ConversationListPanel: React.FC<Props> = ({ className }) => {
116116
<Transition.Child
117117
ref={panelRef}
118118
as="nav"
119-
enterFrom="lg:opacity-0"
120-
enterTo="lg:opacity-100"
119+
enterFrom="opacity-100 lg:opacity-0"
120+
enterTo="opacity-100"
121121
leaveFrom="lg:opacity-100"
122-
leaveTo="lg:opacity-0"
122+
leaveTo="opacity-100 lg:opacity-0"
123123
className={cn(
124124
'transition-opacity ease-in-out lg:duration-500',
125125
'flex h-full w-full flex-grow flex-col',

0 commit comments

Comments
 (0)