@genspectrum/dashboard-components 0.13.7 → 0.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +24 -62
- package/dist/{LineageFilterChangedEvent-GedKNGFI.js → LineageFilterChangedEvent-C9dXOxt6.js} +11 -3
- package/dist/LineageFilterChangedEvent-C9dXOxt6.js.map +1 -0
- package/dist/assets/mutationOverTimeWorker-Dxnxrfe0.js.map +1 -1
- package/dist/components.d.ts +40 -50
- package/dist/components.js +112 -91
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +38 -28
- package/dist/util.js +1 -1
- package/package.json +2 -2
- package/src/lapisApi/lapisApi.ts +1 -1
- package/src/operator/FillMissingOperator.spec.ts +1 -1
- package/src/operator/GroupByAndSumOperator.spec.ts +1 -1
- package/src/operator/GroupByOperator.spec.ts +2 -2
- package/src/operator/MapOperator.spec.ts +1 -1
- package/src/operator/MockOperator.spec.ts +1 -1
- package/src/operator/MockOperator.ts +6 -4
- package/src/operator/SortOperator.spec.ts +1 -1
- package/src/preact/LapisUrlContext.ts +14 -1
- package/src/preact/aggregatedData/aggregate.stories.tsx +4 -4
- package/src/preact/aggregatedData/aggregate.tsx +3 -4
- package/src/preact/components/csv-download-button.stories.tsx +2 -2
- package/src/preact/components/csv-download-button.tsx +1 -1
- package/src/preact/components/error-boundary.stories.tsx +5 -5
- package/src/preact/components/error-boundary.tsx +14 -3
- package/src/preact/components/error-display.stories.tsx +9 -9
- package/src/preact/components/fullscreen.tsx +3 -3
- package/src/preact/components/info.tsx +1 -1
- package/src/preact/components/mutation-type-selector.stories.tsx +1 -1
- package/src/preact/components/table.stories.tsx +3 -3
- package/src/preact/components/table.tsx +1 -1
- package/src/preact/dateRangeSelector/computeInitialValues.spec.ts +34 -20
- package/src/preact/dateRangeSelector/computeInitialValues.ts +25 -21
- package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +107 -46
- package/src/preact/dateRangeSelector/date-range-selector.tsx +31 -22
- package/src/preact/dateRangeSelector/dateRangeOption.ts +11 -1
- package/src/preact/lineageFilter/lineage-filter.stories.tsx +9 -9
- package/src/preact/lineageFilter/lineage-filter.tsx +3 -4
- package/src/preact/locationFilter/fetchAutocompletionList.ts +1 -1
- package/src/preact/locationFilter/location-filter.stories.tsx +9 -9
- package/src/preact/locationFilter/location-filter.tsx +4 -4
- package/src/preact/map/sequences-by-location.stories.tsx +4 -4
- package/src/preact/map/sequences-by-location.tsx +3 -4
- package/src/preact/mutationComparison/mutation-comparison.stories.tsx +3 -3
- package/src/preact/mutationComparison/mutation-comparison.tsx +4 -4
- package/src/preact/mutationFilter/mutation-filter-info.tsx +3 -3
- package/src/preact/mutationFilter/mutation-filter.stories.tsx +7 -7
- package/src/preact/mutations/getMutationsGridData.ts +1 -1
- package/src/preact/mutations/mutations.stories.tsx +3 -3
- package/src/preact/mutations/mutations.tsx +4 -4
- package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +3 -3
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +4 -4
- package/src/preact/mutationsOverTime/mutations-over-time.tsx +5 -4
- package/src/preact/numberSequencesOverTime/number-sequences-over-time.stories.tsx +4 -4
- package/src/preact/numberSequencesOverTime/number-sequences-over-time.tsx +4 -4
- package/src/preact/prevalenceOverTime/prevalence-over-time-bubble-chart.tsx +4 -4
- package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +4 -4
- package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +4 -4
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +4 -4
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +4 -4
- package/src/preact/shared/floating-ui/hooks.ts +1 -1
- package/src/preact/statistic/statistics.stories.tsx +3 -3
- package/src/preact/statistic/statistics.tsx +2 -3
- package/src/preact/textInput/text-input.stories.tsx +7 -7
- package/src/preact/textInput/text-input.tsx +3 -4
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.stories.tsx +3 -3
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +4 -4
- package/src/utils/map2d.ts +1 -0
- package/src/web-components/PreactLitAdapter.tsx +3 -3
- package/src/web-components/gs-app.stories.ts +7 -7
- package/src/web-components/gs-app.ts +3 -1
- package/src/web-components/input/gs-date-range-selector.stories.ts +10 -17
- package/src/web-components/input/gs-date-range-selector.tsx +15 -38
- package/src/web-components/input/gs-lineage-filter.stories.ts +1 -1
- package/src/web-components/input/gs-location-filter.stories.ts +1 -1
- package/src/web-components/input/gs-mutation-filter.stories.ts +7 -7
- package/src/web-components/input/gs-text-input.stories.ts +3 -3
- package/src/web-components/visualization/gs-aggregate.tsx +2 -2
- package/standalone-bundle/assets/mutationOverTimeWorker-CmSrq4SZ.js.map +1 -1
- package/standalone-bundle/dashboard-components.js +6068 -6055
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/dist/LineageFilterChangedEvent-GedKNGFI.js.map +0 -1
|
@@ -6,7 +6,7 @@ import { LineageFilter, type LineageFilterProps } from './lineage-filter';
|
|
|
6
6
|
import { previewHandles } from '../../../.storybook/preview';
|
|
7
7
|
import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
8
8
|
import aggregatedData from '../../preact/lineageFilter/__mockData__/aggregated.json';
|
|
9
|
-
import {
|
|
9
|
+
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
10
10
|
import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
11
11
|
|
|
12
12
|
const meta: Meta = {
|
|
@@ -78,14 +78,14 @@ export default meta;
|
|
|
78
78
|
|
|
79
79
|
export const Default: StoryObj<LineageFilterProps> = {
|
|
80
80
|
render: (args) => (
|
|
81
|
-
<
|
|
81
|
+
<LapisUrlContextProvider value={LAPIS_URL}>
|
|
82
82
|
<LineageFilter {...args} />
|
|
83
|
-
</
|
|
83
|
+
</LapisUrlContextProvider>
|
|
84
84
|
),
|
|
85
85
|
play: async ({ canvasElement, step }) => {
|
|
86
86
|
const { canvas, lineageChangedListenerMock } = await prepare(canvasElement, step);
|
|
87
87
|
|
|
88
|
-
step('change lineage filter value fires event', async () => {
|
|
88
|
+
await step('change lineage filter value fires event', async () => {
|
|
89
89
|
const input = await inputField(canvas);
|
|
90
90
|
await userEvent.clear(input);
|
|
91
91
|
await userEvent.type(input, 'B.1');
|
|
@@ -105,7 +105,7 @@ export const ClearSelection: StoryObj<LineageFilterProps> = {
|
|
|
105
105
|
play: async ({ canvasElement, step }) => {
|
|
106
106
|
const { canvas, lineageChangedListenerMock } = await prepare(canvasElement, step);
|
|
107
107
|
|
|
108
|
-
step('clear selection fires event with empty filter', async () => {
|
|
108
|
+
await step('clear selection fires event with empty filter', async () => {
|
|
109
109
|
const clearSelectionButton = await canvas.findByLabelText('clear selection');
|
|
110
110
|
await userEvent.click(clearSelectionButton);
|
|
111
111
|
|
|
@@ -123,7 +123,7 @@ export const OnBlurInput: StoryObj<LineageFilterProps> = {
|
|
|
123
123
|
play: async ({ canvasElement, step }) => {
|
|
124
124
|
const { canvas, lineageChangedListenerMock } = await prepare(canvasElement, step);
|
|
125
125
|
|
|
126
|
-
step('after cleared selection by hand and then blur fires event with empty filter', async () => {
|
|
126
|
+
await step('after cleared selection by hand and then blur fires event with empty filter', async () => {
|
|
127
127
|
const input = await inputField(canvas);
|
|
128
128
|
await userEvent.clear(input);
|
|
129
129
|
await userEvent.click(canvas.getByLabelText('toggle menu'));
|
|
@@ -144,7 +144,7 @@ export const WithNoLapisField: StoryObj<LineageFilterProps> = {
|
|
|
144
144
|
lapisField: '',
|
|
145
145
|
},
|
|
146
146
|
play: async ({ canvasElement, step }) => {
|
|
147
|
-
step('expect error message', async () => {
|
|
147
|
+
await step('expect error message', async () => {
|
|
148
148
|
await expectInvalidAttributesErrorMessage(canvasElement, 'String must contain at least 1 character(s)');
|
|
149
149
|
});
|
|
150
150
|
},
|
|
@@ -154,11 +154,11 @@ async function prepare(canvasElement: HTMLElement, step: StepFunction<PreactRend
|
|
|
154
154
|
const canvas = within(canvasElement);
|
|
155
155
|
|
|
156
156
|
const lineageChangedListenerMock = fn();
|
|
157
|
-
step('Setup event listener mock', () => {
|
|
157
|
+
await step('Setup event listener mock', () => {
|
|
158
158
|
canvasElement.addEventListener('gs-lineage-filter-changed', lineageChangedListenerMock);
|
|
159
159
|
});
|
|
160
160
|
|
|
161
|
-
step('location filter is rendered with value', async () => {
|
|
161
|
+
await step('location filter is rendered with value', async () => {
|
|
162
162
|
await waitFor(async () => {
|
|
163
163
|
return expect(await inputField(canvas)).toHaveValue('A.1');
|
|
164
164
|
});
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { type FunctionComponent } from 'preact';
|
|
2
|
-
import { useContext } from 'preact/hooks';
|
|
3
2
|
import z from 'zod';
|
|
4
3
|
|
|
5
|
-
import {
|
|
6
|
-
import { LapisUrlContext } from '../LapisUrlContext';
|
|
4
|
+
import { useLapisUrl } from '../LapisUrlContext';
|
|
7
5
|
import { LineageFilterChangedEvent } from './LineageFilterChangedEvent';
|
|
6
|
+
import { fetchLineageAutocompleteList } from './fetchLineageAutocompleteList';
|
|
8
7
|
import { lapisFilterSchema } from '../../types';
|
|
9
8
|
import { DownshiftCombobox } from '../components/downshift-combobox';
|
|
10
9
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
@@ -47,7 +46,7 @@ const LineageFilterInner: FunctionComponent<LineageFilterInnerProps> = ({
|
|
|
47
46
|
value,
|
|
48
47
|
lapisFilter,
|
|
49
48
|
}) => {
|
|
50
|
-
const lapis =
|
|
49
|
+
const lapis = useLapisUrl();
|
|
51
50
|
|
|
52
51
|
const { data, error, isLoading } = useQuery(
|
|
53
52
|
() => fetchLineageAutocompleteList({ lapis, field: lapisField, lapisFilter }),
|
|
@@ -43,7 +43,7 @@ export async function fetchAutocompletionList({
|
|
|
43
43
|
|
|
44
44
|
return [...locationValues]
|
|
45
45
|
.map<EntryWithNullValues>(([json, count]) => ({
|
|
46
|
-
value: JSON.parse(json),
|
|
46
|
+
value: JSON.parse(json) as Record<string, string | null>,
|
|
47
47
|
count,
|
|
48
48
|
}))
|
|
49
49
|
.sort(compareLocationEntries(fields))
|
|
@@ -6,7 +6,7 @@ import data from './__mockData__/aggregated.json';
|
|
|
6
6
|
import { LocationFilter, type LocationFilterProps } from './location-filter';
|
|
7
7
|
import { previewHandles } from '../../../.storybook/preview';
|
|
8
8
|
import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
9
|
-
import {
|
|
9
|
+
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
10
10
|
import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
11
11
|
|
|
12
12
|
const meta: Meta<LocationFilterProps> = {
|
|
@@ -77,14 +77,14 @@ export default meta;
|
|
|
77
77
|
|
|
78
78
|
export const Primary: StoryObj<LocationFilterProps> = {
|
|
79
79
|
render: (args) => (
|
|
80
|
-
<
|
|
80
|
+
<LapisUrlContextProvider value={LAPIS_URL}>
|
|
81
81
|
<LocationFilter {...args} />
|
|
82
|
-
</
|
|
82
|
+
</LapisUrlContextProvider>
|
|
83
83
|
),
|
|
84
84
|
play: async ({ canvasElement, step }) => {
|
|
85
85
|
const { canvas, locationChangedListenerMock } = await prepare(canvasElement, step);
|
|
86
86
|
|
|
87
|
-
step('change location filter value fires event', async () => {
|
|
87
|
+
await step('change location filter value fires event', async () => {
|
|
88
88
|
const input = await inputField(canvas);
|
|
89
89
|
await userEvent.clear(input);
|
|
90
90
|
await userEvent.type(input, 'Germany');
|
|
@@ -107,7 +107,7 @@ export const ClearSelection: StoryObj<LocationFilterProps> = {
|
|
|
107
107
|
play: async ({ canvasElement, step }) => {
|
|
108
108
|
const { canvas, locationChangedListenerMock } = await prepare(canvasElement, step);
|
|
109
109
|
|
|
110
|
-
step('clear selection fires event with empty filter', async () => {
|
|
110
|
+
await step('clear selection fires event with empty filter', async () => {
|
|
111
111
|
const clearSelectionButton = await canvas.findByLabelText('clear selection');
|
|
112
112
|
await userEvent.click(clearSelectionButton);
|
|
113
113
|
|
|
@@ -128,7 +128,7 @@ export const OnBlurInput: StoryObj<LocationFilterProps> = {
|
|
|
128
128
|
play: async ({ canvasElement, step }) => {
|
|
129
129
|
const { canvas, locationChangedListenerMock } = await prepare(canvasElement, step);
|
|
130
130
|
|
|
131
|
-
step('after cleared selection by hand and then blur fires event with empty filter', async () => {
|
|
131
|
+
await step('after cleared selection by hand and then blur fires event with empty filter', async () => {
|
|
132
132
|
const input = await inputField(canvas);
|
|
133
133
|
await userEvent.clear(input);
|
|
134
134
|
await userEvent.click(canvas.getByLabelText('toggle menu'));
|
|
@@ -151,11 +151,11 @@ async function prepare(canvasElement: HTMLElement, step: StepFunction<PreactRend
|
|
|
151
151
|
const canvas = within(canvasElement);
|
|
152
152
|
|
|
153
153
|
const locationChangedListenerMock = fn();
|
|
154
|
-
step('Setup event listener mock', () => {
|
|
154
|
+
await step('Setup event listener mock', () => {
|
|
155
155
|
canvasElement.addEventListener('gs-location-changed', locationChangedListenerMock);
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
-
step('location filter is rendered with value', async () => {
|
|
158
|
+
await step('location filter is rendered with value', async () => {
|
|
159
159
|
await waitFor(async () => {
|
|
160
160
|
return expect(await inputField(canvas)).toHaveValue('Europe');
|
|
161
161
|
});
|
|
@@ -171,7 +171,7 @@ export const WithNoFields: StoryObj<LocationFilterProps> = {
|
|
|
171
171
|
fields: [],
|
|
172
172
|
},
|
|
173
173
|
play: async ({ canvasElement, step }) => {
|
|
174
|
-
step('expect error message', async () => {
|
|
174
|
+
await step('expect error message', async () => {
|
|
175
175
|
await expectInvalidAttributesErrorMessage(canvasElement, 'Array must contain at least 1 element(s)');
|
|
176
176
|
});
|
|
177
177
|
},
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type FunctionComponent } from 'preact';
|
|
2
|
-
import {
|
|
2
|
+
import { useMemo } from 'preact/hooks';
|
|
3
3
|
import z from 'zod';
|
|
4
4
|
|
|
5
|
-
import { fetchAutocompletionList, type LocationEntry } from './fetchAutocompletionList';
|
|
6
|
-
import { LapisUrlContext } from '../LapisUrlContext';
|
|
7
5
|
import { LocationChangedEvent } from './LocationChangedEvent';
|
|
6
|
+
import { fetchAutocompletionList, type LocationEntry } from './fetchAutocompletionList';
|
|
8
7
|
import { lapisFilterSchema, type LapisLocationFilter, lapisLocationFilterSchema } from '../../types';
|
|
8
|
+
import { useLapisUrl } from '../LapisUrlContext';
|
|
9
9
|
import { DownshiftCombobox } from '../components/downshift-combobox';
|
|
10
10
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
11
11
|
import { LoadingDisplay } from '../components/loading-display';
|
|
@@ -40,7 +40,7 @@ export const LocationFilter: FunctionComponent<LocationFilterProps> = (props) =>
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
export const LocationFilterInner = ({ value, fields, placeholderText, lapisFilter }: LocationFilterInnerProps) => {
|
|
43
|
-
const lapis =
|
|
43
|
+
const lapis = useLapisUrl();
|
|
44
44
|
|
|
45
45
|
const { data, error, isLoading } = useQuery(
|
|
46
46
|
() => fetchAutocompletionList({ fields, lapis, lapisFilter }),
|
|
@@ -2,7 +2,7 @@ import { type Meta, type StoryObj } from '@storybook/preact';
|
|
|
2
2
|
|
|
3
3
|
import worldAtlas from './__mockData__/worldAtlas.json';
|
|
4
4
|
import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
5
|
-
import {
|
|
5
|
+
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
6
6
|
import aggregatedWorld from './__mockData__/aggregatedWorld.json';
|
|
7
7
|
import { SequencesByLocation, type SequencesByLocationProps } from './sequences-by-location';
|
|
8
8
|
import { expectInvalidAttributesErrorMessage, playThatExpectsErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
@@ -37,9 +37,9 @@ const aggregatedWorldMatcher = {
|
|
|
37
37
|
|
|
38
38
|
export const Default: StoryObj<SequencesByLocationProps> = {
|
|
39
39
|
render: (args) => (
|
|
40
|
-
<
|
|
40
|
+
<LapisUrlContextProvider value={LAPIS_URL}>
|
|
41
41
|
<SequencesByLocation {...args} />
|
|
42
|
-
</
|
|
42
|
+
</LapisUrlContextProvider>
|
|
43
43
|
),
|
|
44
44
|
args: {
|
|
45
45
|
lapisFilter: { dateFrom: '2022-01-01', dateTo: '2022-04-01' },
|
|
@@ -134,7 +134,7 @@ export const InvalidProps: StoryObj<SequencesByLocationProps> = {
|
|
|
134
134
|
lapisLocationField: '',
|
|
135
135
|
},
|
|
136
136
|
play: async ({ canvasElement, step }) => {
|
|
137
|
-
step('expect error message', async () => {
|
|
137
|
+
await step('expect error message', async () => {
|
|
138
138
|
await expectInvalidAttributesErrorMessage(
|
|
139
139
|
canvasElement,
|
|
140
140
|
'"lapisLocationField": String must contain at least 1 character(s)',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { FunctionComponent } from 'preact';
|
|
2
|
-
import { useContext } from 'preact/hooks';
|
|
3
2
|
import z from 'zod';
|
|
4
3
|
|
|
4
|
+
import { useLapisUrl } from '../LapisUrlContext';
|
|
5
5
|
import { SequencesByLocationMap } from './sequences-by-location-map';
|
|
6
6
|
import { SequencesByLocationTable } from './sequences-by-location-table';
|
|
7
7
|
import {
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
} from '../../query/computeMapLocationData';
|
|
12
12
|
import { type AggregateData } from '../../query/queryAggregateData';
|
|
13
13
|
import { querySequencesByLocationData } from '../../query/querySequencesByLocationData';
|
|
14
|
-
import { LapisUrlContext } from '../LapisUrlContext';
|
|
15
14
|
import { CsvDownloadButton } from '../components/csv-download-button';
|
|
16
15
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
17
16
|
import { Fullscreen } from '../components/fullscreen';
|
|
@@ -58,7 +57,7 @@ export const SequencesByLocation: FunctionComponent<SequencesByLocationProps> =
|
|
|
58
57
|
const SequencesByLocationMapInner: FunctionComponent<SequencesByLocationProps> = (props) => {
|
|
59
58
|
const { lapisFilter, lapisLocationField, mapSource } = props;
|
|
60
59
|
|
|
61
|
-
const lapis =
|
|
60
|
+
const lapis = useLapisUrl();
|
|
62
61
|
const {
|
|
63
62
|
data,
|
|
64
63
|
error,
|
|
@@ -158,7 +157,7 @@ type SequencesByLocationMapInfoProps = {
|
|
|
158
157
|
};
|
|
159
158
|
|
|
160
159
|
const SequencesByLocationMapInfo: FunctionComponent<SequencesByLocationMapInfoProps> = ({ originalComponentProps }) => {
|
|
161
|
-
const lapis =
|
|
160
|
+
const lapis = useLapisUrl();
|
|
162
161
|
return (
|
|
163
162
|
<Info>
|
|
164
163
|
<InfoHeadline1>Prevalence by location</InfoHeadline1>
|
|
@@ -6,7 +6,7 @@ import nucleotideMutationsSomeDataset from './__mockData__/nucleotideMutationsSo
|
|
|
6
6
|
import { MutationComparison, type MutationComparisonProps } from './mutation-comparison';
|
|
7
7
|
import { LAPIS_URL, NUCLEOTIDE_MUTATIONS_ENDPOINT } from '../../constants';
|
|
8
8
|
import referenceGenome from '../../lapisApi/__mockData__/referenceGenome.json';
|
|
9
|
-
import {
|
|
9
|
+
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
10
10
|
import { ReferenceGenomeContext } from '../ReferenceGenomeContext';
|
|
11
11
|
|
|
12
12
|
const dateToSomeDataset = '2022-01-01';
|
|
@@ -76,7 +76,7 @@ export default meta;
|
|
|
76
76
|
|
|
77
77
|
const Template: StoryObj<MutationComparisonProps> = {
|
|
78
78
|
render: (args) => (
|
|
79
|
-
<
|
|
79
|
+
<LapisUrlContextProvider value={LAPIS_URL}>
|
|
80
80
|
<ReferenceGenomeContext.Provider value={referenceGenome}>
|
|
81
81
|
<MutationComparison
|
|
82
82
|
lapisFilters={args.lapisFilters}
|
|
@@ -87,7 +87,7 @@ const Template: StoryObj<MutationComparisonProps> = {
|
|
|
87
87
|
pageSize={args.pageSize}
|
|
88
88
|
/>
|
|
89
89
|
</ReferenceGenomeContext.Provider>
|
|
90
|
-
</
|
|
90
|
+
</LapisUrlContextProvider>
|
|
91
91
|
),
|
|
92
92
|
};
|
|
93
93
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type FunctionComponent } from 'preact';
|
|
2
|
-
import { type Dispatch, type StateUpdater,
|
|
2
|
+
import { type Dispatch, type StateUpdater, useMemo, useState } from 'preact/hooks';
|
|
3
3
|
import z from 'zod';
|
|
4
4
|
|
|
5
5
|
import { getMutationComparisonTableData } from './getMutationComparisonTableData';
|
|
@@ -7,7 +7,7 @@ import { MutationComparisonTable } from './mutation-comparison-table';
|
|
|
7
7
|
import { MutationComparisonVenn } from './mutation-comparison-venn';
|
|
8
8
|
import { filterMutationData, type MutationData, queryMutationData } from './queryMutationData';
|
|
9
9
|
import { namedLapisFilterSchema, sequenceTypeSchema, views } from '../../types';
|
|
10
|
-
import {
|
|
10
|
+
import { useLapisUrl } from '../LapisUrlContext';
|
|
11
11
|
import { CsvDownloadButton } from '../components/csv-download-button';
|
|
12
12
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
13
13
|
import { Fullscreen } from '../components/fullscreen';
|
|
@@ -52,7 +52,7 @@ export const MutationComparison: FunctionComponent<MutationComparisonProps> = (c
|
|
|
52
52
|
|
|
53
53
|
const MutationComparisonInner: FunctionComponent<MutationComparisonProps> = (componentProps) => {
|
|
54
54
|
const { lapisFilters, sequenceType } = componentProps;
|
|
55
|
-
const lapis =
|
|
55
|
+
const lapis = useLapisUrl();
|
|
56
56
|
|
|
57
57
|
const { data, error, isLoading } = useQuery(async () => {
|
|
58
58
|
return queryMutationData(lapisFilters, sequenceType, lapis);
|
|
@@ -187,7 +187,7 @@ type MutationComparisonInfoProps = {
|
|
|
187
187
|
};
|
|
188
188
|
|
|
189
189
|
const MutationComparisonInfo: FunctionComponent<MutationComparisonInfoProps> = ({ originalComponentProps }) => {
|
|
190
|
-
const lapis =
|
|
190
|
+
const lapis = useLapisUrl();
|
|
191
191
|
return (
|
|
192
192
|
<Info>
|
|
193
193
|
<InfoHeadline1>Info for mutation comparison</InfoHeadline1>
|
|
@@ -55,13 +55,13 @@ const QuickStart = () => {
|
|
|
55
55
|
)}
|
|
56
56
|
</ul>
|
|
57
57
|
</InfoParagraph>
|
|
58
|
-
|
|
59
|
-
{referenceGenome.nucleotideSequences.length > 1 ? (
|
|
58
|
+
{referenceGenome.nucleotideSequences.length > 1 && (
|
|
60
59
|
<InfoParagraph>
|
|
61
60
|
This organism has the following segments:{' '}
|
|
62
61
|
{referenceGenome.nucleotideSequences.map((gene) => gene.name).join(', ')}.
|
|
63
62
|
</InfoParagraph>
|
|
64
|
-
)
|
|
63
|
+
)}
|
|
64
|
+
{referenceGenome.nucleotideSequences.length === 0 && (
|
|
65
65
|
<InfoParagraph>This organism doesn't support nucleotide sequences.</InfoParagraph>
|
|
66
66
|
)}
|
|
67
67
|
{referenceGenome.genes.length !== 0 ? (
|
|
@@ -6,7 +6,7 @@ import { MutationFilter, type MutationFilterProps } from './mutation-filter';
|
|
|
6
6
|
import { previewHandles } from '../../../.storybook/preview';
|
|
7
7
|
import { LAPIS_URL } from '../../constants';
|
|
8
8
|
import referenceGenome from '../../lapisApi/__mockData__/referenceGenome.json';
|
|
9
|
-
import {
|
|
9
|
+
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
10
10
|
import { ReferenceGenomeContext } from '../ReferenceGenomeContext';
|
|
11
11
|
|
|
12
12
|
const meta: Meta<MutationFilterProps> = {
|
|
@@ -32,11 +32,11 @@ export default meta;
|
|
|
32
32
|
|
|
33
33
|
export const Default: StoryObj<MutationFilterProps> = {
|
|
34
34
|
render: (args) => (
|
|
35
|
-
<
|
|
35
|
+
<LapisUrlContextProvider value={LAPIS_URL}>
|
|
36
36
|
<ReferenceGenomeContext.Provider value={referenceGenome}>
|
|
37
37
|
<MutationFilter width={args.width} initialValue={args.initialValue} />
|
|
38
38
|
</ReferenceGenomeContext.Provider>
|
|
39
|
-
</
|
|
39
|
+
</LapisUrlContextProvider>
|
|
40
40
|
),
|
|
41
41
|
args: {
|
|
42
42
|
width: '100%',
|
|
@@ -184,11 +184,11 @@ export const FiresFilterChangedEvents: StoryObj<MutationFilterProps> = {
|
|
|
184
184
|
|
|
185
185
|
export const WithInitialValue: StoryObj<MutationFilterProps> = {
|
|
186
186
|
render: (args) => (
|
|
187
|
-
<
|
|
187
|
+
<LapisUrlContextProvider value={LAPIS_URL}>
|
|
188
188
|
<ReferenceGenomeContext.Provider value={referenceGenome}>
|
|
189
189
|
<MutationFilter initialValue={args.initialValue} width={args.width} />
|
|
190
190
|
</ReferenceGenomeContext.Provider>
|
|
191
|
-
</
|
|
191
|
+
</LapisUrlContextProvider>
|
|
192
192
|
),
|
|
193
193
|
args: {
|
|
194
194
|
initialValue: {
|
|
@@ -223,7 +223,7 @@ async function prepare(canvasElement: HTMLElement, step: StepFunction<PreactRend
|
|
|
223
223
|
const canvas = within(canvasElement);
|
|
224
224
|
|
|
225
225
|
const changedListenerMock = fn();
|
|
226
|
-
await step('Setup event listener mock',
|
|
226
|
+
await step('Setup event listener mock', () => {
|
|
227
227
|
canvasElement.addEventListener('gs-mutation-filter-changed', changedListenerMock);
|
|
228
228
|
});
|
|
229
229
|
|
|
@@ -265,5 +265,5 @@ const testNoOptionsExist = async (canvas: ReturnType<typeof within>, mutation: s
|
|
|
265
265
|
await expect(options).toHaveLength(0);
|
|
266
266
|
};
|
|
267
267
|
|
|
268
|
-
const inputField = (canvas: ReturnType<typeof within>) =>
|
|
268
|
+
const inputField = (canvas: ReturnType<typeof within>): HTMLElement =>
|
|
269
269
|
canvas.getByPlaceholderText('Enter a mutation', { exact: false });
|
|
@@ -25,7 +25,7 @@ const accumulateByPosition = (data: SubstitutionOrDeletionEntry[], sequenceType:
|
|
|
25
25
|
|
|
26
26
|
const initiallyFillPositionsToProportionAtBase = () => {
|
|
27
27
|
if (!positionsToProportionAtBase.has(position)) {
|
|
28
|
-
const empty = new Map();
|
|
28
|
+
const empty = new Map<string | undefined, number>();
|
|
29
29
|
basesOfView.forEach((base) => empty.set(base, 0));
|
|
30
30
|
empty.set(mutationEntry.mutation.valueAtReference, 1);
|
|
31
31
|
positionsToProportionAtBase.set(position, empty);
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import referenceGenome from '../../lapisApi/__mockData__/referenceGenome.json';
|
|
14
14
|
import baselineNucleotideMutations from '../../preact/mutations/__mockData__/baselineNucleotideMutations.json';
|
|
15
15
|
import overallVariantCount from '../../preact/mutations/__mockData__/overallVariantCount.json';
|
|
16
|
-
import {
|
|
16
|
+
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
17
17
|
import { ReferenceGenomeContext } from '../ReferenceGenomeContext';
|
|
18
18
|
|
|
19
19
|
const meta: Meta<MutationsProps> = {
|
|
@@ -39,11 +39,11 @@ export default meta;
|
|
|
39
39
|
|
|
40
40
|
const Template = {
|
|
41
41
|
render: (args: MutationsProps) => (
|
|
42
|
-
<
|
|
42
|
+
<LapisUrlContextProvider value={LAPIS_URL}>
|
|
43
43
|
<ReferenceGenomeContext.Provider value={referenceGenome}>
|
|
44
44
|
<Mutations {...args} />
|
|
45
45
|
</ReferenceGenomeContext.Provider>
|
|
46
|
-
</
|
|
46
|
+
</LapisUrlContextProvider>
|
|
47
47
|
),
|
|
48
48
|
};
|
|
49
49
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type FunctionComponent } from 'preact';
|
|
2
|
-
import { type Dispatch, type StateUpdater,
|
|
2
|
+
import { type Dispatch, type StateUpdater, useState } from 'preact/hooks';
|
|
3
3
|
import z from 'zod';
|
|
4
4
|
|
|
5
5
|
import { getInsertionsTableData } from './getInsertionsTableData';
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
type SubstitutionOrDeletionEntry,
|
|
16
16
|
views,
|
|
17
17
|
} from '../../types';
|
|
18
|
-
import {
|
|
18
|
+
import { useLapisUrl } from '../LapisUrlContext';
|
|
19
19
|
import { CsvDownloadButton } from '../components/csv-download-button';
|
|
20
20
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
21
21
|
import { Fullscreen } from '../components/fullscreen';
|
|
@@ -59,7 +59,7 @@ export const Mutations: FunctionComponent<MutationsProps> = (componentProps) =>
|
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
export const MutationsInner: FunctionComponent<MutationsProps> = (componentProps) => {
|
|
62
|
-
const lapis =
|
|
62
|
+
const lapis = useLapisUrl();
|
|
63
63
|
const { lapisFilter, baselineLapisFilter, sequenceType } = componentProps;
|
|
64
64
|
|
|
65
65
|
const { data, error, isLoading } = useQuery(async () => {
|
|
@@ -237,7 +237,7 @@ type MutationsInfoProps = {
|
|
|
237
237
|
};
|
|
238
238
|
|
|
239
239
|
const MutationsInfo: FunctionComponent<MutationsInfoProps> = ({ originalComponentProps }) => {
|
|
240
|
-
const lapis =
|
|
240
|
+
const lapis = useLapisUrl();
|
|
241
241
|
|
|
242
242
|
return (
|
|
243
243
|
<Info>
|
|
@@ -62,9 +62,9 @@ const MutationsOverTimeGrid: FunctionComponent<MutationsOverTimeGridProps> = ({
|
|
|
62
62
|
))}
|
|
63
63
|
{shownMutations.map((mutation, rowIndex) => {
|
|
64
64
|
return (
|
|
65
|
-
<Fragment key={`fragment-${mutation.
|
|
65
|
+
<Fragment key={`fragment-${mutation.code}`}>
|
|
66
66
|
<div
|
|
67
|
-
key={`mutation-${mutation.
|
|
67
|
+
key={`mutation-${mutation.code}`}
|
|
68
68
|
style={{ gridRowStart: rowIndex + 2, gridColumnStart: 1 }}
|
|
69
69
|
>
|
|
70
70
|
<MutationCell mutation={mutation} />
|
|
@@ -80,7 +80,7 @@ const MutationsOverTimeGrid: FunctionComponent<MutationsOverTimeGridProps> = ({
|
|
|
80
80
|
return (
|
|
81
81
|
<div
|
|
82
82
|
style={{ gridRowStart: rowIndex + 2, gridColumnStart: columnIndex + 2 }}
|
|
83
|
-
key={`${mutation.
|
|
83
|
+
key={`${mutation.code}-${date.dateString}`}
|
|
84
84
|
>
|
|
85
85
|
<ProportionCell
|
|
86
86
|
value={value}
|
|
@@ -4,7 +4,7 @@ import { expect, userEvent, waitFor } from '@storybook/test';
|
|
|
4
4
|
import { MutationsOverTime, type MutationsOverTimeProps } from './mutations-over-time';
|
|
5
5
|
import { LAPIS_URL } from '../../constants';
|
|
6
6
|
import referenceGenome from '../../lapisApi/__mockData__/referenceGenome.json';
|
|
7
|
-
import {
|
|
7
|
+
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
8
8
|
import { ReferenceGenomeContext } from '../ReferenceGenomeContext';
|
|
9
9
|
import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
10
10
|
|
|
@@ -38,7 +38,7 @@ export default meta;
|
|
|
38
38
|
|
|
39
39
|
const Template = {
|
|
40
40
|
render: (args: MutationsOverTimeProps) => (
|
|
41
|
-
<
|
|
41
|
+
<LapisUrlContextProvider value={LAPIS_URL}>
|
|
42
42
|
<ReferenceGenomeContext.Provider value={referenceGenome}>
|
|
43
43
|
<MutationsOverTime
|
|
44
44
|
lapisFilter={args.lapisFilter}
|
|
@@ -50,7 +50,7 @@ const Template = {
|
|
|
50
50
|
lapisDateField={args.lapisDateField}
|
|
51
51
|
/>
|
|
52
52
|
</ReferenceGenomeContext.Provider>
|
|
53
|
-
</
|
|
53
|
+
</LapisUrlContextProvider>
|
|
54
54
|
),
|
|
55
55
|
};
|
|
56
56
|
|
|
@@ -164,7 +164,7 @@ export const WithNoLapisDateFieldField: StoryObj<MutationsOverTimeProps> = {
|
|
|
164
164
|
lapisDateField: '',
|
|
165
165
|
},
|
|
166
166
|
play: async ({ canvasElement, step }) => {
|
|
167
|
-
step('expect error message', async () => {
|
|
167
|
+
await step('expect error message', async () => {
|
|
168
168
|
await expectInvalidAttributesErrorMessage(canvasElement, 'String must contain at least 1 character(s)');
|
|
169
169
|
});
|
|
170
170
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type FunctionComponent } from 'preact';
|
|
2
|
-
import { type Dispatch, type StateUpdater,
|
|
2
|
+
import { type Dispatch, type StateUpdater, useMemo, useState } from 'preact/hooks';
|
|
3
3
|
import z from 'zod';
|
|
4
4
|
|
|
5
5
|
// @ts-expect-error -- uses subpath imports and vite worker import
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
} from '../../types';
|
|
19
19
|
import { type Deletion, type Substitution } from '../../utils/mutations';
|
|
20
20
|
import { toTemporalClass } from '../../utils/temporalClass';
|
|
21
|
-
import {
|
|
21
|
+
import { useLapisUrl } from '../LapisUrlContext';
|
|
22
22
|
import { type ColorScale } from '../components/color-scale-selector';
|
|
23
23
|
import { ColorScaleSelectorDropdown } from '../components/color-scale-selector-dropdown';
|
|
24
24
|
import { CsvDownloadButton } from '../components/csv-download-button';
|
|
@@ -63,7 +63,7 @@ export const MutationsOverTime: FunctionComponent<MutationsOverTimeProps> = (com
|
|
|
63
63
|
};
|
|
64
64
|
|
|
65
65
|
export const MutationsOverTimeInner: FunctionComponent<MutationsOverTimeProps> = (componentProps) => {
|
|
66
|
-
const lapis =
|
|
66
|
+
const lapis = useLapisUrl();
|
|
67
67
|
const { lapisFilter, sequenceType, granularity, lapisDateField } = componentProps;
|
|
68
68
|
|
|
69
69
|
const messageToWorker = useMemo(() => {
|
|
@@ -78,6 +78,7 @@ export const MutationsOverTimeInner: FunctionComponent<MutationsOverTimeProps> =
|
|
|
78
78
|
|
|
79
79
|
const { data, error, isLoading } = useWebWorker<MutationOverTimeQuery, MutationOverTimeWorkerResponse>(
|
|
80
80
|
messageToWorker,
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
81
82
|
MutationOverTimeWorker,
|
|
82
83
|
);
|
|
83
84
|
|
|
@@ -230,7 +231,7 @@ type MutationsOverTimeInfoProps = {
|
|
|
230
231
|
};
|
|
231
232
|
|
|
232
233
|
const MutationsOverTimeInfo: FunctionComponent<MutationsOverTimeInfoProps> = ({ originalComponentProps }) => {
|
|
233
|
-
const lapis =
|
|
234
|
+
const lapis = useLapisUrl();
|
|
234
235
|
return (
|
|
235
236
|
<Info>
|
|
236
237
|
<InfoHeadline1>Mutations over time</InfoHeadline1>
|
|
@@ -5,7 +5,7 @@ import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
|
5
5
|
import oneVariantEG from '../../preact/numberSequencesOverTime/__mockData__/oneVariantEG.json';
|
|
6
6
|
import twoVariantsEG from '../../preact/numberSequencesOverTime/__mockData__/twoVariantsEG.json';
|
|
7
7
|
import twoVariantsJN1 from '../../preact/numberSequencesOverTime/__mockData__/twoVariantsJN1.json';
|
|
8
|
-
import {
|
|
8
|
+
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
9
9
|
import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
10
10
|
|
|
11
11
|
export default {
|
|
@@ -29,9 +29,9 @@ export default {
|
|
|
29
29
|
|
|
30
30
|
const Template: StoryObj<NumberSequencesOverTimeProps> = {
|
|
31
31
|
render: (args) => (
|
|
32
|
-
<
|
|
32
|
+
<LapisUrlContextProvider value={LAPIS_URL}>
|
|
33
33
|
<NumberSequencesOverTime {...args} />
|
|
34
|
-
</
|
|
34
|
+
</LapisUrlContextProvider>
|
|
35
35
|
),
|
|
36
36
|
args: {
|
|
37
37
|
views: ['bar', 'line', 'table'],
|
|
@@ -129,7 +129,7 @@ export const WithNoLapisDateField: StoryObj<NumberSequencesOverTimeProps> = {
|
|
|
129
129
|
lapisDateField: '',
|
|
130
130
|
},
|
|
131
131
|
play: async ({ canvasElement, step }) => {
|
|
132
|
-
step('expect error message', async () => {
|
|
132
|
+
await step('expect error message', async () => {
|
|
133
133
|
await expectInvalidAttributesErrorMessage(canvasElement, 'String must contain at least 1 character(s)');
|
|
134
134
|
});
|
|
135
135
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type FunctionComponent } from 'preact';
|
|
2
|
-
import {
|
|
2
|
+
import { useState } from 'preact/hooks';
|
|
3
3
|
import z from 'zod';
|
|
4
4
|
|
|
5
5
|
import { getNumberOfSequencesOverTimeTableData } from './getNumberOfSequencesOverTimeTableData';
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
queryNumberOfSequencesOverTime,
|
|
12
12
|
} from '../../query/queryNumberOfSequencesOverTime';
|
|
13
13
|
import { namedLapisFilterSchema, temporalGranularitySchema, views } from '../../types';
|
|
14
|
-
import {
|
|
14
|
+
import { useLapisUrl } from '../LapisUrlContext';
|
|
15
15
|
import { CsvDownloadButton } from '../components/csv-download-button';
|
|
16
16
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
17
17
|
import { Fullscreen } from '../components/fullscreen';
|
|
@@ -59,7 +59,7 @@ export const NumberSequencesOverTime = (componentProps: NumberSequencesOverTimeP
|
|
|
59
59
|
|
|
60
60
|
const NumberSequencesOverTimeInner = (componentProps: NumberSequencesOverTimeProps) => {
|
|
61
61
|
const { lapisFilters, lapisDateField, granularity, smoothingWindow } = componentProps;
|
|
62
|
-
const lapis =
|
|
62
|
+
const lapis = useLapisUrl();
|
|
63
63
|
|
|
64
64
|
const { data, error, isLoading } = useQuery(
|
|
65
65
|
() => queryNumberOfSequencesOverTime(lapis, lapisFilters, lapisDateField, granularity, smoothingWindow),
|
|
@@ -169,7 +169,7 @@ type NumberSequencesOverTimeInfoProps = {
|
|
|
169
169
|
const NumberSequencesOverTimeInfo: FunctionComponent<NumberSequencesOverTimeInfoProps> = ({
|
|
170
170
|
originalComponentProps,
|
|
171
171
|
}) => {
|
|
172
|
-
const lapis =
|
|
172
|
+
const lapis = useLapisUrl();
|
|
173
173
|
|
|
174
174
|
return (
|
|
175
175
|
<Info>
|
|
@@ -87,13 +87,13 @@ const PrevalenceOverTimeBubbleChart = ({
|
|
|
87
87
|
intersect: false,
|
|
88
88
|
callbacks: {
|
|
89
89
|
title: (context) => {
|
|
90
|
-
const dataset = nonNullDateRangeData[context[0].datasetIndex
|
|
91
|
-
const dataPoint = dataset.content[context[0].dataIndex
|
|
90
|
+
const dataset = nonNullDateRangeData[context[0].datasetIndex];
|
|
91
|
+
const dataPoint = dataset.content[context[0].dataIndex];
|
|
92
92
|
return dataPoint.dateRange?.toString();
|
|
93
93
|
},
|
|
94
94
|
label: (context) => {
|
|
95
|
-
const dataset = nonNullDateRangeData[context.datasetIndex
|
|
96
|
-
const dataPoint = dataset.content[context.dataIndex
|
|
95
|
+
const dataset = nonNullDateRangeData[context.datasetIndex];
|
|
96
|
+
const dataPoint = dataset.content[context.dataIndex];
|
|
97
97
|
|
|
98
98
|
const percentage = (dataPoint.prevalence * 100).toFixed(2);
|
|
99
99
|
const count = dataPoint.count.toFixed(0);
|