Repository navigation
feat(viewer): edit and save Views in the embedded Neuroglancer - #463
Merged
Merged
Conversation
allison-truhlar
added this pull request to stack #429
October 6, 2026 20:20
allison-truhlar
marked this pull request as ready for review
October 6, 2026 20:43
allison-truhlar
force-pushed
the
ngviews-13-edit-save
branch
from
October 6, 2026 20:48
55ae25f to
60568f3
Compare
allison-truhlar
force-pushed
the
ngviews-13-edit-save
branch
from
October 7, 2026 18:34
60568f3 to
ab3c0ec
Compare
allison-truhlar
force-pushed
the
ngviews-13-edit-save
branch
from
October 13, 2026 14:25
32c78cd to
0ab29a6
Compare
allison-truhlar
force-pushed
the
ngviews-13-edit-save
branch
from
October 15, 2026 15:34
0ab29a6 to
1bed914
Compare
…icter passthrough paths - The embedded viewer fixed its iframe src on first state load, which could land before the viewers config and lock in the appspot fallback (so editing showed as unavailable on same-origin deployments). The internal NG base URL is now null until the config loads, and the viewer waits for it. - The beforeunload guard fired for non-owners, who cannot save. - A failed background refetch replaced the viewer (and unsaved edits) with "View not found"; cached state now keeps rendering. - The dev passthrough rejects '%' so a once-decoded %2e%2e can't escape the configured prefix upstream.
If the iframe reloads while the View is dirty, toast that changes may have been lost and hide the Save bar until Neuroglancer is ready again. Then compare with the saved baseline instead of re-baselining: Neuroglancer restores its own URL hash, so edits can survive the reload and must stay unsaved.
…edits With unsaved changes, in-app link clicks (logo, Views breadcrumb, profile menu) and Copy link / Download JSON / Open in Neuroglancer open a dialog: Save and continue, Continue without saving, or Cancel. Exports use the state just saved, or the last saved one when continuing without saving. BrowserRouter has no useBlocker, so a capture-phase click listener on the document intercepts same-origin links before React Router's Link handles them. Browser back/forward still leaves without asking.
…ough test_no_passthrough_when_unset built Settings without neuroglancer_url, so a developer's config.yaml that sets it made the test fail. Pass None explicitly.
…ache Save and continue saves, then leaves the page, which cancels the state refetch the save triggered. Reopening the View then rendered the cached pre-save state first, and because the iframe src is fixed at first load, Neuroglancer kept showing it after the refetch landed. Wait for the mount refetch before fixing the src.
The message, each source path, and its Relink button now share a row, with equal gaps between them, so the banner takes one line for a single broken source. Extra sources wrap after the message, which ends in a colon. The path uses the message's font so the row reads evenly.
allison-truhlar
force-pushed
the
ngviews-13-edit-save
branch
from
October 15, 2026 17:12
1bed914 to
e945210
Compare
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.
Editable-Views branch 13: a View's owner edits it in the embedded Neuroglancer viewer (
/view/<read_key>) and keeps the changes with an explicit Save or Discard. This builds on #458 (relink UI) and the existingPUT /api/neuroglancer/views/{short_key}.Editing reads the iframe's
window.viewer, so it works only when Fileglancer and Neuroglancer share an origin. With a cross-origin Neuroglancer, such as the CLI defaultneuroglancer-demo.appspot.com, the owner sees "Editing isn't available with this Neuroglancer deployment" and the viewer stays read-only.What changed
useNeuroglancerViewerhook polls the iframe forwindow.viewer. It reportsreadyfor a same-origin viewer andunavailablewhen access throws, and it exposesgetState,setState, and change subscriptions.useViewEditStatecompares the viewer'stoJSON()with a saved baseline. Until the user first interacts, each change resets the baseline, so Neuroglancer's own normalization and position updates during load don't count as edits. After a Save, the baseline is the state the request sent, so a camera move during an in-flight Save stays unsaved.srconce, at first load, so the refetch after a Save doesn't reload Neuroglancer.RelinkDialogfrom feat(views): relink broken View sources from the Views table and on Data Link create #458. After a relink, the bridge pushes the new state into the viewer; when the bridge is unavailable, the iframe reloads with the relinked state. The Relink button stays disabled while the View has unsaved changes, with the tooltip "Save or discard changes first".beforeunloadprompt.BrowserRouterhas nouseBlocker, so a capture-phase click listener catches same-origin links before React Router handles them. Browser back and forward still leave without asking.useCanEditView. A non-owner gets no Save bar, note, banner, dialog, or leave prompt.neuroglancer_urlsetting (FGC_NEUROGLANCER_URL) serves that Neuroglancer at/neuroglancer/, so you can test editing locally. The setting is unset by default, and the routes exist only when you set it. The passthrough is a GET proxy that rejects dot segments,%,?, and#in the path. Production serves Neuroglancer from its reverse proxy instead. The Vite dev server proxies/neuroglancerto the backend. For setup, see "Testing View editing locally" indocs/Development.md.Testing
The backend suite (1122) and frontend suite (517) pass, ESLint and Prettier are clean, and
node-checkstays at the known 5-error baseline.I tested editing by hand against the real Neuroglancer through the dev passthrough:
@krokicki