diff --git a/frontend/src/lib/components/graph/FlowGraphV2.svelte b/frontend/src/lib/components/graph/FlowGraphV2.svelte index 08cd4e80ca..d63b06c5bb 100644 --- a/frontend/src/lib/components/graph/FlowGraphV2.svelte +++ b/frontend/src/lib/components/graph/FlowGraphV2.svelte @@ -241,7 +241,8 @@ setGraphContext({ selectionManager: selectionManager, useDataflow, - showAssets + showAssets, + noteManager }) if (triggerContext && allowSimplifiedPoll) { @@ -748,6 +749,7 @@ if (selectionManager.mode === 'normal') { selectionManager.clearSelection() } + noteManager.clearNoteSelection() }} onnodedragstop={(event) => { const node = event.targetNode diff --git a/frontend/src/lib/components/graph/graphContext.ts b/frontend/src/lib/components/graph/graphContext.ts index 99270a763a..5d2d24abc1 100644 --- a/frontend/src/lib/components/graph/graphContext.ts +++ b/frontend/src/lib/components/graph/graphContext.ts @@ -1,11 +1,13 @@ import { getContext, setContext } from 'svelte' import type { SelectionManager } from './selectionUtils.svelte' +import type { NoteManager } from './noteManager.svelte' import type { Writable } from 'svelte/store' type GraphContext = { selectionManager: SelectionManager useDataflow: Writable showAssets: Writable + noteManager?: NoteManager } const graphContextKey = 'FlowGraphContext' diff --git a/frontend/src/lib/components/graph/noteManager.svelte.ts b/frontend/src/lib/components/graph/noteManager.svelte.ts index fb46a44317..b0bebd3535 100644 --- a/frontend/src/lib/components/graph/noteManager.svelte.ts +++ b/frontend/src/lib/components/graph/noteManager.svelte.ts @@ -40,6 +40,9 @@ export class NoteManager { #getNodes: () => Node[] #editMode: boolean = false + // Selection state + selectedNoteId = $state(undefined) + constructor( notes: () => FlowNote[], setNodes: (nodes: Node[]) => void, @@ -306,4 +309,25 @@ export class NoteManager { delete this.#cache[noteId] this.render() } + + /** + * Select a note by ID (single selection only) + */ + selectNote(noteId: string): void { + this.selectedNoteId = noteId + } + + /** + * Clear note selection + */ + clearNoteSelection(): void { + this.selectedNoteId = undefined + } + + /** + * Check if a note is currently selected + */ + isNoteSelected(noteId: string): boolean { + return this.selectedNoteId === noteId + } } diff --git a/frontend/src/lib/components/graph/renderers/nodes/NoteNode.svelte b/frontend/src/lib/components/graph/renderers/nodes/NoteNode.svelte index 612de13f70..ed22fa0bf8 100644 --- a/frontend/src/lib/components/graph/renderers/nodes/NoteNode.svelte +++ b/frontend/src/lib/components/graph/renderers/nodes/NoteNode.svelte @@ -8,6 +8,7 @@ import { NoteColor, NOTE_COLORS, DEFAULT_NOTE_COLOR } from '../../noteColors' import { Button } from '$lib/components/common' import { getNoteEditorContext } from '../../noteEditor.svelte' + import { getGraphContext } from '../../graphContext' interface Props { data: { @@ -24,12 +25,16 @@ } let { data, dragging = false }: Props = $props() - let selected = $state(false) // Get NoteEditor context for edit mode const noteEditorContext = getNoteEditorContext() const isEditModeAvailable = $derived(!!noteEditorContext?.noteEditor && data.editMode) + // Get graph context for note selection + const graphContext = getGraphContext() + const noteManager = graphContext?.noteManager + const selected = $derived(noteManager?.isNoteSelected(data.noteId) ?? false) + let textareaElement: HTMLTextAreaElement | undefined = $state(undefined) let editMode = $state(false) let hovering = $state(false) @@ -115,6 +120,23 @@ }) let colorPickerIsOpen = $state(false) + + function handleNoteClick(event: MouseEvent) { + // Only handle selection if not in edit mode and not dragging + if (!editMode && !dragging && noteManager) { + event.stopPropagation() + noteManager.selectNote(data.noteId) + } + } + + function handleNoteKeydown(event: KeyboardEvent) { + // Handle Enter or Space key for selection (accessibility) + if ((event.key === 'Enter' || event.key === ' ') && !editMode && !dragging && noteManager) { + event.preventDefault() + event.stopPropagation() + noteManager.selectNote(data.noteId) + } + }
{ dragging = false }} @@ -138,7 +162,8 @@ }} onmouseenter={handleMouseEnter} onmouseleave={handleMouseLeave} - role="note" + role="button" + tabindex={editMode ? -1 : 0} > {#if isEditModeAvailable}