feat(frontend): SessionMenu kebab + NavSessions prop-driven; AppShell owns sessions query
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import { Menu } from "@base-ui/react/menu";
|
||||
import { MoreVertical } from "lucide-react";
|
||||
import type { SessionSummary } from "../api/types";
|
||||
|
||||
interface Props {
|
||||
session: SessionSummary;
|
||||
groups: string[];
|
||||
onView: () => void;
|
||||
onRename: () => void;
|
||||
onMove: (group: string) => void;
|
||||
onNewGroup: () => void;
|
||||
onArchiveToggle: () => void;
|
||||
onDelete: () => void;
|
||||
}
|
||||
|
||||
const itemCls =
|
||||
"flex w-full cursor-default select-none items-center rounded-md px-2 py-1.5 text-sm outline-none data-highlighted:bg-accent data-highlighted:text-accent-foreground";
|
||||
|
||||
export function SessionMenu({ session, groups, onView, onRename, onMove, onNewGroup, onArchiveToggle, onDelete }: Props) {
|
||||
return (
|
||||
<Menu.Root>
|
||||
<Menu.Trigger
|
||||
aria-label="Session actions"
|
||||
className="rounded-md p-1 text-muted-foreground opacity-0 transition-opacity hover:bg-accent group-hover:opacity-100 data-popup-open:opacity-100"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<MoreVertical className="size-4" />
|
||||
</Menu.Trigger>
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner side="bottom" align="end" sideOffset={4}>
|
||||
<Menu.Popup className="z-50 min-w-44 rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-none">
|
||||
<Menu.Item className={itemCls} onClick={onView}>Vista divisa</Menu.Item>
|
||||
<Menu.Item className={itemCls} onClick={onRename}>Rinomina</Menu.Item>
|
||||
<Menu.SubmenuRoot>
|
||||
<Menu.SubmenuTrigger className={itemCls}>Sposta nel gruppo ›</Menu.SubmenuTrigger>
|
||||
<Menu.Portal>
|
||||
<Menu.Positioner side="right" align="start">
|
||||
<Menu.Popup className="z-50 min-w-44 rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-none">
|
||||
{groups.filter((g) => g !== session.group).map((g) => (
|
||||
<Menu.Item key={g} className={itemCls} onClick={() => onMove(g)}>{g}</Menu.Item>
|
||||
))}
|
||||
{session.group && (
|
||||
<Menu.Item className={itemCls} onClick={() => onMove("")}>Senza gruppo</Menu.Item>
|
||||
)}
|
||||
<Menu.Item className={itemCls} onClick={onNewGroup}>Nuovo gruppo…</Menu.Item>
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
</Menu.SubmenuRoot>
|
||||
<Menu.Item className={itemCls} onClick={onArchiveToggle}>
|
||||
{session.archived ? "Ripristina" : "Archivia"}
|
||||
</Menu.Item>
|
||||
<Menu.Separator className="my-1 h-px bg-border" />
|
||||
<Menu.Item className={`${itemCls} text-destructive`} onClick={onDelete}>Elimina</Menu.Item>
|
||||
</Menu.Popup>
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
</Menu.Root>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user