Skip to content

Commit

Permalink
feat(components): gs-mutation-filter: show error when the reference g…
Browse files Browse the repository at this point in the history
…enomes are empty

resolves #713
  • Loading branch information
fengelniederhammer committed Feb 11, 2025
1 parent e058cb4 commit 6e9bb19
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 8 deletions.
15 changes: 14 additions & 1 deletion components/src/preact/ReferenceGenomeContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,17 @@ import { createContext } from 'preact';

import { type ReferenceGenome } from '../lapisApi/ReferenceGenome';

export const ReferenceGenomeContext = createContext<ReferenceGenome>({ nucleotideSequences: [], genes: [] });
const UNINITIALIZED_SEQUENCE = '__uninitialized__';

export const ReferenceGenomeContext = createContext<ReferenceGenome>({
nucleotideSequences: [{ name: UNINITIALIZED_SEQUENCE, sequence: '' }],
genes: [],
});

export function isNotInitialized(referenceGenome: ReferenceGenome) {
return (
referenceGenome.genes.length === 0 &&
referenceGenome.nucleotideSequences.length === 1 &&
referenceGenome.nucleotideSequences[0].name === UNINITIALIZED_SEQUENCE
);
}
7 changes: 1 addition & 6 deletions components/src/preact/components/ReferenceGenomesAwaiter.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { type ComponentChildren, type FunctionalComponent } from 'preact';
import { useContext } from 'preact/hooks';

import { type ReferenceGenome } from '../../lapisApi/ReferenceGenome';
import { ReferenceGenomeContext } from '../ReferenceGenomeContext';
import { isNotInitialized, ReferenceGenomeContext } from '../ReferenceGenomeContext';

/**
* Sometimes the reference genome is not immediately available.
Expand All @@ -19,7 +18,3 @@ export const ReferenceGenomesAwaiter: FunctionalComponent<{ children: ComponentC

return <>{children}</>;
};

function isNotInitialized(referenceGenome: ReferenceGenome) {
return referenceGenome.nucleotideSequences.length === 0 && referenceGenome.genes.length === 0;
}
18 changes: 17 additions & 1 deletion components/src/preact/mutationFilter/mutation-filter.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type PreactRenderer, type Meta, type StoryObj } from '@storybook/preact';
import { type Meta, type PreactRenderer, type StoryObj } from '@storybook/preact';
import { expect, fireEvent, fn, userEvent, waitFor, within } from '@storybook/test';
import { type StepFunction } from '@storybook/types';

Expand All @@ -8,6 +8,7 @@ import { LAPIS_URL } from '../../constants';
import referenceGenome from '../../lapisApi/__mockData__/referenceGenome.json';
import { LapisUrlContextProvider } from '../LapisUrlContext';
import { ReferenceGenomeContext } from '../ReferenceGenomeContext';
import { playThatExpectsErrorMessage } from '../shared/stories/expectErrorMessage';

const meta: Meta<MutationFilterProps> = {
title: 'Input/MutationFilter',
Expand Down Expand Up @@ -219,6 +220,21 @@ export const WithInitialValue: StoryObj<MutationFilterProps> = {
},
};

export const WithNoReferenceSequencesDefined: StoryObj<MutationFilterProps> = {
...Default,
render: (args) => (
<LapisUrlContextProvider value={LAPIS_URL}>
<ReferenceGenomeContext.Provider value={{ nucleotideSequences: [], genes: [] }}>
<MutationFilter {...args} />
</ReferenceGenomeContext.Provider>
</LapisUrlContextProvider>
),
play: playThatExpectsErrorMessage(
'Error - No reference sequences available',
'This organism has neither nucleotide nor amino acid sequences',
),
};

async function prepare(canvasElement: HTMLElement, step: StepFunction<PreactRenderer, unknown>) {
const canvas = within(canvasElement);

Expand Down
8 changes: 8 additions & 0 deletions components/src/preact/mutationFilter/mutation-filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { type MutationsFilter, mutationsFilterSchema } from '../../types';
import { type DeletionClass, type InsertionClass, type SubstitutionClass } from '../../utils/mutations';
import { ReferenceGenomeContext } from '../ReferenceGenomeContext';
import { ErrorBoundary } from '../components/error-boundary';
import { UserFacingError } from '../components/error-display';
import { singleGraphColorRGBByName } from '../shared/charts/colors';

const mutationFilterInnerPropsSchema = z.object({
Expand Down Expand Up @@ -54,6 +55,13 @@ export const MutationFilterInner: FunctionComponent<MutationFilterInnerProps> =

const filterRef = useRef<HTMLDivElement>(null);

if (referenceGenome.nucleotideSequences.length === 0 && referenceGenome.genes.length === 0) {
throw new UserFacingError(
'No reference sequences available',
'This organism has neither nucleotide nor amino acid sequences configured in its reference genome. You cannot filter by mutations.',
);
}

const handleRemoveValue = (option: ParsedMutationFilter) => {
const newSelectedFilters = {
...selectedFilters,
Expand Down

0 comments on commit 6e9bb19

Please sign in to comment.