Skip to content

feat(website): show resistance mutation annotations on COVID and RSV dashboards - #1359

Merged
fhennig merged 9 commits into
mainfrom
resistance-mutation-annotations-on-regular-dashboards
Jul 30, 2026
Merged

feat(website): show resistance mutation annotations on COVID and RSV dashboards#1359
fhennig merged 9 commits into
mainfrom
resistance-mutation-annotations-on-regular-dashboards

Conversation

@fhennig

@fhennig fhennig commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Extract resistance mutation collection configs and helpers from the wasap subtree into a shared util file (resistanceMutations.ts). Add byEnv as a pure selector to dbIdSpace.ts. Wire COVID, RSV-A, and RSV-B constants to factory functions that build collection configs; have the generic Astro page components fetch annotations server-side and pass them down through the React layout tree.

Screenshot

image

PR Checklist

  • All necessary documentation has been adapted.
  • The implemented feature is covered by an appropriate test.

@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
dashboards Ready Ready Preview Jul 30, 2026 8:54am

Request Review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds support for displaying resistance mutation annotations on organism dashboards (COVID, RSV-A, RSV-B) by extracting resistance-collection configuration and annotation-building utilities into shared helpers, and by fetching these annotations server-side in the generic Astro pages before passing them down into the React layout tree.

Changes:

  • Introduces shared resistance-mutation utilities (resistanceMutations.ts) and an SSR fetch helper (fetchOrganismMutationAnnotations.ts).
  • Extends organism constants with a factory hook to build resistance-collection configs by environment, and wires COVID/RSV-A/RSV-B to these factories.
  • Updates the generic Astro pages + React layouts to accept and forward mutationAnnotations.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
website/src/views/rsvB.ts Removes empty per-organism annotations and wires RSV-B to the shared resistance-collection factory.
website/src/views/rsvA.ts Removes empty per-organism annotations and wires RSV-A to the shared resistance-collection factory.
website/src/views/OrganismConstants.ts Adds optional buildResistanceMutationCollections hook to organism constants.
website/src/views/covid.ts Removes empty per-organism annotations and wires COVID to the shared resistance-collection factory.
website/src/util/resistanceMutations.ts New shared utilities: collection config types, env-specific collection builders, annotation building, and collection fetch-to-annotations helper.
website/src/util/fetchOrganismMutationAnnotations.ts New SSR helper to fetch organism mutation annotations safely (tolerates failures).
website/src/types/wastewaterConfig.ts Reuses shared resistance-collection factory functions and central byEnv selector.
website/src/types/dbIdSpace.ts Adds exported byEnv selector for env-dependent constants.
website/src/layouts/OrganismPage/SingleVariantOrganismPageLayout.tsx Adds optional mutationAnnotations prop and forwards to OrganismViewPageLayout.
website/src/layouts/OrganismPage/OrganismViewPageLayout.tsx Accepts optional mutationAnnotations prop and prioritizes it over constants’ annotations.
website/src/components/views/wasap/wasapPageConfig.ts Moves ResistanceMutationCollectionConfig type import to shared util.
website/src/components/views/wasap/resistanceData.ts Reuses shared buildMutationAnnotations to avoid duplication.
website/src/components/views/sequencingEfforts/GenericSequencingEffortsReactPage.tsx Threads optional mutationAnnotations prop into the layout tree.
website/src/components/views/sequencingEfforts/GenericSequencingEffortsPage.astro Fetches mutation annotations server-side and passes to the React page.
website/src/components/views/compareVariants/GenericCompareVariantsReactPage.tsx Threads optional mutationAnnotations prop into the layout tree.
website/src/components/views/compareVariants/GenericCompareVariantsPage.astro Fetches mutation annotations server-side and passes to the React page.
website/src/components/views/compareToBaseline/GenericCompareToBaselineReactPage.tsx Threads optional mutationAnnotations prop into the layout tree.
website/src/components/views/compareToBaseline/GenericCompareToBaselinePage.astro Fetches mutation annotations server-side and passes to the React page.
website/src/components/views/compareSideBySide/GenericCompareSideBySideReactPage.tsx Threads optional mutationAnnotations prop into the layout tree.
website/src/components/views/compareSideBySide/GenericCompareSideBySidePage.astro Fetches mutation annotations server-side and passes to the React page.
website/src/components/views/analyzeSingleVariant/GenericAnalyzeSingleVariantPage.astro Fetches mutation annotations server-side and passes to the React page.
website/src/components/views/analyzeSingleVariant/GenericAnalyseSingleVariantReactPage.tsx Threads optional mutationAnnotations prop into the layout tree.

Comment thread website/src/types/dbIdSpace.ts
Comment thread website/src/views/covid.ts
Comment thread website/src/util/fetchOrganismMutationAnnotations.ts
Felix Hennig and others added 6 commits July 29, 2026 14:54
…dashboards

Extract resistance mutation collection configs and helpers from the wasap
subtree into a shared util file (resistanceMutations.ts). Add `byEnv` as
a pure selector to dbIdSpace.ts. Wire COVID, RSV-A, and RSV-B constants
to factory functions that build collection configs; have the generic Astro
page components fetch annotations server-side and pass them down through
the React layout tree.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… duplication

The five generic Astro page components all had identical 12-line blocks for
fetching resistance mutation annotations. Extract these into a single helper
with its own dedicated logger instance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nfig from wasapPageConfig

Consumers should import directly from resistanceMutations.ts; the re-export was unused.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…variant page

The COVID single-variant page uses a custom Astro page that bypasses the
generic one, so it was not fetching annotations at all. Add the fetch call
and thread the mutationAnnotations prop through CovidSingleVariantReactPage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ions

Unit tests cover buildMutationAnnotations directly: empty inputs, the
annotationSymbol→symbol rename, query-variant exclusion, missing
aminoAcidMutations, and multi-collection ordering.

E2E tests verify that COVID, RSV-A, and RSV-B single-variant pages show
the expected resistance mutation set names in the filter mutations panel.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n E2E tests

The mutations-over-time component (which contains the Filter mutations button)
only renders after a variant has been selected and filters applied. The previous
tests clicked the button immediately on page load before the component existed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@fhennig
fhennig force-pushed the resistance-mutation-annotations-on-regular-dashboards branch from 61ca5b2 to a3baa39 Compare July 29, 2026 12:54
…ode violation

Both the nucleotide and amino acid mutations-over-time components render a
Filter mutations button. Both show the same annotations so clicking either is
sufficient; .first() avoids Playwright's strict mode error on ambiguous locators.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ons-over-time panel

Both nuc and AA components render their filter labels in the DOM at all times
(overflow-clipped when closed), so page-level getByText finds both. Scope
the button click and text assertions to the first gs-mutations-over-time
element to avoid strict mode violations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 26 out of 26 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (6)

website/src/types/dbIdSpace.ts:18

  • byEnv is declared to return T but the switch has no default/exhaustiveness guard, so at runtime it can return undefined if env is ever an unexpected value (and TypeScript may also warn that not all code paths return a value). Add a default branch that throws to make the function total and fail fast.
export function byEnv<T>(env: DbIdSpace, vars: { prod: T; staging: T; local: T }): T {
    switch (env) {
        case dbIdSpaces.prod:
            return vars.prod;
        case dbIdSpaces.staging:
            return vars.staging;
        case dbIdSpaces.local:
            return vars.local;
    }
}

website/src/layouts/OrganismPage/OrganismViewPageLayout.tsx:35

  • mutationAnnotations can now be undefined when the server-side fetch fails and view.organismConstants.mutationAnnotations is not set (e.g. COVID/RSV after this change). Passing undefined into <gs-app mutationAnnotations={...}> risks runtime errors if the web component assumes an array. Coalesce to an empty array as a safe default.
            <gs-app
                lapis={lapisUrl}
                mutationAnnotations={mutationAnnotations ?? view.organismConstants.mutationAnnotations}
            >

website/src/util/resistanceMutations.ts:32

  • buildMutationAnnotations indexes collections[i] without validating that collections and setConfigs have matching lengths. Since this is an exported helper, a mismatch will currently throw a cryptic Cannot read properties of undefined at collections[i].variants. Add an explicit length check with a clear error.
    return setConfigs.map((setConfig, i) => {
        const filterVariants = collections[i].variants.filter((v) => v.type === 'filterObject');
        return {

website/src/views/covid.ts:32

  • In website/src/views/*, internal util imports consistently include the .ts extension (e.g. website/src/views/mpox.ts:36). This new import is missing the extension, which is inconsistent with the established pattern and can be problematic under stricter ESM module resolution. Consider updating it to include .ts.
import { buildCovidResistanceMutationCollections } from '../util/resistanceMutations';

website/src/views/rsvA.ts:37

  • In website/src/views/*, internal util imports consistently include the .ts extension (e.g. website/src/views/mpox.ts:36). This new import is missing the extension, which is inconsistent with the established pattern and can be problematic under stricter ESM module resolution. Consider updating it to include .ts.
import { buildRsvAResistanceMutationCollections } from '../util/resistanceMutations';

website/src/views/rsvB.ts:37

  • In website/src/views/*, internal util imports consistently include the .ts extension (e.g. website/src/views/mpox.ts:36). This new import is missing the extension, which is inconsistent with the established pattern and can be problematic under stricter ESM module resolution. Consider updating it to include .ts.
import { buildRsvBResistanceMutationCollections } from '../util/resistanceMutations';

Comment thread website/src/util/fetchOrganismMutationAnnotations.ts Outdated
Comment thread website/src/util/fetchOrganismMutationAnnotations.ts Outdated
@fhennig
fhennig merged commit 0672a6b into main Jul 30, 2026
9 of 10 checks passed
@fhennig
fhennig deleted the resistance-mutation-annotations-on-regular-dashboards branch July 30, 2026 08:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants