Context menu sidebar

This commit is contained in:
2026-02-28 14:06:00 +01:00
parent 1931f9208b
commit e71b481dbb
2 changed files with 60 additions and 51 deletions
+10 -2
View File
@@ -164,10 +164,10 @@ export default function AppSidebar({
<SidebarMenuItem> <SidebarMenuItem>
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<button className="flex w-full items-center justify-between px-2 py-1 text-sm"> <Button className="w-full" variant='ghost'>
{workspace.name} {workspace.name}
<ChevronDown className="ml-auto h-4 w-4 opacity-60" /> <ChevronDown className="ml-auto h-4 w-4 opacity-60" />
</button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent <DropdownMenuContent
@@ -236,6 +236,14 @@ export default function AppSidebar({
> >
Create workspace Create workspace
</DropdownMenuItem> </DropdownMenuItem>
<DropdownMenuItem
onSelect={() => {
localStorage.removeItem(workspace.id);
}}
variant="destructive"
>
Delete workspace
</DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
</SidebarMenuItem> </SidebarMenuItem>
+50 -49
View File
@@ -30,6 +30,13 @@ import {
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { useState } from "react"; import { useState } from "react";
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuSeparator,
ContextMenuTrigger,
} from "../ui/context-menu";
type Props = { type Props = {
node: LayoutNode; node: LayoutNode;
@@ -58,7 +65,6 @@ export default function EntitySwitch({
removeNode, removeNode,
renameGroup, renameGroup,
}: Props) { }: Props) {
const [menuOpen, setMenuOpen] = useState(false);
const [dialogOpen, setDialogOpen] = useState(false); const [dialogOpen, setDialogOpen] = useState(false);
const [dialogValue, setDialogValue] = useState(""); const [dialogValue, setDialogValue] = useState("");
const [dialogMode, setDialogMode] = useState< const [dialogMode, setDialogMode] = useState<
@@ -74,7 +80,6 @@ export default function EntitySwitch({
setDialogValue(initial); setDialogValue(initial);
} }
setDialogOpen(true); setDialogOpen(true);
setMenuOpen(false);
}; };
const handleDialogSubmit = () => { const handleDialogSubmit = () => {
@@ -100,32 +105,30 @@ export default function EntitySwitch({
<SidebarGroup> <SidebarGroup>
<SidebarGroupLabel asChild> <SidebarGroupLabel asChild>
<div className="flex items-center justify-between w-full"> <div className="flex items-center justify-between w-full">
<SidebarMenuButton asChild> <ContextMenu>
<CollapsibleTrigger className="flex w-full items-center"> <ContextMenuTrigger asChild>
{node.name} <SidebarMenuButton asChild>
<ChevronDown className="ml-auto h-4 w-4 transition-transform group-data-[state=open]/collapsible:rotate-180" /> <CollapsibleTrigger className="flex w-full items-center">
</CollapsibleTrigger> {node.name}
</SidebarMenuButton> <ChevronDown className="ml-auto h-4 w-4 transition-transform group-data-[state=open]/collapsible:rotate-180" />
<DropdownMenu open={menuOpen} onOpenChange={setMenuOpen}> </CollapsibleTrigger>
<DropdownMenuTrigger asChild> </SidebarMenuButton>
<button className="p-1 hover:bg-accent rounded"> </ContextMenuTrigger>
<MoreHorizontal className="h-4 w-4" /> <ContextMenuContent>
</button> <ContextMenuItem onSelect={() => openDialog("add-item")}>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem onSelect={() => openDialog("add-item")}>
Add list Add list
</DropdownMenuItem> </ContextMenuItem>
<DropdownMenuItem onSelect={() => openDialog("add-group")}> <ContextMenuItem onSelect={() => openDialog("add-group")}>
Add group Add group
</DropdownMenuItem> </ContextMenuItem>
<DropdownMenuSeparator /> <ContextMenuSeparator />
<DropdownMenuItem <ContextMenuItem
onSelect={() => openDialog("rename-group", node.name)} onSelect={() => openDialog("rename-group", node.name)}
> >
Rename Rename
</DropdownMenuItem> </ContextMenuItem>
<DropdownMenuItem <ContextMenuItem
variant="destructive"
onSelect={() => { onSelect={() => {
if ( if (
window.confirm("Delete this group and its children?") window.confirm("Delete this group and its children?")
@@ -135,9 +138,9 @@ export default function EntitySwitch({
}} }}
> >
Delete Delete
</DropdownMenuItem> </ContextMenuItem>
</DropdownMenuContent> </ContextMenuContent>
</DropdownMenu> </ContextMenu>
</div> </div>
</SidebarGroupLabel> </SidebarGroupLabel>
@@ -209,29 +212,27 @@ export default function EntitySwitch({
return ( return (
<SidebarMenuItem> <SidebarMenuItem>
<div className="flex items-center justify-between w-full"> <div className="flex items-center justify-between w-full">
<SidebarMenuButton <ContextMenu>
onClick={() => <ContextMenuTrigger asChild>
setRoute({ <SidebarMenuButton
workspace: workspace.id, onClick={() =>
entity: node.entityId, setRoute({
}) workspace: workspace.id,
} entity: node.entityId,
> })
{workspaceEntity.name} }
</SidebarMenuButton> >
<DropdownMenu open={menuOpen} onOpenChange={setMenuOpen}> {workspaceEntity.name}
<DropdownMenuTrigger asChild> </SidebarMenuButton>
<button className="p-1 hover:bg-accent rounded"> </ContextMenuTrigger>
<MoreHorizontal className="h-4 w-4" /> <ContextMenuContent>
</button> <ContextMenuItem
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem
onSelect={() => openDialog("rename-item", workspaceEntity.name)} onSelect={() => openDialog("rename-item", workspaceEntity.name)}
> >
Rename Rename
</DropdownMenuItem> </ContextMenuItem>
<DropdownMenuItem <ContextMenuItem
variant="destructive"
onSelect={() => { onSelect={() => {
if (window.confirm("Delete this list?")) { if (window.confirm("Delete this list?")) {
deleteEntity(node.entityId); deleteEntity(node.entityId);
@@ -239,9 +240,9 @@ export default function EntitySwitch({
}} }}
> >
Delete Delete
</DropdownMenuItem> </ContextMenuItem>
</DropdownMenuContent> </ContextMenuContent>
</DropdownMenu> </ContextMenu>
</div> </div>
</SidebarMenuItem> </SidebarMenuItem>
); );