From c9c3baecb344a3d5abddb01d3fc21aa7fd3ecd62 Mon Sep 17 00:00:00 2001 From: Guilhem Date: Wed, 4 Mar 2026 12:48:02 +0000 Subject: [PATCH] add context menu with delete option to preprocessor nodes (#8223) * fix: add context menu with delete option to preprocessor nodes Co-Authored-By: Claude Opus 4.5 * feat: add delete styling and shortcuts to right-click context menu Co-Authored-By: Claude Opus 4.5 --------- Co-authored-by: Claude Opus 4.5 --- .../common/contextmenu/ContextMenu.svelte | 14 +++++++--- .../common/contextmenu/contextMenuStyles.ts | 6 +++++ .../flows/map/FlowModuleSchemaItem.svelte | 2 +- .../graph/renderers/nodes/ModuleNode.svelte | 26 ++++++++++++------- .../graph/renderers/nodes/NodeWrapper.svelte | 19 +++++++++----- 5 files changed, 46 insertions(+), 21 deletions(-) diff --git a/frontend/src/lib/components/common/contextmenu/ContextMenu.svelte b/frontend/src/lib/components/common/contextmenu/ContextMenu.svelte index 86a2dc7ccb..ccab6ef3f0 100644 --- a/frontend/src/lib/components/common/contextmenu/ContextMenu.svelte +++ b/frontend/src/lib/components/common/contextmenu/ContextMenu.svelte @@ -8,6 +8,7 @@ getContextMenuContainerClass, CONTEXT_MENU_ITEM_BASE_CLASS, CONTEXT_MENU_ITEM_HOVER_MELT_CLASS, + CONTEXT_MENU_ITEM_DELETE_CLASS, CONTEXT_MENU_ITEM_DISABLED_CLASS, CONTEXT_MENU_DIVIDER_CLASS, CONTEXT_MENU_ANIMATION_CLASSES @@ -20,6 +21,8 @@ disabled?: boolean onClick?: () => void divider?: boolean + type?: 'action' | 'delete' + shortcut?: string } interface Props { @@ -111,18 +114,23 @@ CONTEXT_MENU_ITEM_BASE_CLASS, menuItem.disabled ? CONTEXT_MENU_ITEM_DISABLED_CLASS - : CONTEXT_MENU_ITEM_HOVER_MELT_CLASS + : menuItem.type === 'delete' + ? CONTEXT_MENU_ITEM_DELETE_CLASS + : CONTEXT_MENU_ITEM_HOVER_MELT_CLASS )} use:melt={$item} onclick={() => handleItemClick(menuItem)} > {#if menuItem.icon} - + {/if} {#if menu} {@render menu({ item: menuItem })} {:else} - {menuItem.label} + {menuItem.label} + {/if} + {#if menuItem.shortcut} + {menuItem.shortcut} {/if} {/if} diff --git a/frontend/src/lib/components/common/contextmenu/contextMenuStyles.ts b/frontend/src/lib/components/common/contextmenu/contextMenuStyles.ts index ecbe6c6f87..16844dc3d9 100644 --- a/frontend/src/lib/components/common/contextmenu/contextMenuStyles.ts +++ b/frontend/src/lib/components/common/contextmenu/contextMenuStyles.ts @@ -27,6 +27,12 @@ export const CONTEXT_MENU_ITEM_HOVER_CLASS = 'hover:bg-surface-hover' */ export const CONTEXT_MENU_ITEM_HOVER_MELT_CLASS = 'data-[highlighted]:bg-surface-hover' +/** + * Delete action styles for context menu items + */ +export const CONTEXT_MENU_ITEM_DELETE_CLASS = + 'text-red-600 dark:text-red-400 data-[highlighted]:bg-red-500/10 dark:data-[highlighted]:bg-red-900/80 dark:data-[highlighted]:text-red-300' + /** * Disabled state styles for context menu items */ diff --git a/frontend/src/lib/components/flows/map/FlowModuleSchemaItem.svelte b/frontend/src/lib/components/flows/map/FlowModuleSchemaItem.svelte index 0a0fe310f0..28c66c05ca 100644 --- a/frontend/src/lib/components/flows/map/FlowModuleSchemaItem.svelte +++ b/frontend/src/lib/components/flows/map/FlowModuleSchemaItem.svelte @@ -535,7 +535,7 @@ {/if} - {#if !isMultiSelected && id !== 'preprocessor' && menuItems && menuItems.length > 0} + {#if !isMultiSelected && menuItems && menuItems.length > 0}
data.eventHandlers.move({ id: data.id }) - }, - { - displayName: 'Duplicate', - icon: Copy, - action: () => data.eventHandlers.duplicate({ id: data.id }) - }, + ...(isPreprocessor + ? [] + : [ + { + displayName: 'Move', + icon: Move, + action: () => data.eventHandlers.move({ id: data.id }) + }, + { + displayName: 'Duplicate', + icon: Copy, + action: () => data.eventHandlers.duplicate({ id: data.id }) + } + ]), { displayName: 'Delete', icon: Trash2, diff --git a/frontend/src/lib/components/graph/renderers/nodes/NodeWrapper.svelte b/frontend/src/lib/components/graph/renderers/nodes/NodeWrapper.svelte index 46bcfb6ee9..329dafcdda 100644 --- a/frontend/src/lib/components/graph/renderers/nodes/NodeWrapper.svelte +++ b/frontend/src/lib/components/graph/renderers/nodes/NodeWrapper.svelte @@ -31,13 +31,18 @@ let resolvedContextMenuItems: ContextMenuItem[] | undefined = $derived( contextMenuItems ?? - menuItems?.map((item) => ({ - id: item.displayName, - label: item.displayName, - icon: item.icon, - disabled: item.disabled, - onClick: item.action as (() => void) | undefined - })) + menuItems?.flatMap((item) => [ + ...(item.separatorTop ? [{ id: `${item.displayName}-divider`, label: '', divider: true }] : []), + { + id: item.displayName, + label: item.displayName, + icon: item.icon, + disabled: item.disabled, + type: item.type, + shortcut: item.shortcut, + onClick: item.action as (() => void) | undefined + } + ]) ) const { moveManager } = getGraphContext()