refactor context menu II

This commit is contained in:
2025-11-10 21:33:12 +01:00
parent 80f9044729
commit 8e630839a0
3 changed files with 144 additions and 67 deletions

View File

@@ -1,5 +1,5 @@
import { Dropdown, type MenuProps } from "antd";
import { useState } from "react";
import type { EdgeModel, NodeContext } from "./Graph";
const items: MenuProps['items'] = [
{
@@ -19,15 +19,21 @@ const items: MenuProps['items'] = [
}
]
export default function NodeContextMenu({
coords,
openContextMenu,
contextMenuOpened } :
{
coords: {x:number, y:number},
openContextMenu: React.Dispatch<React.SetStateAction<boolean>>,
contextMenuOpened: boolean
}) {
export default function NodeContextMenu({
nodeContext,
contextMenuOpened,
openContextMenu,
openRenameModal
}: {
nodeContext: NodeContext,
contextMenuOpened: boolean,
openContextMenu: React.Dispatch<React.SetStateAction<boolean>>,
openRenameModal: React.Dispatch<React.SetStateAction<boolean>>
}) {
if (!contextMenuOpened) {
return;
}
function contextMenuOpenChange(open: boolean) {
if (!open) {
openContextMenu(false)
@@ -35,32 +41,54 @@ export default function NodeContextMenu({
}
const onMenuClick: MenuProps['onClick'] = ({ key }) => {
switch (key) {
case 'rename': {
//openRenameModal(true);
break;
}
case 'remove': {
//removeNode(nodeId);
break;
}
case 'subgraph': {
break;
}
switch (key) {
case 'rename': {
openRenameModal(true);
break;
}
};
case 'remove': {
removeNode(nodeContext.nodeId);
break;
}
case 'subgraph': {
break;
}
}
};
function removeNode(id: string) {
nodeContext.setGraph(prev => ({ ...prev, nodes: [...prev.nodes.filter(n => n.id !== nodeContext.nodeId)], edges: removeEdgesOfNode(id, prev.edges) }));
}
function removeEdgesOfNode(nodeId: string, edges: EdgeModel[]): EdgeModel[] {
const parentConnection = edges.find(e => e.to === nodeId);
if (parentConnection) {
edges.filter(e => e.from === nodeId).forEach(e => {
e.from = parentConnection.from;
});
edges = edges.filter(e => e.to !== nodeId);
}
if (!parentConnection) {
edges = edges.filter(e => e.from !== nodeId);
}
const result = [...edges];
return result;
}
return (
<Dropdown menu={{ items, onClick: onMenuClick }} trigger={['contextMenu']} open={contextMenuOpened} onOpenChange={contextMenuOpenChange} getPopupContainer={() => document.body}
// 👇 Key part: manually position the dropdown
overlayStyle={{
position: "absolute",
left: coords.x,
top: coords.y,
left: nodeContext.coords.x,
top: nodeContext.coords.y,
}}>
</Dropdown>
)
}