diff --git a/frontend/src/components/network/ContextMenu.tsx b/frontend/src/components/network/ContextMenu.tsx index 2ea4b1ad..ca4e4151 100644 --- a/frontend/src/components/network/ContextMenu.tsx +++ b/frontend/src/components/network/ContextMenu.tsx @@ -1,5 +1,10 @@ import { useEffect, useRef } from 'react' -import { Copy, CopyPlus, Trash2, ClipboardPaste, BoxSelect, Maximize2, BringToFront, SendToBack } from 'lucide-react' +import { + Copy, CopyPlus, Trash2, ClipboardPaste, BoxSelect, Maximize2, BringToFront, SendToBack, + AlignStartVertical, AlignCenterHorizontal, AlignEndVertical, + AlignStartHorizontal, AlignCenterVertical, AlignEndHorizontal, + AlignHorizontalSpaceAround, AlignVerticalSpaceAround, +} from 'lucide-react' import { cn } from '@/lib/utils' interface MenuAction { @@ -15,9 +20,41 @@ interface ContextMenuProps { position: { x: number; y: number } actions: MenuAction[] onClose: () => void + onAlignLeft?: () => void + onAlignRight?: () => void + onAlignCenterH?: () => void + onAlignTop?: () => void + onAlignBottom?: () => void + onAlignCenterV?: () => void + onDistributeH?: () => void + onDistributeV?: () => void + canAlign?: boolean + canDistribute?: boolean + onGroupSelection?: () => void + onUngroupSelection?: () => void + canGroup?: boolean + canUngroup?: boolean } -export function ContextMenu({ position, actions, onClose }: ContextMenuProps) { +export function ContextMenu({ + position, + actions, + onClose, + onAlignLeft, + onAlignRight, + onAlignCenterH, + onAlignTop, + onAlignBottom, + onAlignCenterV, + onDistributeH, + onDistributeV, + canAlign, + canDistribute, + onGroupSelection, + onUngroupSelection, + canGroup, + canUngroup, +}: ContextMenuProps) { const menuRef = useRef(null) const clampedPosition = { ...position } @@ -83,6 +120,59 @@ export function ContextMenu({ position, actions, onClose }: ContextMenuProps) { ))} + + {canAlign && ( + <> +
+
Align
+ + + + + + + {canDistribute && ( + <> +
+
Distribute
+ + + + )} + + )} + + {(canGroup || canUngroup) && ( + <> +
+ {canGroup && ( + + )} + {canUngroup && ( + + )} + + )}
) } diff --git a/frontend/src/pages/NetworkDiagrams/DiagramEditor.tsx b/frontend/src/pages/NetworkDiagrams/DiagramEditor.tsx index 60e26ee3..1da1cd7a 100644 --- a/frontend/src/pages/NetworkDiagrams/DiagramEditor.tsx +++ b/frontend/src/pages/NetworkDiagrams/DiagramEditor.tsx @@ -736,6 +736,20 @@ function DiagramEditorInner() { }) } onClose={closeContextMenu} + onAlignLeft={diagramCommands.alignLeft} + onAlignRight={diagramCommands.alignRight} + onAlignCenterH={diagramCommands.alignCenterH} + onAlignTop={diagramCommands.alignTop} + onAlignBottom={diagramCommands.alignBottom} + onAlignCenterV={diagramCommands.alignCenterV} + onDistributeH={diagramCommands.distributeHorizontally} + onDistributeV={diagramCommands.distributeVertically} + canAlign={contextMenu.type === 'node' ? diagramCommands.canAlign : false} + canDistribute={contextMenu.type === 'node' ? diagramCommands.canDistribute : false} + onGroupSelection={() => {}} + onUngroupSelection={() => {}} + canGroup={false} + canUngroup={false} /> )} {pendingDeleteNodeId && (