feat: generate viewer links dynamically for Zarr datasets#307
feat: generate viewer links dynamically for Zarr datasets#307allison-truhlar wants to merge 86 commits intomainfrom
Conversation
- Custom viewers (validator, vol-e) now check for multiscales - Ensures viewers only display for OME-Zarr datasets, not plain Zarr arrays - Update DataToolLinks alt text to use displayName for E2E test compatibility
Add useCallback to memoize the getCompatibleViewers function in ViewersContext to prevent unnecessary recalculations and improve performance when filtering compatible viewers based on metadata.
Add more detailed error logging and ensure graceful degradation when: - Capability manifests fail to load - Viewer configuration parsing fails - No valid viewers are configured The application will continue with an empty viewer list and clear console messages to help users troubleshoot configuration issues.
neomorphic
left a comment
There was a problem hiding this comment.
Looks good to me. I was able to enable and disable a viewer using the viewers.config.yaml. I added a few comments about some the code I wasn't sure on.
- previously, if a logo path wasn't found, a 404 URL was still created, so it was never falling through to the fallback_logo.
- includes checking that a fallback_logo is used when no logo is found for a viewer
- includes mock viewers.config.yaml file for CI
…EffectiveZarrStorageVersion utilities - also splits availableVersions in the ZarrMetadataResult type into availableZarrVersions (number[]) and availableOmeZarrVersions (string[])
… and read versions from content
- copy icon had changed from img to svg - i saved the vizarr/avivator logo under avivator.png, so needed to update vizarr -> avivator
Use validateViewer() instead of isCompatible() so that when a viewer is filtered out, the specific reasons are logged (e.g. "Viewer does not support OME-Zarr v3 (supports: 0.4)").
krokicki
left a comment
There was a problem hiding this comment.
This is really coming along!
docs/ViewersConfiguration.md
Outdated
| | `frontend/viewers.config.yaml` | **Local override** — gitignored, safe to customize without merge conflicts | | ||
| | `frontend/src/config/viewers.config.yaml` | **Default config** — committed source file, used when no override exists | | ||
|
|
||
| Copy `frontend/viewers.config.yaml.template` to `frontend/viewers.config.yaml` to create a local override. This file is listed in `.gitignore` so your customizations will not conflict with upstream updates. |
There was a problem hiding this comment.
Could frontend/viewers.config.yaml.template be merged into frontend/src/config/viewers.config.yaml? Then you could just copy the default config to create a local override. This would have the benefit of not duplicating the viewer URLs in two places.
docs/ViewersConfiguration.md
Outdated
| | `manifest_url` | Yes | URL to a capability manifest YAML file | | ||
| | `instance_template_url` | No | Override the viewer's `template_url` from the manifest | | ||
| | `label` | No | Custom tooltip text (defaults to "View in {Name}") | | ||
| | `logo` | No | Filename of logo in `frontend/src/assets/` (defaults to `{normalized_name}.png`) | |
There was a problem hiding this comment.
Similar to the config, would it be possible to have a way to add custom viewer logos without triggering git changes? Maybe just adding a subfolder in assets that is already gitignored, and documenting it here? But that assumes you can put slashes in the logo filename, not sure if that's possible.
| label: "View in Vol-E" | ||
| ``` | ||
|
|
||
| ## Capability Manifest Files |
There was a problem hiding this comment.
We should document the capability manifest schema in the capability-manifest repo. This documentation could just link to a specific version (e.g. git commit) of that schema documentation.
|
|
||
| 1. The application reads the dataset's metadata (OME-Zarr version, axes, codecs, etc.) | ||
| 2. For each registered viewer, the library's `validateViewer()` function compares the dataset metadata against the manifest's declared capabilities | ||
| 3. Only viewers whose capabilities match the dataset are shown to the user |
There was a problem hiding this comment.
I think we need to distinguish at least two different "levels" of capabilities, e.g.:
- Data compatibility - will this data open in the view (or will it fail to open, or fail to render)
- Data support - is a particular data feature supported by the viewer (maybe it loads okay, but doesn't show a piece of metadata)
Generally speaking, these capabilities are about compatibility: ome_zarr_versions, compression_codecs, rfcs_supported. The rest are about support.
Another way to think about this is like the NGFF viewer feature matrix. There is an additional dimension of information (color) which describes how the viewer behaves when presented with the data.
Incompatible viewers should not be shown, but viewers which incompletely support the data should be shown, and their warnings logged or made accessible somewhere. For example, if a viewer doesn't support zarrv3, then OME-Zarrs with NGFF version >=0.5 should not be shown. But if a viewer does not support, say, omero_metadata, the viewer should still be shown.
| @@ -0,0 +1,41 @@ | |||
| viewer: | |||
There was a problem hiding this comment.
Since these YAML files are loaded by URL now, can we host them in the capabilities-manifest repo? That way, other non-Fileglancer consumers can access them.
| bioformats2raw_layout: false | ||
|
|
||
| # Is the OMERO metadata used to e.g. color the channels? | ||
| omero_metadata: false |
There was a problem hiding this comment.
I think Neuroglancer does use OMERO metadata.
| name: "Avivator" | ||
| version: "0.16.1" | ||
| repo: "https://github.com/hms-dbmi/viv" | ||
| template_url: "https://avivator.gehlenborglab.org/?image_url={DATA_URL}" |
There was a problem hiding this comment.
If this is Avivator, maybe the file should be called avivator.yaml?
Clickup id: 86advt10e
This PR implements dynamic viewer configuration for Zarr datasets via a build-time viewers.config.yaml file and integration of the @bioimagetools/capability-manifest library for automatic dataset-viewer compatibility detection.
Changes
Created viewers.config.yaml with documentation for customizing viewer configuration. This file specifies available viewers for a Fileglancer deployment. The default configuration is our current viewers: Neuroglancer, Avivator, Vol-E, and OME-Zarr Validator. Configuration is bundled at build time.
Added ViewersContext for managing viewer configuration. This context:
/publicfolder bundled into the application during the build (this is currently the case since the manifests are not present on our main branch, only in this PR branch)getCompatibleViewers()function to determine dataset-viewer compatibility using the capability-manifest library for compatibility detectionRefactored useZarrMetadata to dynamically generate
openWithToolUrlsusing ViewersContext. URLs are generated only for compatible viewers based on thegetCompatibleViewersfunction.Updated DataToolLinks to render viewer buttons dynamically by mapping over valid viewers from ViewersContext. The "Copy URL" tool is always available when a data link is available.
Added logo management system with convention-based naming (
{name}.png), custom logo override support, and fallback logo for missing assets.Added unit tests for config parsing and component tests for DataToolLinks.
Updated documentation with a ViewersConfiguration.md guide and updated CLAUDE.md with viewer configuration instructions.