diff --git a/frontend/src/lib/components/graph/GroupNodeCard.svelte b/frontend/src/lib/components/graph/GroupNodeCard.svelte index 1c78012f28..35b3965e0c 100644 --- a/frontend/src/lib/components/graph/GroupNodeCard.svelte +++ b/frontend/src/lib/components/graph/GroupNodeCard.svelte @@ -3,6 +3,7 @@ import { getNodeColorClasses } from '$lib/components/graph' import { NOTE_COLORS, NoteColor } from './noteColors' import { twMerge } from 'tailwind-merge' + import { preventDefault, stopPropagation } from 'svelte/legacy' import GroupNoteArea from './GroupNoteArea.svelte' interface Props { @@ -14,6 +15,7 @@ note?: string showNote?: boolean editMode?: boolean + onSummaryUpdate?: (text: string) => void onNoteUpdate?: (text: string) => void onHeightChange?: (height: number) => void } @@ -27,6 +29,7 @@ note, showNote = false, editMode = false, + onSummaryUpdate, onNoteUpdate, onHeightChange }: Props = $props() @@ -37,6 +40,37 @@ let defaultColorClasses = $derived(getNodeColorClasses(undefined, selected)) + // Inline summary editing + let editingSummary = $state(false) + let summaryInput = $state('') + let summaryInputElement: HTMLInputElement | undefined = $state(undefined) + + function startEditingSummary() { + if (!editMode) return + editingSummary = true + summaryInput = summary ?? '' + requestAnimationFrame(() => { + summaryInputElement?.focus() + summaryInputElement?.select() + }) + } + + function saveSummary() { + editingSummary = false + const trimmed = summaryInput.trim() + if (trimmed !== (summary ?? '')) { + onSummaryUpdate?.(trimmed) + } + } + + function handleSummaryKeydown(event: KeyboardEvent) { + if (event.key === 'Enter') { + saveSummary() + } else if (event.key === 'Escape') { + editingSummary = false + } + } + // Reset height to 0 when note is hidden $effect(() => { if (!showNote) { @@ -63,7 +97,27 @@ >
- {summary || 'Group'} + {#if editingSummary} + {}))} + onpointerdown={stopPropagation(() => {})} + spellcheck="false" + /> + {:else} + + + {})) : undefined} + >{summary || 'Group'} + {/if} {#if stepCount != null} {stepCount} node{stepCount !== 1 ? 's' : ''} {/if} diff --git a/frontend/src/lib/components/graph/GroupOverlay.svelte b/frontend/src/lib/components/graph/GroupOverlay.svelte index e8ad863007..3065d5cbc6 100644 --- a/frontend/src/lib/components/graph/GroupOverlay.svelte +++ b/frontend/src/lib/components/graph/GroupOverlay.svelte @@ -148,6 +148,7 @@ note={group.note} showNote={showNotes && group.note != null} {editMode} + onSummaryUpdate={(text) => groupEditorContext?.groupEditor.updateSummary(group.id, text)} onNoteUpdate={(text) => groupEditorContext?.groupEditor.updateNote(group.id, text)} onHeightChange={(h) => groupEditorContext?.groupEditor.setNoteHeight(group.id, h)} /> diff --git a/frontend/src/lib/components/graph/renderers/nodes/CollapsedGroupNode.svelte b/frontend/src/lib/components/graph/renderers/nodes/CollapsedGroupNode.svelte index f1495672f3..24688755c3 100644 --- a/frontend/src/lib/components/graph/renderers/nodes/CollapsedGroupNode.svelte +++ b/frontend/src/lib/components/graph/renderers/nodes/CollapsedGroupNode.svelte @@ -38,6 +38,8 @@ note={data.note} showNote={data.showNotes && data.note != null} editMode={data.editMode} + onSummaryUpdate={(text) => + groupEditorContext?.groupEditor.updateSummary(data.groupId, text)} onNoteUpdate={(text) => groupEditorContext?.groupEditor.updateNote(data.groupId, text)} onHeightChange={(h) =>