feat(website): show resistance mutation annotations on COVID and RSV dashboards - #1359
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
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. |
…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>
61ca5b2 to
a3baa39
Compare
…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>
There was a problem hiding this comment.
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
byEnvis declared to returnTbut theswitchhas nodefault/exhaustiveness guard, so at runtime it can returnundefinedifenvis ever an unexpected value (and TypeScript may also warn that not all code paths return a value). Add adefaultbranch 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
mutationAnnotationscan now beundefinedwhen the server-side fetch fails andview.organismConstants.mutationAnnotationsis not set (e.g. COVID/RSV after this change). Passingundefinedinto<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
buildMutationAnnotationsindexescollections[i]without validating thatcollectionsandsetConfigshave matching lengths. Since this is an exported helper, a mismatch will currently throw a crypticCannot read properties of undefinedatcollections[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.tsextension (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.tsextension (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.tsextension (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';
Summary
Extract resistance mutation collection configs and helpers from the wasap subtree into a shared util file (resistanceMutations.ts). Add
byEnvas 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
PR Checklist