Skip to content

Conversation

@jameshadfield
Copy link
Member

@jameshadfield jameshadfield commented Nov 19, 2025

Review app for nextstrain.org
Review app for stand-alone Auspice

The sidebar-based dataset selector has existed unchanged for many years
now, despite many nextstrain.org changes to how datasets are served
(different sources, snapshots etc).

This commit completely redesigns the selector UI, whilst still
leveraging the same underlying data (via the charon/getAvailable API
call). The two big UI improvements are to allow multiple changes to
different parts of the heirarcy (rather than changing page as soon as
anything was changed), and to allow snapshots to be requested.

image

A number of bugs are fixed, namely those which occured when changing an
intermediate-level option wouldn't preserve deeper options.² For
instance, previously viewing "seasonal-flu/h3n2/na/3y" then changing
"na" to "ha" would change "3y" to "2y"¹. The UI now preserves the
choices for different levels where possible, and selects defaults where
necessary.³

As with a redesign like this there are future avenues to persue if we
choose to!

  • There is a conflict between Auspice-specific code and nextstrain.org
    specific code, especially for snapshots.
  • Snapshots aren't available in the (nextstrain.org) getAvailable API
    response, so we allow any YYYY-MM-DD value and rely on the server to
    handle these appropriately.
  • The nextstrain.org getAvailable data is per-source, e.g. for core
    datasets you can only see other core datasets. We could greatly
    rethink this, but this is better done as a redesign of the
    getAvailable API.
  • Expose available narratives via the UI. I started out intending to do
    this but didn't get round to it.

Closes #560
Closes #697
Closes nextstrain/nextstrain.org#352
Closes nextstrain/nextstrain.org#40

¹ This happened because the client made a request to
seasonal-flu/h3n2/ha which was expanded to the canonical/default 2y
timespan

² This resulted in bugs when the server didn't redirect, most common
on nextstrain.org groups and community pages, e.g. see
nextstrain/nextstrain.org#40

³ If a level's chosen option isn't available (e.g. change 'seasonal-flu'
to 'avian-flu' and thus 'h3n2' doesn't exist) then we choose a default
by looking at the first applicable option from the available datasets.
This doesn't necesarily match the default on the server-side, which is
set via the manifest JSON. In the avian-flu case, the UI will select
'h5n1-cattle-outbreak' but the server would have selected 'h5n1'.


Original PR message (now outdated)

As part of diving into the quirks of how we change datasets yesterday I ended up prototyping how a new auspice selector might work. Early days, but I think this has promise. The main idea is that we leverage the getAvailable data API to limit Auspice into only allowing valid selections, so there should never be a situation where the server has to canonicalize / redirect the requested dataset.

@victorlin @joverlee521 I'd be interested in your thoughts at this early stage

E.g. load https://nextstrain-s-nextstrain-amsecf.herokuapp.com/groups/blab/229e/E, click on the dataset (top of sidebar), and interact with the new modal.

@victorlin
Copy link
Member

victorlin commented Nov 19, 2025

Nice! I found this nested example useful for exploring more: https://nextstrain-s-nextstrain-amsecf.herokuapp.com/groups/blab/flu/seasonal/h1n1pdm/ha/12y

Haven't looked at the code, but looks great in terms of functionality. Not sure if you want feedback on UI at this stage, so I'll hold back on that.

@joverlee521
Copy link
Contributor

Nice, I really like this direction! In brief testing, this works with core, groups (within single group), and community (within single repo). Doesn't work as well with staging but that seems expected since the available datasets for staging is just a duplication of core.

I'm all for pushing on this to polish the UI and getting this out!

@jameshadfield
Copy link
Member Author

jameshadfield commented Nov 19, 2025

I'm all for pushing on this to polish the UI and getting this out!

Great - seems like there's consensus here. I think the behaviour is pretty good, although I still want to:

  • look into the relationship between the core getAvailable data and our concepts of defaults
  • work out if we ever have or want "partial" datasets, e.g. A + A/B, as that complicates things a fair bit
  • make versioned @YYYY-MM-DD datasets work
  • think about 2-tree views

Doesn't work as well with staging but that seems expected since the available datasets for staging is just a duplication of core.

Good observation. I think that should be improved, but on the server-side as you imply. The simplest would be akin to what we do for groups (basically run aws s3 ls every ~hour) or leverage the resource indexer (which we're already using), but I'm going to stay away for now...

Haven't looked at the code, but looks great in terms of functionality. Not sure if you want feedback on UI at this stage, so I'll hold back on that.

Please share any big UI ideas you have! I was thinking of adding buttons/tabs for "datasets" vs "narratives", but otherwise just polishing what you see here.

@jameshadfield jameshadfield force-pushed the james/dataset-selector branch 2 times, most recently from 97db69f to c43cec4 Compare January 8, 2026 22:17
@jameshadfield jameshadfield changed the title prototype new dataset selector New dataset selector Jan 8, 2026
@jameshadfield jameshadfield marked this pull request as ready for review January 8, 2026 22:18
@jameshadfield jameshadfield temporarily deployed to auspice-james-dataset-s-zdevkq January 8, 2026 22:21 Inactive
@joverlee521 joverlee521 self-requested a review January 9, 2026 21:10
Copy link
Contributor

@joverlee521 joverlee521 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left mostly minor comments and notes on odd behaviors I noticed. Overall, like I said before, I really like this new design!

Comment on lines 192 to 217
/**
* Render a freeform text input for snapshot name, styled to match CustomSelect.
*
* A note on snapshots: In the vanilla Auspice client/server a '@YYYY-MM-DD' part of the dataset
* isn't special, it needs to be part of the actual filename to work; this also means the available
* "snapshots" are known to us via this.props.available. In the nextstrain.org server it's special
* cased, and if it's not in YYYY-MM-DD format then loading that dataset results in a Bad Request.
*
* This implementation is catered for nextstrain.org usage -- you can enter in any datestamp but
* we enforce the YYYY-MM-DD format client-side. So if you use `@` in your datasets in Auspice
* functionality of the dataset selector will be less than idea. Long term, I think we should
* incorporate the idea of special-casing '@' in Auspice too!
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not asking for change, just want to document behavior that I've seen

Really awesome that this works for snapshots of the core datasets in nextstrain.org! I wish we could hide it for groups/community which don't support the snapshots. From a groups/community dataset, entering a snapshot will go to an error page, which I think is ~fine.

As you noted this is not ideal in vanilla Auspice: if I enter a snapshot that does not exist as part of the filename, then the dataset goes to the default (?) dataset instead of an error page.

Screen.Recording.2026-01-09.at.2.55.50.PM.mov

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This encouraged me to actually sort it out rather than the unsatisfying place I had left it at.

I modified the getAvailable response structure to allow datasets to specify an optional snapshosts boolean (undocumented at the moment), and only when a dataset supports it does the UI allow snapshots to be entered. This requires a small nextstrain.org server change to expose the snapshots UI for core/nextclade datasets.

P.S. I left it undocumented as we might want to change from a boolean to a list of known snapshots in the future, but I don't want to block on that possible enhancement.

The structure was inferred from auspice server & nextstrain.org server
responses, as it's grown organically/haphazardly over time.
Only triggered on mobile, but greatly improves the UX
Not used for the current modals but will be for the upcoming dataset
selector
The sidebar-based dataset selector has existed unchanged for many years
now, despite many nextstrain.org changes to how datasets are served
(different sources, snapshots etc).

This commit completely redesigns the selector UI, whilst still
leveraging the same underlying data (via the `charon/getAvailable` API
call). The two big UI improvements are to allow multiple changes to
different parts of the heirarcy (rather than changing page as soon as
anything was changed), and to allow snapshots to be requested.

A number of bugs are fixed, namely those which occured when changing an
intermediate-level option wouldn't preserve deeper options.² For
instance, previously viewing "seasonal-flu/h3n2/na/3y" then changing
"na" to "ha" would change "3y" to "2y"¹. The UI now preserves the
choices for different levels where possible, and selects defaults where
necessary.³

As with a redesign like this there are future avenues to persue if we
choose to!
* There is a conflict between Auspice-specific code and nextstrain.org
  specific code, especially for snapshots.
* Snapshots aren't available in the (nextstrain.org) `getAvailable` API
  response, so we allow any YYYY-MM-DD value and rely on the server to
  handle these appropriately.
* The nextstrain.org `getAvailable` data is per-source, e.g. for core
  datasets you can only see other core datasets. We could greatly
  rethink this, but this is better done as a redesign of the
  getAvailable API.
* Expose available narratives via the UI. I started out intending to do
  this but didn't get round to it.

Closes <#560>
Closes <#697>
Closes <nextstrain/nextstrain.org#352>
Closes <nextstrain/nextstrain.org#40>

¹ This happened because the client made a request to
`seasonal-flu/h3n2/ha` which was expanded to the canonical/default 2y
timespan

² This resulted in bugs when the server didn't redirect, most common
on nextstrain.org groups and community pages, e.g. see
<nextstrain/nextstrain.org#40>

³ If a level's chosen option isn't available (e.g. change 'seasonal-flu'
to 'avian-flu' and thus 'h3n2' doesn't exist) then we choose a default
by looking at the first applicable option from the available datasets.
This doesn't necesarily match the default on the server-side, which is
set via the manifest JSON. In the avian-flu case, the UI will select
'h5n1-cattle-outbreak' but the server would have selected 'h5n1'.
@jameshadfield jameshadfield force-pushed the james/dataset-selector branch from c43cec4 to 8fcd06b Compare January 19, 2026 21:42
@jameshadfield jameshadfield temporarily deployed to auspice-james-dataset-s-zdevkq January 19, 2026 21:42 Inactive
jameshadfield added a commit to nextstrain/nextstrain.org that referenced this pull request Jan 19, 2026
The new Auspice dataset selector UI
<nextstrain/auspice#2030> looks for an optional
`snapshots: boolean` in the getAvailable API response to decide whether
to expose this in the UI. Over time we may adapt this response (and the
UI) to list the known snapshots, but for now a `true` value will result
in a freeform text box where you can enter in the desired YYYY-MM-DD
snapshot for a given dataset.
@jameshadfield jameshadfield merged commit a341764 into master Jan 19, 2026
17 checks passed
@jameshadfield jameshadfield deleted the james/dataset-selector branch January 19, 2026 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

5 participants