Repository navigation
feat: Add data sidebar in the embedded viewer - #464
Merged
allison-truhlar merged 14 commits intoOct 16, 2026
Merged
Conversation
allison-truhlar
added this pull request to stack #429
October 7, 2026 19:18
allison-truhlar
marked this pull request as ready for review
October 7, 2026 19:27
allison-truhlar
force-pushed
the
ngviews-14-viewer-sidebar
branch
2 times, most recently
from
October 15, 2026 15:34
a785e52 to
c9f1cf2
Compare
Neuroglancer splits a multichannel OME-Zarr layer into one layer per
channel, named "<layer> <channel>". appendLayers compared only exact
names, so re-adding a dataset collided after the split and NG appended
its own digit ("…CD3-170Er1"). A name now also counts as taken when a
split layer of it exists, so the copy becomes "<layer> (2) <channel>".
…ources Add to this View no longer leaves datasets that can't load as layers in the cart. Their Data Links wait in the edit state, make the View dirty, and go to the server on Save as unsupported_sharing_keys, which appends unsupported view_layers rows once each. The Views table then lists them in Sources with the warning triangle, as checkout does.
… View Adding a dataset whose Data Link was deleted creates a new link, and creating a link relinks the owner's broken Views on that dataset server-side. The viewer's local state still pointed the old layer at the dead key, so the next Save overwrote the relink and re-broke the layer. The add now rewrites those broken sources to the new link in the local state too, from a snapshot of the View's rows taken before the link exists.
The cart's mismatch check compared datasets only with the first cart dataset. Beside the viewer, the reference is now the View's first source with OME dimensions, since a View's dimensions come from its first dataset at checkout. Every cart dataset that differs gets the warning triangle, and the Add to this View dialog asks for the acknowledgement.
allison-truhlar
force-pushed
the
ngviews-14-viewer-sidebar
branch
from
October 15, 2026 17:12
c9f1cf2 to
a88f582
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.
A View's owner can add data to the View they have open. This builds on #463 (edit and save). An "Add data" sidebar in the embedded viewer (
/view/<read_key>) shows the Layer Cart, and "Add to this View" adds the cart's datasets to the live View. Adding doesn't save: the View has unsaved changes and the owner keeps the change with the Save bar from #463.What changed
ready. Whether the sidebar is open is local state, with no new preference. Opening or closing the sidebar never remounts the iframe, so unsaved edits survive.CartListtakes anactionrender prop, so the sidebar shows "Add to this View" where/ngviewsand the Browse drawer show "Create View". The button stays disabled until every dataset is probed, because the mismatch check isn't final before then.useCartCheckoutsplits outresolveCartDatasets, which finds or creates each dataset's Data Link.useCreateViewFlowgainsstartAddToView, so adding shows the same consent and dimension-mismatch dialogs as Create View. The dialogs are titled "Add to this View", and adding skips the dialog when there is nothing to ask./ngviewsand in the Browse drawer), the first cart dataset stays the reference.useAddToViewbuilds layers with the existingbuildViewState, then merges them into the viewer's current state with the pure helperappendLayers. The View keeps its dimensions, layout, and selected layer. Added layers from index 4 on start archived. Neuroglancer requires unique layer names, so a repeated name gets(2), then(3). Neuroglancer splits a multichannel OME-Zarr layerXintoX <channel>layers, so a name also counts as taken when one of its split layers exists. Without that check, Neuroglancer renames the collision itself toX <channel>1.useViewEditStategainsmarkEdited. Branch 13 treats state changes before the first in-viewer input as Neuroglancer's own and absorbs them into the baseline. An add from the sidebar happens outside the iframe, so withoutmarkEditedthe View would never show as unsaved.useViewEditState.pendingSources, which counts as an unsaved change, and Discard drops it. On Save,PUT /api/neuroglancer/views/{short_key}sends it in the newunsupported_sharing_keysfield. The server appends an unsupportedview_layersrow for each key the View doesn't already list, and rejects an unknown key with a 400. The Views table then lists the dataset in Sources with the warning triangle, as it does after checkout.dataLinkSegmentandrewriteDataLinkSegmentport the server'sdata_link_segmentandrewrite_layer_segment.Testing
The backend suite (1127) and frontend suite (550) pass, ESLint and Prettier are clean, and
node-checkstays at the known 5-error baseline.I tested in headless Chromium against the dev passthrough:
5025551.zarr (2) <channel>.view_layersrow.5025551.zarrand a cart offused-multichannel.zarrthen5025552.zarr, the sidebar flagsfused-multichannel.zarrand not5025552.zarr.@krokicki