fix(site): refactor agents sidebar timestamp/action cell (#22595)

This commit is contained in:
Danielle Maywood
2026-03-04 11:36:54 +00:00
committed by GitHub
parent cfcb81fb0f
commit a0b3a32cd3
2 changed files with 87 additions and 49 deletions
@@ -30,14 +30,16 @@ const defaultModelConfigs: TypesGen.ChatModelConfig[] = [
},
];
const oneWeekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
const buildChat = (overrides: Partial<Chat> = {}): Chat => ({
id: "chat-default",
owner_id: "owner-1",
title: "Agent",
status: "completed",
last_model_config_id: defaultModelConfigs[0].id,
created_at: "2026-02-18T00:00:00.000Z",
updated_at: "2026-02-18T00:00:00.000Z",
created_at: oneWeekAgo,
updated_at: oneWeekAgo,
archived: false,
last_error: null,
...overrides,
@@ -419,3 +421,41 @@ export const NoArchivedSection: Story = {
expect(canvas.queryByText(/^Archived \(/)).not.toBeInTheDocument();
},
};
export const ArchivingShowsSpinnerOnly: Story = {
args: {
chats: [
buildChat({
id: "archiving-chat",
title: "Chat being archived",
updated_at: todayTimestamp,
}),
],
isArchiving: true,
archivingChatId: "archiving-chat",
},
parameters: {
reactRouter: reactRouterParameters({
location: { path: "/agents" },
routing: agentsRouting,
}),
},
};
export const DefaultShowsTimestampHidesMenu: Story = {
args: {
chats: [
buildChat({
id: "default-chat",
title: "Default state agent",
updated_at: todayTimestamp,
}),
],
},
parameters: {
reactRouter: reactRouterParameters({
location: { path: "/agents" },
routing: agentsRouting,
}),
},
};
+45 -47
View File
@@ -450,52 +450,50 @@ const ChatTreeNode = memo<ChatTreeNodeProps>(({ chat, isChildNode }) => {
</>
)}
</NavLink>
<div className="relative mr-1 mt-1 h-6 w-7 shrink-0 text-right">
<span className="absolute inset-0 flex items-center justify-end text-xs text-content-secondary/50 tabular-nums transition-opacity [@media(hover:hover)]:group-hover:opacity-0">
{shortRelativeTime(chat.updated_at)}
</span>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
variant="subtle"
className={cn(
"absolute inset-0 h-6 w-7 justify-end rounded-none px-0 text-content-secondary opacity-0 transition-opacity hover:text-content-primary [@media(hover:hover)]:group-hover:opacity-100",
isArchivingThisChat && "opacity-100",
)}
aria-label={`Open actions for ${chat.title}`}
>
{isArchivingThisChat ? (
<Loader2Icon className="h-3.5 w-3.5 animate-spin" />
) : (
<EllipsisIcon className="h-3.5 w-3.5" />
)}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem
className="text-content-destructive focus:text-content-destructive"
disabled={isArchiving}
onSelect={() => onArchiveAgent(chat.id)}
>
<ArchiveIcon className="h-3.5 w-3.5" />
Archive agent
</DropdownMenuItem>
{workspaceId && (
<DropdownMenuItem
className="text-content-destructive focus:text-content-destructive"
disabled={isArchiving}
onSelect={() =>
onArchiveAndDeleteWorkspace(chat.id, workspaceId)
}
>
{" "}
<Trash2Icon className="h-3.5 w-3.5" />
Archive & delete workspace
</DropdownMenuItem>
)}
</DropdownMenuContent>{" "}
</DropdownMenu>
<div className="mr-1 mt-1 flex h-6 w-7 shrink-0 items-center justify-end">
{isArchivingThisChat ? (
<Loader2Icon className="h-3.5 w-3.5 animate-spin text-content-secondary" />
) : (
<>
<span className="flex items-center justify-end text-xs text-content-secondary/50 tabular-nums [@media(hover:hover)]:group-hover:hidden group-has-[[data-state=open]]:hidden">
{shortRelativeTime(chat.updated_at)}
</span>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="icon"
variant="subtle"
className="hidden h-6 w-7 min-w-0 justify-end rounded-none px-0 text-content-secondary hover:text-content-primary [@media(hover:hover)]:group-hover:inline-flex data-[state=open]:inline-flex"
aria-label={`Open actions for ${chat.title}`}
>
<EllipsisIcon className="h-3.5 w-3.5" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem
className="text-content-destructive focus:text-content-destructive"
disabled={isArchiving}
onSelect={() => onArchiveAgent(chat.id)}
>
<ArchiveIcon className="h-3.5 w-3.5" />
Archive agent
</DropdownMenuItem>
{workspaceId && (
<DropdownMenuItem
className="text-content-destructive focus:text-content-destructive"
disabled={isArchiving}
onSelect={() =>
onArchiveAndDeleteWorkspace(chat.id, workspaceId)
}
>
<Trash2Icon className="h-3.5 w-3.5" />
Archive & delete workspace
</DropdownMenuItem>
)}
</DropdownMenuContent>
</DropdownMenu>
</>
)}
</div>
</div>
@@ -778,7 +776,7 @@ export const AgentsSidebar: FC<AgentsSidebarProps> = (props) => {
</div>
</CollapsibleContent>
</Collapsible>
)}{" "}
)}
</div>
)}
</ChatTreeContext.Provider>