- #151: chevauchement des boutons dans la barre supérieure pendant une conversation agent - #158: popup de reprise de conversation intempestive (ajout cellule / changement layout / projet) - #159: pastille d'activité de projet
This commit is contained in:
@ -12,6 +12,7 @@
|
||||
|
||||
import type { TabItem } from "@/shared";
|
||||
import { Button, Tabs, cn } from "@/shared";
|
||||
import type { ProjectActivityStatus } from "./projectActivity";
|
||||
|
||||
export interface ProjectTabsProps {
|
||||
items: TabItem[];
|
||||
@ -22,6 +23,8 @@ export interface ProjectTabsProps {
|
||||
projectsPanelOpen: boolean;
|
||||
/** Open the Projects panel (floating) — create/switch project. */
|
||||
onOpenProjectsPanel: () => void;
|
||||
/** Per-project custom CLI activity, keyed by project id. Missing = none. */
|
||||
activityByProjectId?: Record<string, ProjectActivityStatus>;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
@ -32,8 +35,19 @@ export function ProjectTabs({
|
||||
onClose,
|
||||
projectsPanelOpen,
|
||||
onOpenProjectsPanel,
|
||||
activityByProjectId = {},
|
||||
className,
|
||||
}: ProjectTabsProps) {
|
||||
const tabs = items.map((item) => ({
|
||||
...item,
|
||||
leading: (
|
||||
<ProjectActivityDot
|
||||
status={activityByProjectId[item.id] ?? "none"}
|
||||
label={item.label}
|
||||
/>
|
||||
),
|
||||
}));
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
@ -45,7 +59,7 @@ export function ProjectTabs({
|
||||
<p className="px-2 text-sm text-muted">No open tabs.</p>
|
||||
) : (
|
||||
<Tabs
|
||||
items={items}
|
||||
items={tabs}
|
||||
value={activeTabId}
|
||||
onSelect={onSelect}
|
||||
onClose={onClose}
|
||||
@ -72,3 +86,32 @@ export function ProjectTabs({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ProjectActivityDot({
|
||||
status,
|
||||
label,
|
||||
}: {
|
||||
status: ProjectActivityStatus;
|
||||
label: string;
|
||||
}) {
|
||||
const title =
|
||||
status === "busy"
|
||||
? `${label} : activité en cours`
|
||||
: status === "idle"
|
||||
? `${label} : conversation ouverte`
|
||||
: `${label} : aucune conversation active`;
|
||||
return (
|
||||
<span
|
||||
data-testid={`project-activity-${label}`}
|
||||
aria-hidden="true"
|
||||
title={title}
|
||||
className={cn(
|
||||
"h-2.5 w-2.5 shrink-0 rounded-full border",
|
||||
status === "busy" &&
|
||||
"animate-pulse border-warning bg-warning shadow-[0_0_0_2px_rgba(212,155,58,0.16)]",
|
||||
status === "idle" && "border-success bg-success",
|
||||
status === "none" && "border-border-strong bg-muted",
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user