Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ jobs:
run: echo "branchTag=${TAG##*:}" >> $GITHUB_OUTPUT

- name: Wait for website Docker image
uses: lewagon/wait-on-check-action@v1.3.4
uses: lewagon/wait-on-check-action@v1.4.0
with:
ref: ${{ github.sha }}
check-name: Build Website Docker Image
repo-token: ${{ secrets.GITHUB_TOKEN }}
wait-interval: 10
- name: Wait for backend Docker image
uses: lewagon/wait-on-check-action@v1.3.4
uses: lewagon/wait-on-check-action@v1.4.0
with:
ref: ${{ github.sha }}
check-name: Build Backend Docker Image
Expand Down
16 changes: 8 additions & 8 deletions website/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
"@types/node": "^22.15.30",
"@types/node": "^24.0.3",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/topojson-specification": "^1.0.5",
Expand Down
114 changes: 114 additions & 0 deletions website/src/components/InfluenzaInformation.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
import Link from './Link.astro';

interface Props {
type: string;
}

const { type } = Astro.props;
---

<div>
<details>
<summary class='cursor-pointer font-bold'>How We Process Influenza Data</summary>
{
type === 'A' && (
<p class='mb-4'>
Genspectrum uses all open influenza A data that is available on the INSDC (taxonid: 197911). To
classify influenza segments and subtypes we use nextclade sort (using half of all k-mers for each
subtype defined in{' '}
<Link href='https://github.com/anna-parker/InfluenzaAReferenceDB/blob/main/config/config.yaml'>
https://github.com/anna-parker/InfluenzaAReferenceDB
</Link>
) to improve classification). Where available we use the assembly information to group segments that
are from the same sample/isolate. For all remaining segments we use a heuristic grouping algorithm
to group all segments from the same sample/isolate using the metadata available from each segment.
</p>
)
}
{
type === 'B' && (
<p class='mb-4'>
Genspectrum uses all open influenza B data that is available on the INSDC (taxonid: 11520). To
classify influenza segments and lineages we use nextclade sort (using half off all k-mers for each
lineage defined in
https://github.com/anna-parker/InfluenzaAReferenceDB/blob/main/influenza-b/config/config.yaml).
Where available we use the assembly information to group segments that are from the same
sample/isolate. For all remaining segments we use a heuristic grouping algorithm to group all
segments from the same sample/isolate using the metadata available from each segment.
</p>
)
}
</details>
<details>
<summary class='cursor-pointer font-bold'>Protein Functions Explained</summary>
{
type === 'A' && (
<div>
<ul class='mb-4 list-inside list-disc'>
<li>Segment 1: PB2 protein (part of the RNA polymerase subunit).</li>
<li>Segment 2: PB1 protein (part of the RNA polymerase subunit).</li>
<li>Segment 3: PA protein (part of the RNA polymerase subunit).</li>
<li>
Segment 4: HA protein (hemagglutinin, part of the envelope, functions as an attachment
factor and membrane fusion protein. It is responsible for binding influenza to sialic acid
on the surface of target cells in the upper respiratory tract.)
</li>
<li>
Segment 5: NP protein (nucleoprotein, at start of infection binds with RNA to enter host
cell nucleus where it is transcribed and replicated).
</li>
<li>
Segment 6: NA protein (Neuraminidase, part of the envelope, is an enzyme that breaks
glycosidic bonds in molecules called neuraminic acids (often found as sialic acids). This
helps the new virus particles leave the infected cell and spread to other cells).
</li>
<li>
Segment 7: M1 and M2 proteins (M1 forms the capsid - a layer between the nucleoprotein and
the envelope, M2 a proton channel protein).
</li>
<li>Segment 8: NS1 and NEP proteins (non-structural protein and nuclear export protein)</li>
</ul>
<p class='mb-4'>
For each individual influenza subtype you can view the CDS of each protein in the genome data
viewer.
</p>
</div>
)
}
{
type === 'B' && (
<div>
<ul class='mb-4 list-inside list-disc'>
<li>Segment 1: PB1 protein (part of the RNA polymerase subunit).</li>
<li>Segment 2: PB2 protein (part of the RNA polymerase subunit).</li>
<li>Segment 3: PA protein (part of the RNA polymerase subunit).</li>
<li>
Segment 4: HA protein (hemagglutinin, functions as an attachment factor and membrane fusion
protein. It is responsible for binding influenza to sialic acid on the surface of target
cells in the upper respiratory tract.)
</li>
<li>
Segment 5: NP protein (nucleoprotein, at start of infection binds with RNA to enter host
cell nucleus where it is transcribed and replicated).
</li>
<li>
Segment 6: NA protein (Neuraminidase is an enzyme that breaks glycosidic bonds in molecules
called neuraminic acids (often found as sialic acids). This helps the new virus particles
leave the infected cell and spread to other cells).
</li>
<li>
Segment 7: M1 and M2 proteins (M1 forms the capsid - a layer between the nucleoprotein and
the envelope, M2 a proton channel protein).
</li>
<li>Segment 8: NS1 and NEP proteins (non-structural protein and nuclear export protein)</li>
</ul>
<p class='mb-4'>
For each individual influenza lineage you can view the CDS of each protein in the genome data
viewer.
</p>
</div>
)
}
</details>
</div>
28 changes: 16 additions & 12 deletions website/src/components/genspectrum/GsNumberSequencesOverTime.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import '@genspectrum/dashboard-components/components';
import type { NamedLapisFilter } from '@genspectrum/dashboard-components/util';

import { ComponentWrapper } from '../ComponentWrapper.tsx';

type Views = 'bar' | 'line' | 'table';

type TemporalGranularity = 'day' | 'week' | 'month' | 'year';

export function GsNumberSequencesOverTime({
lapisDateField,
lapisFilter,
lapisFilters,
views,
width,
height,
Expand All @@ -16,7 +18,7 @@ export function GsNumberSequencesOverTime({
pageSize,
}: {
lapisDateField: string;
lapisFilter: NamedLapisFilter[];
lapisFilters: NamedLapisFilter[];
views?: Views[];
width?: string;
height?: string;
Expand All @@ -25,15 +27,17 @@ export function GsNumberSequencesOverTime({
pageSize?: boolean | number;
}) {
return (
<gs-number-sequences-over-time
lapisFilter={JSON.stringify(lapisFilter)}
lapisDateField={lapisDateField}
views={JSON.stringify(views)}
width={width}
height={height}
granularity={granularity}
smoothingWindow={smoothingWindow}
pageSize={pageSize}
></gs-number-sequences-over-time>
<ComponentWrapper title='Number sequences' height={height}>
<gs-number-sequences-over-time
lapisFilters={JSON.stringify(lapisFilters)}
lapisDateField={lapisDateField}
views={JSON.stringify(views)}
width={width}
height={height}
granularity={granularity}
smoothingWindow={smoothingWindow}
pageSize={pageSize}
></gs-number-sequences-over-time>
</ComponentWrapper>
);
}
49 changes: 0 additions & 49 deletions website/src/components/genspectrum/GsSequencesByLocation.astro

This file was deleted.

55 changes: 55 additions & 0 deletions website/src/components/genspectrum/GsSequencesByLocation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { type LapisFilter } from '@genspectrum/dashboard-components/util';
import type { FC } from 'react';

import { getSequencesByLocationMapData } from '../../util/getSequencesByLocationMapData';
import { defaultTablePageSize } from '../../views/View';
import { ComponentWrapper } from '../ComponentWrapper.tsx';

export type GsSequencesByLocationProps = {
title: string;
lapisLocationField: string;
lapisFilter: LapisFilter;
height?: string;
mapName?: string;
pageSize?: number;
};

export const GsSequencesByLocation: FC<GsSequencesByLocationProps> = ({
title,
height,
lapisLocationField,
lapisFilter,
mapName,
pageSize,
}) => {
const mapData = getSequencesByLocationMapData(mapName, window.location.href);

return (
<ComponentWrapper title={title} height={height}>
{mapData === undefined ? (
<gs-sequences-by-location
lapisLocationField={lapisLocationField}
lapisFilter={JSON.stringify(lapisFilter)}
pageSize={pageSize ?? defaultTablePageSize}
views={JSON.stringify(['table'])}
width='100%'
height={height ? '100%' : undefined}
/>
) : (
<gs-sequences-by-location
lapisLocationField={lapisLocationField}
lapisFilter={JSON.stringify(lapisFilter)}
pageSize={pageSize ?? defaultTablePageSize}
views={JSON.stringify(['map', 'table'])}
mapSource={JSON.stringify(mapData.mapSource)}
width='100%'
height={height ? '100%' : undefined}
zoom={mapData.zoom}
offsetX={mapData.offsetX}
offsetY={mapData.offsetY}
enableMapNavigation
/>
)}
</ComponentWrapper>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,18 @@ export function BaselineSelector({
},
});
}}
lapisFilter={lapisFilter}
lapisFilter={{ ...lapisFilter, [config.lapisField]: undefined }}
/>
</label>
);
}
case 'location': {
const filterIdentifier = locationFieldsToFilterIdentifier(config.locationFields);

const lapisFilerWithoutLocationFields = Object.fromEntries(
Object.entries(lapisFilter).filter(([key]) => !config.locationFields.includes(key)),
);

return (
<label className='form-control' key={`label${filterIdentifier}`}>
<div className='label'>
Expand All @@ -126,7 +130,7 @@ export function BaselineSelector({
}}
value={datasetFilter.locationFilters[filterIdentifier]}
placeholderText={config.placeholderText}
lapisFilter={lapisFilter}
lapisFilter={lapisFilerWithoutLocationFields}
></GsLocationFilter>
</label>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export function VariantSelector({
});
}}
key={lineageFilterConfig.lapisField}
lapisFilter={lapisFilter}
lapisFilter={{ ...lapisFilter, [lineageFilterConfig.lapisField]: undefined }}
value={variantFilter.lineages?.[lineageFilterConfig.lapisField]}
/>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export function FilterDisplay({
<h2 className='component-title'>Count over time</h2>
<div className='h-[400px]'>
<GsNumberSequencesOverTime
lapisFilter={[
lapisFilters={[
{
displayName: 'Your variant',
lapisFilter: addDateWindowToFilter(
Expand Down
Loading