R8a: restore Open Document View for chat and conversation nodes - #170
Merged
Conversation
Both node kinds' right-click menus carried a disabled "Open Document View"
stub with the tooltip "Document view integration isn't wired into the SPA
yet" since the R7.6b Qt cutover deleted the legacy embedded document-
viewer panel (graphlink_document_viewer_web.py) without a successor.
DocumentViewDialog.tsx restores it as a read-only, scrollable modal
showing a node's full content as markdown. Frontend-only: the content is
already client-side (a chat node's own text, or a conversation node's
message history), so there is no backend change and no new WS intent -
only formatting and display. It reuses the app's existing shared Dialog
surface (the same one About/Help/Settings/Chat Library use - a centered,
single-open-across-the-app modal) rather than the raw-createPortal
anchored-popup pattern NodeMenu/CodeExecutionApprovalPanel use, since this
is not anchored to a click point.
Conversation nodes format their message history into a numbered
transcript, ported from the deleted app's own _history_to_markdown +
_build_document_section("Conversation Transcript", ...): each non-blank
message becomes "### N. Role", 1-indexed over the full history including
skipped blanks (a blank message consumes its number rather than
compressing the sequence), joined under one "## Conversation Transcript"
heading.
SceneCanvas.tsx owns the one piece of state this needs (which markdown is
currently on display) and threads an onOpenDocumentView callback through
toFlowNodes as a new optional third parameter, so the ~50 existing
two-argument call sites in SceneCanvas.test.tsx are unaffected. Both node
kinds guard against opening on empty content.
Built via four agents working in parallel on disjoint files against one
shared contract, then reviewed by two independent passes (cross-file
contract correctness, and transcript-format/test-quality fidelity) - both
came back clean. Verified independently: full backend suite (1033),
frontend typecheck/lint/tests/build (813 tests, 0 lint errors), and a live
browser check confirming the menu item is enabled, a real chat node's
content renders in the dialog, and Escape closes it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Restores the "Open Document View" menu action on chat nodes and conversation nodes, replacing a disabled placeholder with a working read-only overlay.
Problem
Both node kinds' right-click menus carried the item disabled, with the tooltip "Document view integration isn't wired into the SPA yet". The R7.6b Qt cutover deleted the legacy embedded document-viewer panel (
graphlink_document_viewer_web.py) without porting a successor.Changes
DocumentViewDialog.tsxis a new read-only, scrollable modal showing a node's full content as markdown. The feature is frontend-only: the content is already client-side (a chat node's own text, or a conversation node's message history), so no backend change or new WS intent was needed — only formatting and display.It reuses the app's existing shared
Dialogsurface, the same centered, single-open-across-the-app modalAbout/Help/Settings/Chat Libraryalready use, rather than the raw-createPortalanchored-popup patternNodeMenu/CodeExecutionApprovalPaneluse — this surface isn't anchored to a click point.Conversation transcript formatting is ported from the deleted application's own
_history_to_markdown+_build_document_section("Conversation Transcript", ...): each non-blank message becomes### N. Role, numbered 1-indexed over the full history including skipped blanks (a blank message consumes its number rather than compressing the sequence), joined under one## Conversation Transcriptheading.SceneCanvas.tsxowns the one piece of state this needs — which markdown is currently displayed — and threads anonOpenDocumentViewcallback throughtoFlowNodesas a new optional third parameter, so the ~50 existing two-argument call sites inSceneCanvas.test.tsxare unaffected. Both node kinds guard against opening on empty content.Verification
tsc --noEmit/ ESLint / tests / buildLive verification covered the chat-node path end to end. The conversation-transcript formatter — including the blank-message numbering edge case — was hand-verified against the exact ported algorithm and covered by dedicated unit tests, but not observed live, as the available test data contained no conversation nodes.
Related
Hide Other Branchesremains disabled — a distinct legacy feature (branch-visibility toggling) with no backend or frontend equivalent yet, tracked as separate work.