Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 88 additions & 78 deletions src/components/cloud-agent-next/ChatSidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
'use client';

import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Button } from '@/components/Button';
import {
Plus,
SquarePen,
Search,
SlidersHorizontal,
MoreHorizontal,
Expand All @@ -12,6 +11,7 @@ import {
X,
Pencil,
} from 'lucide-react';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { TimeAgo } from '@/components/shared/TimeAgo';
import { usePathname, useRouter } from 'next/navigation';
import { isToday, isYesterday, startOfDay, differenceInCalendarDays, format } from 'date-fns';
Expand Down Expand Up @@ -358,83 +358,93 @@ export function ChatSidebar({
<div className="flex h-full flex-col">
{/* Header */}
<div className={cn('flex items-center gap-2 border-b px-3 py-2.5', isInSheet && 'pt-14')}>
<Button onClick={handleNewSession} className="flex-1" variant="primary" size="sm">
<Plus className="mr-2 h-4 w-4" />
New Session
</Button>
<button
onClick={toggleSearch}
className={cn(
'hover:bg-accent rounded-md p-1.5 transition-colors',
showSearch && 'bg-accent'
)}
>
<Search className="text-muted-foreground h-4 w-4" />
</button>
{(onPlatformChange || onProjectChange) && (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button
className={cn(
'hover:bg-accent rounded-md p-1.5 transition-colors',
hasActiveFilter && 'bg-accent'
<Tooltip>
<TooltipTrigger asChild>
<button
onClick={handleNewSession}
className="hover:bg-accent rounded-md p-1.5 transition-colors"
aria-label="New session"
>
<SquarePen className="text-muted-foreground h-4 w-4" />
</button>
</TooltipTrigger>
<TooltipContent side="bottom">New session</TooltipContent>
</Tooltip>
<div className="ml-auto flex items-center gap-1">
<button
onClick={toggleSearch}
className={cn(
'hover:bg-accent rounded-md p-1.5 transition-colors',
showSearch && 'bg-accent'
)}
>
<Search className="text-muted-foreground h-4 w-4" />
</button>
{(onPlatformChange || onProjectChange) && (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button
className={cn(
'hover:bg-accent rounded-md p-1.5 transition-colors',
hasActiveFilter && 'bg-accent'
)}
>
<SlidersHorizontal className="text-muted-foreground h-4 w-4" />
</button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{onProjectChange && recentProjects.length > 0 && (
<>
<DropdownMenuLabel>Project</DropdownMenuLabel>
<DropdownMenuItem onClick={() => onProjectChange(undefined)}>
<Check
className={cn('mr-2 h-4 w-4', !projectFilter ? 'opacity-100' : 'opacity-0')}
/>
All projects
</DropdownMenuItem>
{recentProjects.map(project => {
const isActive = projectFilter === project.gitUrl;
return (
<DropdownMenuItem
key={project.gitUrl}
onClick={() => onProjectChange(project.gitUrl)}
>
<Check
className={cn('mr-2 h-4 w-4', isActive ? 'opacity-100' : 'opacity-0')}
/>
{project.displayName}
</DropdownMenuItem>
);
})}
</>
)}
>
<SlidersHorizontal className="text-muted-foreground h-4 w-4" />
</button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{onProjectChange && recentProjects.length > 0 && (
<>
<DropdownMenuLabel>Project</DropdownMenuLabel>
<DropdownMenuItem onClick={() => onProjectChange(undefined)}>
<Check
className={cn('mr-2 h-4 w-4', !projectFilter ? 'opacity-100' : 'opacity-0')}
/>
All projects
</DropdownMenuItem>
{recentProjects.map(project => {
const isActive = projectFilter === project.gitUrl;
return (
<DropdownMenuItem
key={project.gitUrl}
onClick={() => onProjectChange(project.gitUrl)}
>
<Check
className={cn('mr-2 h-4 w-4', isActive ? 'opacity-100' : 'opacity-0')}
/>
{project.displayName}
</DropdownMenuItem>
);
})}
</>
)}
{onPlatformChange && (
<>
{onProjectChange && recentProjects.length > 0 && <DropdownMenuSeparator />}
<DropdownMenuLabel>Platform</DropdownMenuLabel>
{PLATFORM_FILTERS.map(p => {
const isFilterActive = p === 'all' ? !platformFilter : platformFilter === p;
return (
<DropdownMenuItem
key={p}
onClick={() => onPlatformChange(p === 'all' ? undefined : p)}
>
<Check
className={cn(
'mr-2 h-4 w-4',
isFilterActive ? 'opacity-100' : 'opacity-0'
)}
/>
{platformFilterLabel(p)}
</DropdownMenuItem>
);
})}
</>
)}
</DropdownMenuContent>
</DropdownMenu>
)}
{onPlatformChange && (
<>
{onProjectChange && recentProjects.length > 0 && <DropdownMenuSeparator />}
<DropdownMenuLabel>Platform</DropdownMenuLabel>
{PLATFORM_FILTERS.map(p => {
const isFilterActive = p === 'all' ? !platformFilter : platformFilter === p;
return (
<DropdownMenuItem
key={p}
onClick={() => onPlatformChange(p === 'all' ? undefined : p)}
>
<Check
className={cn(
'mr-2 h-4 w-4',
isFilterActive ? 'opacity-100' : 'opacity-0'
)}
/>
{platformFilterLabel(p)}
</DropdownMenuItem>
);
})}
</>
)}
</DropdownMenuContent>
</DropdownMenu>
)}
</div>
</div>

{/* Collapsible search */}
Expand Down
Loading