@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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { StoryObj } from '@storybook/preact';
|
|
2
2
|
import { expect, waitFor } from '@storybook/test';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
5
5
|
import denominatorFilter from './__mockData__/denominatorFilter.json';
|
|
6
6
|
import denominatorOneDataset from './__mockData__/denominatorFilterOneDataset.json';
|
|
7
7
|
import numeratorFilterEG from './__mockData__/numeratorFilterEG.json';
|
|
@@ -42,9 +42,9 @@ export default {
|
|
|
42
42
|
|
|
43
43
|
const Template = {
|
|
44
44
|
render: (args: PrevalenceOverTimeProps) => (
|
|
45
|
-
<
|
|
45
|
+
<LapisUrlContextProvider value={LAPIS_URL}>
|
|
46
46
|
<PrevalenceOverTime {...args} />
|
|
47
|
-
</
|
|
47
|
+
</LapisUrlContextProvider>
|
|
48
48
|
),
|
|
49
49
|
};
|
|
50
50
|
|
|
@@ -254,7 +254,7 @@ export const WithNoLapisDateField: StoryObj<PrevalenceOverTimeProps> = {
|
|
|
254
254
|
lapisDateField: '',
|
|
255
255
|
},
|
|
256
256
|
play: async ({ canvasElement, step }) => {
|
|
257
|
-
step('expect error message', async () => {
|
|
257
|
+
await step('expect error message', async () => {
|
|
258
258
|
await expectInvalidAttributesErrorMessage(canvasElement, 'String must contain at least 1 character(s)');
|
|
259
259
|
});
|
|
260
260
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type FunctionComponent } from 'preact';
|
|
2
|
-
import {
|
|
2
|
+
import { useEffect, useState } from 'preact/hooks';
|
|
3
3
|
import z from 'zod';
|
|
4
4
|
|
|
5
5
|
import { getPrevalenceOverTimeTableData } from './getPrevalenceOverTimeTableData';
|
|
@@ -9,7 +9,7 @@ import PrevalenceOverTimeLineChart from './prevalence-over-time-line-chart';
|
|
|
9
9
|
import PrevalenceOverTimeTable from './prevalence-over-time-table';
|
|
10
10
|
import { type PrevalenceOverTimeData, queryPrevalenceOverTime } from '../../query/queryPrevalenceOverTime';
|
|
11
11
|
import { lapisFilterSchema, namedLapisFilterSchema, temporalGranularitySchema, views } from '../../types';
|
|
12
|
-
import {
|
|
12
|
+
import { useLapisUrl } from '../LapisUrlContext';
|
|
13
13
|
import { ConfidenceIntervalSelector } from '../components/confidence-interval-selector';
|
|
14
14
|
import { CsvDownloadButton } from '../components/csv-download-button';
|
|
15
15
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
@@ -65,7 +65,7 @@ export const PrevalenceOverTime: FunctionComponent<PrevalenceOverTimeProps> = (c
|
|
|
65
65
|
|
|
66
66
|
export const PrevalenceOverTimeInner: FunctionComponent<PrevalenceOverTimeProps> = (componentProps) => {
|
|
67
67
|
const { numeratorFilters, denominatorFilter, granularity, smoothingWindow, lapisDateField } = componentProps;
|
|
68
|
-
const lapis =
|
|
68
|
+
const lapis = useLapisUrl();
|
|
69
69
|
|
|
70
70
|
const { data, error, isLoading } = useQuery(
|
|
71
71
|
() =>
|
|
@@ -226,7 +226,7 @@ const Toolbar: FunctionComponent<ToolbarProps> = ({
|
|
|
226
226
|
|
|
227
227
|
const PrevalenceOverTimeInfo: FunctionComponent<PrevalenceOverTimeProps> = (componentProps) => {
|
|
228
228
|
const { granularity, smoothingWindow, views } = componentProps;
|
|
229
|
-
const lapis =
|
|
229
|
+
const lapis = useLapisUrl();
|
|
230
230
|
return (
|
|
231
231
|
<Info>
|
|
232
232
|
<InfoHeadline1>Prevalence over time</InfoHeadline1>
|
|
@@ -5,7 +5,7 @@ import denominator from './__mockData__/denominatorFilter.json';
|
|
|
5
5
|
import numerator from './__mockData__/numeratorFilter.json';
|
|
6
6
|
import { RelativeGrowthAdvantage, type RelativeGrowthAdvantageProps } from './relative-growth-advantage';
|
|
7
7
|
import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
8
|
-
import {
|
|
8
|
+
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
9
9
|
import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
10
10
|
|
|
11
11
|
export default {
|
|
@@ -30,9 +30,9 @@ export default {
|
|
|
30
30
|
|
|
31
31
|
export const Primary: StoryObj<RelativeGrowthAdvantageProps> = {
|
|
32
32
|
render: (args: RelativeGrowthAdvantageProps) => (
|
|
33
|
-
<
|
|
33
|
+
<LapisUrlContextProvider value={LAPIS_URL}>
|
|
34
34
|
<RelativeGrowthAdvantage {...args} />
|
|
35
|
-
</
|
|
35
|
+
</LapisUrlContextProvider>
|
|
36
36
|
),
|
|
37
37
|
args: {
|
|
38
38
|
numeratorFilter: {
|
|
@@ -188,7 +188,7 @@ export const WithNoLapisDateField: StoryObj<RelativeGrowthAdvantageProps> = {
|
|
|
188
188
|
lapisDateField: '',
|
|
189
189
|
},
|
|
190
190
|
play: async ({ canvasElement, step }) => {
|
|
191
|
-
step('expect error message', async () => {
|
|
191
|
+
await step('expect error message', async () => {
|
|
192
192
|
await expectInvalidAttributesErrorMessage(canvasElement, 'String must contain at least 1 character(s)');
|
|
193
193
|
});
|
|
194
194
|
},
|
|
@@ -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 RelativeGrowthAdvantageChart from './relative-growth-advantage-chart';
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
type RelativeGrowthAdvantageData,
|
|
10
10
|
} from '../../query/queryRelativeGrowthAdvantage';
|
|
11
11
|
import { lapisFilterSchema, views } from '../../types';
|
|
12
|
-
import {
|
|
12
|
+
import { useLapisUrl } from '../LapisUrlContext';
|
|
13
13
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
14
14
|
import { Fullscreen } from '../components/fullscreen';
|
|
15
15
|
import Info, { InfoComponentCode, InfoHeadline1, InfoHeadline2, InfoLink, InfoParagraph } from '../components/info';
|
|
@@ -52,7 +52,7 @@ export const RelativeGrowthAdvantage: FunctionComponent<RelativeGrowthAdvantageP
|
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
export const RelativeGrowthAdvantageInner: FunctionComponent<RelativeGrowthAdvantageProps> = (componentProps) => {
|
|
55
|
-
const lapis =
|
|
55
|
+
const lapis = useLapisUrl();
|
|
56
56
|
const { numeratorFilter, denominatorFilter, generationTime, lapisDateField } = componentProps;
|
|
57
57
|
|
|
58
58
|
const [yAxisScaleType, setYAxisScaleType] = useState<ScaleType>('linear');
|
|
@@ -160,7 +160,7 @@ const RelativeGrowthAdvantageToolbar: FunctionComponent<RelativeGrowthAdvantageT
|
|
|
160
160
|
const RelativeGrowthAdvantageInfo: FunctionComponent<{ originalComponentProps: RelativeGrowthAdvantageProps }> = ({
|
|
161
161
|
originalComponentProps,
|
|
162
162
|
}) => {
|
|
163
|
-
const lapis =
|
|
163
|
+
const lapis = useLapisUrl();
|
|
164
164
|
const generationTime = originalComponentProps.generationTime;
|
|
165
165
|
|
|
166
166
|
return (
|
|
@@ -2,7 +2,7 @@ import { type Meta, type StoryObj } from '@storybook/preact';
|
|
|
2
2
|
import { expect, waitFor, within } from '@storybook/test';
|
|
3
3
|
|
|
4
4
|
import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
5
|
-
import {
|
|
5
|
+
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
6
6
|
import denominatorData from './__mockData__/denominator.json';
|
|
7
7
|
import numeratorData from './__mockData__/numerator.json';
|
|
8
8
|
import { Statistics, type StatisticsProps } from './statistics';
|
|
@@ -55,9 +55,9 @@ export default meta;
|
|
|
55
55
|
|
|
56
56
|
export const Default: StoryObj<StatisticsProps> = {
|
|
57
57
|
render: (args) => (
|
|
58
|
-
<
|
|
58
|
+
<LapisUrlContextProvider value={LAPIS_URL}>
|
|
59
59
|
<Statistics {...args} />
|
|
60
|
-
</
|
|
60
|
+
</LapisUrlContextProvider>
|
|
61
61
|
),
|
|
62
62
|
args: {
|
|
63
63
|
numeratorFilter: {
|
|
@@ -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
4
|
import { queryGeneralStatistics } from '../../query/queryGeneralStatistics';
|
|
6
5
|
import { lapisFilterSchema } from '../../types';
|
|
7
|
-
import {
|
|
6
|
+
import { useLapisUrl } from '../LapisUrlContext';
|
|
8
7
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
9
8
|
import { LoadingDisplay } from '../components/loading-display';
|
|
10
9
|
import { NoDataDisplay } from '../components/no-data-display';
|
|
@@ -35,7 +34,7 @@ export const Statistics: FunctionComponent<StatisticsProps> = (componentProps) =
|
|
|
35
34
|
|
|
36
35
|
export const StatisticsInner: FunctionComponent<StatisticsProps> = (componentProps) => {
|
|
37
36
|
const { numeratorFilter, denominatorFilter } = componentProps;
|
|
38
|
-
const lapis =
|
|
37
|
+
const lapis = useLapisUrl();
|
|
39
38
|
|
|
40
39
|
const { data, error, isLoading } = useQuery(async () => {
|
|
41
40
|
return queryGeneralStatistics(numeratorFilter, denominatorFilter, lapis);
|
|
@@ -5,7 +5,7 @@ import data from './__mockData__/aggregated_hosts.json';
|
|
|
5
5
|
import { TextInput, type TextInputProps } from './text-input';
|
|
6
6
|
import { previewHandles } from '../../../.storybook/preview';
|
|
7
7
|
import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
8
|
-
import {
|
|
8
|
+
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
9
9
|
import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
10
10
|
|
|
11
11
|
const meta: Meta<TextInputProps> = {
|
|
@@ -67,9 +67,9 @@ export default meta;
|
|
|
67
67
|
|
|
68
68
|
export const Default: StoryObj<TextInputProps> = {
|
|
69
69
|
render: (args) => (
|
|
70
|
-
<
|
|
70
|
+
<LapisUrlContextProvider value={LAPIS_URL}>
|
|
71
71
|
<TextInput {...args} />
|
|
72
|
-
</
|
|
72
|
+
</LapisUrlContextProvider>
|
|
73
73
|
),
|
|
74
74
|
args: {
|
|
75
75
|
lapisField: 'host',
|
|
@@ -92,13 +92,13 @@ export const RemoveInitialValue: StoryObj<TextInputProps> = {
|
|
|
92
92
|
const canvas = within(canvasElement);
|
|
93
93
|
|
|
94
94
|
const changedListenerMock = fn();
|
|
95
|
-
await step('Setup event listener mock',
|
|
95
|
+
await step('Setup event listener mock', () => {
|
|
96
96
|
canvasElement.addEventListener('gs-text-input-changed', changedListenerMock);
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
await waitFor(() => {
|
|
99
|
+
await waitFor(async () => {
|
|
100
100
|
const input = canvas.getByPlaceholderText('Enter a host name', { exact: false });
|
|
101
|
-
expect(input).toHaveValue('Homo sapiens');
|
|
101
|
+
await expect(input).toHaveValue('Homo sapiens');
|
|
102
102
|
});
|
|
103
103
|
|
|
104
104
|
await step('Remove initial value', async () => {
|
|
@@ -122,7 +122,7 @@ export const WithNoLapisField: StoryObj<TextInputProps> = {
|
|
|
122
122
|
lapisField: '',
|
|
123
123
|
},
|
|
124
124
|
play: async ({ canvasElement, step }) => {
|
|
125
|
-
step('expect error message', async () => {
|
|
125
|
+
await step('expect error message', async () => {
|
|
126
126
|
await expectInvalidAttributesErrorMessage(canvasElement, 'String must contain at least 1 character(s)');
|
|
127
127
|
});
|
|
128
128
|
},
|
|
@@ -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 { TextInputChangedEvent } from './TextInputChangedEvent';
|
|
6
|
+
import { fetchStringAutocompleteList } from './fetchStringAutocompleteList';
|
|
8
7
|
import { lapisFilterSchema } from '../../types';
|
|
9
8
|
import { DownshiftCombobox } from '../components/downshift-combobox';
|
|
10
9
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
@@ -46,7 +45,7 @@ const TextInputInner: FunctionComponent<TextInputInnerProps> = ({
|
|
|
46
45
|
placeholderText,
|
|
47
46
|
lapisFilter,
|
|
48
47
|
}) => {
|
|
49
|
-
const lapis =
|
|
48
|
+
const lapis = useLapisUrl();
|
|
50
49
|
|
|
51
50
|
const { data, error, isLoading } = useQuery(
|
|
52
51
|
() => fetchStringAutocompleteList({ lapis, field: lapisField, lapisFilter }),
|
|
@@ -3,7 +3,7 @@ import { type Meta, type StoryObj } from '@storybook/preact';
|
|
|
3
3
|
import { WastewaterMutationsOverTime, type WastewaterMutationsOverTimeProps } from './wastewater-mutations-over-time';
|
|
4
4
|
import { WISE_DETAILS_ENDPOINT, WISE_LAPIS_URL } from '../../../constants';
|
|
5
5
|
import referenceGenome from '../../../lapisApi/__mockData__/referenceGenome.json';
|
|
6
|
-
import {
|
|
6
|
+
import { LapisUrlContextProvider } from '../../LapisUrlContext';
|
|
7
7
|
import { ReferenceGenomeContext } from '../../ReferenceGenomeContext';
|
|
8
8
|
import details from './__mockData__/details.json';
|
|
9
9
|
|
|
@@ -28,11 +28,11 @@ export default meta;
|
|
|
28
28
|
|
|
29
29
|
const Template = {
|
|
30
30
|
render: (args: WastewaterMutationsOverTimeProps) => (
|
|
31
|
-
<
|
|
31
|
+
<LapisUrlContextProvider value={WISE_LAPIS_URL}>
|
|
32
32
|
<ReferenceGenomeContext.Provider value={referenceGenome}>
|
|
33
33
|
<WastewaterMutationsOverTime {...args} />
|
|
34
34
|
</ReferenceGenomeContext.Provider>
|
|
35
|
-
</
|
|
35
|
+
</LapisUrlContextProvider>
|
|
36
36
|
),
|
|
37
37
|
};
|
|
38
38
|
|
|
@@ -1,10 +1,10 @@
|
|
|
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 { computeWastewaterMutationsOverTimeDataPerLocation } from './computeWastewaterMutationsOverTimeDataPerLocation';
|
|
6
6
|
import { lapisFilterSchema, sequenceTypeSchema } from '../../../types';
|
|
7
|
-
import {
|
|
7
|
+
import { useLapisUrl } from '../../LapisUrlContext';
|
|
8
8
|
import { type ColorScale } from '../../components/color-scale-selector';
|
|
9
9
|
import { ColorScaleSelectorDropdown } from '../../components/color-scale-selector-dropdown';
|
|
10
10
|
import { ErrorBoundary } from '../../components/error-boundary';
|
|
@@ -44,7 +44,7 @@ export const WastewaterMutationsOverTime: FunctionComponent<WastewaterMutationsO
|
|
|
44
44
|
export const WastewaterMutationsOverTimeInner: FunctionComponent<WastewaterMutationsOverTimeProps> = (
|
|
45
45
|
componentProps,
|
|
46
46
|
) => {
|
|
47
|
-
const lapis =
|
|
47
|
+
const lapis = useLapisUrl();
|
|
48
48
|
|
|
49
49
|
const {
|
|
50
50
|
data: mutationOverTimeDataPerLocation,
|
|
@@ -142,7 +142,7 @@ type WastewaterMutationsOverTimeInfoProps = {
|
|
|
142
142
|
const WastewaterMutationsOverTimeInfo: FunctionComponent<WastewaterMutationsOverTimeInfoProps> = ({
|
|
143
143
|
originalComponentProps,
|
|
144
144
|
}) => {
|
|
145
|
-
const lapis =
|
|
145
|
+
const lapis = useLapisUrl();
|
|
146
146
|
return (
|
|
147
147
|
<Info>
|
|
148
148
|
<InfoHeadline1>Info for mutations over time</InfoHeadline1>
|
package/src/utils/map2d.ts
CHANGED
|
@@ -150,6 +150,7 @@ export class Map2dView<Key1 extends object | string, Key2 extends object | strin
|
|
|
150
150
|
this.keysSecondAxis = new Map(map.keysSecondAxis);
|
|
151
151
|
|
|
152
152
|
if (map instanceof Map2dView) {
|
|
153
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- the generics match, we know that.
|
|
153
154
|
this.baseMap = map.baseMap;
|
|
154
155
|
}
|
|
155
156
|
this.baseMap = map;
|
|
@@ -7,7 +7,7 @@ import { type JSXInternal } from 'preact/src/jsx';
|
|
|
7
7
|
import { lapisContext } from './lapis-context';
|
|
8
8
|
import { referenceGenomeContext } from './reference-genome-context';
|
|
9
9
|
import { type ReferenceGenome } from '../lapisApi/ReferenceGenome';
|
|
10
|
-
import {
|
|
10
|
+
import { LapisUrlContextProvider } from '../preact/LapisUrlContext';
|
|
11
11
|
import { ReferenceGenomeContext } from '../preact/ReferenceGenomeContext';
|
|
12
12
|
import minMaxPercentSliderCss from '../preact/components/min-max-percent-slider.css?inline';
|
|
13
13
|
import tailwindStyle from '../styles/tailwind.css?inline';
|
|
@@ -47,11 +47,11 @@ export abstract class PreactLitAdapter extends ReactiveElement {
|
|
|
47
47
|
|
|
48
48
|
override update(changedProperties: PropertyValues) {
|
|
49
49
|
const vdom = (
|
|
50
|
-
<
|
|
50
|
+
<LapisUrlContextProvider value={this.lapis}>
|
|
51
51
|
<ReferenceGenomeContext.Provider value={this.referenceGenome}>
|
|
52
52
|
{this.render()}
|
|
53
53
|
</ReferenceGenomeContext.Provider>
|
|
54
|
-
</
|
|
54
|
+
</LapisUrlContextProvider>
|
|
55
55
|
);
|
|
56
56
|
super.update(changedProperties);
|
|
57
57
|
render(vdom, this.renderRoot);
|
|
@@ -50,9 +50,9 @@ export const Default: StoryObj<{ lapis: string }> = {
|
|
|
50
50
|
play: async ({ canvasElement }) => {
|
|
51
51
|
const canvas = within(canvasElement);
|
|
52
52
|
|
|
53
|
-
await waitFor(() => {
|
|
54
|
-
expect(canvas.getByText(LAPIS_URL)).toBeVisible();
|
|
55
|
-
expect(canvas.getByText('"name": "ORF1a",', { exact: false })).toBeVisible();
|
|
53
|
+
await waitFor(async () => {
|
|
54
|
+
await expect(canvas.getByText(LAPIS_URL)).toBeVisible();
|
|
55
|
+
await expect(canvas.getByText('"name": "ORF1a",', { exact: false })).toBeVisible();
|
|
56
56
|
});
|
|
57
57
|
},
|
|
58
58
|
};
|
|
@@ -66,8 +66,8 @@ export const WithNoLapisUrl: StoryObj<{ lapis: string }> = {
|
|
|
66
66
|
play: async ({ canvasElement }) => {
|
|
67
67
|
const canvas = within(canvasElement);
|
|
68
68
|
|
|
69
|
-
await waitFor(() => {
|
|
70
|
-
expect(canvas.getByText("Error: Invalid LAPIS URL: 'notAValidUrl'", { exact: false })).toBeVisible();
|
|
69
|
+
await waitFor(async () => {
|
|
70
|
+
await expect(canvas.getByText("Error: Invalid LAPIS URL: 'notAValidUrl'", { exact: false })).toBeVisible();
|
|
71
71
|
});
|
|
72
72
|
},
|
|
73
73
|
};
|
|
@@ -103,8 +103,8 @@ export const FailsToFetchReferenceGenome: StoryObj<{ lapis: string }> = {
|
|
|
103
103
|
play: async ({ canvasElement }) => {
|
|
104
104
|
const canvas = within(canvasElement);
|
|
105
105
|
|
|
106
|
-
await waitFor(() => {
|
|
107
|
-
expect(canvas.getByText('Error: Cannot fetch reference genome.', { exact: false })).toBeVisible();
|
|
106
|
+
await waitFor(async () => {
|
|
107
|
+
await expect(canvas.getByText('Error: Cannot fetch reference genome.', { exact: false })).toBeVisible();
|
|
108
108
|
});
|
|
109
109
|
},
|
|
110
110
|
};
|
|
@@ -55,7 +55,9 @@ export class AppComponent extends LitElement {
|
|
|
55
55
|
task: async () => {
|
|
56
56
|
const lapisUrl = lapisUrlSchema.parse(this.lapis);
|
|
57
57
|
|
|
58
|
-
this.referenceGenome = await fetchReferenceGenome(
|
|
58
|
+
this.referenceGenome = await fetchReferenceGenome(
|
|
59
|
+
lapisUrl.endsWith('/') ? lapisUrl.slice(0, -1) : lapisUrl,
|
|
60
|
+
);
|
|
59
61
|
},
|
|
60
62
|
args: () => [this.lapis],
|
|
61
63
|
});
|
|
@@ -16,9 +16,7 @@ const codeExample = String.raw`
|
|
|
16
16
|
<gs-date-range-selector
|
|
17
17
|
dateRangeOptions='[{ "label": "Year 2021", "dateFrom": "2021-01-01", "dateTo": "2021-12-31" }]'
|
|
18
18
|
earliestDate="1970-01-01"
|
|
19
|
-
|
|
20
|
-
initialDateFrom="2020-01-01"
|
|
21
|
-
initialDateTo="2021-01-01"
|
|
19
|
+
value="Year 2021"
|
|
22
20
|
width="100%"
|
|
23
21
|
lapisDateField="myDateColumn"
|
|
24
22
|
></gs-date-range-selector>`;
|
|
@@ -40,11 +38,10 @@ const meta: Meta<Required<DateRangeSelectorProps>> = {
|
|
|
40
38
|
},
|
|
41
39
|
}),
|
|
42
40
|
argTypes: {
|
|
43
|
-
|
|
41
|
+
value: {
|
|
44
42
|
control: {
|
|
45
|
-
type: '
|
|
43
|
+
type: 'object',
|
|
46
44
|
},
|
|
47
|
-
options: [dateRangeOptionPresets.lastMonth.label, dateRangeOptionPresets.allTimes.label, 'CustomDateRange'],
|
|
48
45
|
},
|
|
49
46
|
lapisDateField: { control: { type: 'text' } },
|
|
50
47
|
dateRangeOptions: {
|
|
@@ -71,11 +68,9 @@ const meta: Meta<Required<DateRangeSelectorProps>> = {
|
|
|
71
68
|
customDateRange,
|
|
72
69
|
],
|
|
73
70
|
earliestDate: '1970-01-01',
|
|
74
|
-
|
|
71
|
+
value: dateRangeOptionPresets.lastMonth.label,
|
|
75
72
|
lapisDateField: 'aDateColumn',
|
|
76
73
|
width: '100%',
|
|
77
|
-
initialDateFrom: undefined,
|
|
78
|
-
initialDateTo: undefined,
|
|
79
74
|
},
|
|
80
75
|
tags: ['autodocs'],
|
|
81
76
|
};
|
|
@@ -89,9 +84,7 @@ export const Default: StoryObj<Required<DateRangeSelectorProps>> = {
|
|
|
89
84
|
<gs-date-range-selector
|
|
90
85
|
.dateRangeOptions=${args.dateRangeOptions}
|
|
91
86
|
.earliestDate=${args.earliestDate}
|
|
92
|
-
.
|
|
93
|
-
.initialDateFrom=${args.initialDateFrom}
|
|
94
|
-
.initialDateTo=${args.initialDateTo}
|
|
87
|
+
.value=${args.value}
|
|
95
88
|
.width=${args.width}
|
|
96
89
|
.lapisDateField=${args.lapisDateField}
|
|
97
90
|
></gs-date-range-selector>
|
|
@@ -106,15 +99,15 @@ export const FiresEvents: StoryObj<Required<DateRangeSelectorProps>> = {
|
|
|
106
99
|
|
|
107
100
|
const filterChangedListenerMock = fn();
|
|
108
101
|
const optionChangedListenerMock = fn();
|
|
109
|
-
await step('Setup event listener mock',
|
|
102
|
+
await step('Setup event listener mock', () => {
|
|
110
103
|
canvasElement.addEventListener('gs-date-range-filter-changed', filterChangedListenerMock);
|
|
111
104
|
canvasElement.addEventListener('gs-date-range-option-changed', optionChangedListenerMock);
|
|
112
105
|
});
|
|
113
106
|
|
|
114
107
|
await step('Expect last 6 months to be selected', async () => {
|
|
115
108
|
await expect(selectField(canvas)).toHaveValue('Last month');
|
|
116
|
-
await waitFor(() => {
|
|
117
|
-
expect(dateToPicker(canvas)).toHaveValue(toYYYYMMDD(new Date()));
|
|
109
|
+
await waitFor(async () => {
|
|
110
|
+
await expect(dateToPicker(canvas)).toHaveValue(toYYYYMMDD(new Date()));
|
|
118
111
|
});
|
|
119
112
|
});
|
|
120
113
|
|
|
@@ -140,5 +133,5 @@ export const FiresEvents: StoryObj<Required<DateRangeSelectorProps>> = {
|
|
|
140
133
|
},
|
|
141
134
|
};
|
|
142
135
|
|
|
143
|
-
const dateToPicker = (canvas: ReturnType<typeof within>) => canvas.getByPlaceholderText('Date to');
|
|
144
|
-
const selectField = (canvas: ReturnType<typeof within>) => canvas.getByRole('combobox');
|
|
136
|
+
const dateToPicker = (canvas: ReturnType<typeof within>): HTMLElement => canvas.getByPlaceholderText('Date to');
|
|
137
|
+
const selectField = (canvas: ReturnType<typeof within>): HTMLElement => canvas.getByRole('combobox');
|
|
@@ -46,15 +46,18 @@ import { PreactLitAdapter } from '../PreactLitAdapter';
|
|
|
46
46
|
* Contains the selected dateRangeOption or when users select custom values it contains the selected dates.
|
|
47
47
|
*
|
|
48
48
|
* Use this event, when you want to control this component in your JS application.
|
|
49
|
+
* You can supply the `detail` of this event to the `value` attribute of this component.
|
|
49
50
|
*/
|
|
50
51
|
@customElement('gs-date-range-selector')
|
|
51
52
|
export class DateRangeSelectorComponent extends PreactLitAdapter {
|
|
52
53
|
/**
|
|
53
54
|
* An array of date range options that the select field should provide.
|
|
54
|
-
* The `label` will be shown to the user, and it will be available as `
|
|
55
|
+
* The `label` will be shown to the user, and it will be available as `value`.
|
|
55
56
|
* The dates must be in the format `YYYY-MM-DD`.
|
|
56
57
|
*
|
|
57
58
|
* If dateFrom or dateTo is not set, the component will default to the `earliestDate` or the current date.
|
|
59
|
+
*
|
|
60
|
+
* We provide some options in `dateRangeOptionPresets` for convenience.
|
|
58
61
|
*/
|
|
59
62
|
@property({ type: Array })
|
|
60
63
|
dateRangeOptions: { label: string; dateFrom?: string; dateTo?: string }[] = [];
|
|
@@ -66,33 +69,17 @@ export class DateRangeSelectorComponent extends PreactLitAdapter {
|
|
|
66
69
|
earliestDate: string = '1900-01-01';
|
|
67
70
|
|
|
68
71
|
/**
|
|
69
|
-
* The
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* It will be overwritten if `initialDateFrom` or `initialDateTo` is set.
|
|
72
|
+
* The value to use for this date range selector.
|
|
73
|
+
* - If it is a string, then it must be a valid label from the `dateRangeOptions`.
|
|
74
|
+
* - If it is an object, then it accepts dates in the format `YYYY-MM-DD` for the keys `dateFrom` and `dateTo`.
|
|
75
|
+
* Keys that are not set will default to the `earliestDate` or the current date respectively.
|
|
76
|
+
* - If the attribute is not set, the component will default to the range `earliestDate` until today.
|
|
75
77
|
*
|
|
76
|
-
*
|
|
77
|
-
|
|
78
|
-
@property()
|
|
79
|
-
initialValue: string | undefined = undefined;
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* A date string in the format `YYYY-MM-DD`.
|
|
83
|
-
* If set, the date range selector will be initialized with the given date (overwriting `initialValue` to `custom`).
|
|
84
|
-
* If `initialDateTo` is set, but this is unset, it will default to `earliestDate`.
|
|
85
|
-
*/
|
|
86
|
-
@property()
|
|
87
|
-
initialDateFrom: string | undefined = undefined;
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* A date string in the format `YYYY-MM-DD`.
|
|
91
|
-
* If set, the date range selector will be initialized with the given date (overwriting `initialValue` to `custom`).
|
|
92
|
-
* If `initialDateFrom` is set, but this is unset, it will default to the current date.
|
|
78
|
+
* The `detail` of the `gs-date-range-option-changed` event can be used for this attribute,
|
|
79
|
+
* if you want to control this component in your JS application.
|
|
93
80
|
*/
|
|
94
|
-
@property()
|
|
95
|
-
|
|
81
|
+
@property({ type: Object })
|
|
82
|
+
value: string | { dateFrom?: string; dateTo?: string } | undefined = undefined;
|
|
96
83
|
|
|
97
84
|
/**
|
|
98
85
|
* The width of the component.
|
|
@@ -113,9 +100,7 @@ export class DateRangeSelectorComponent extends PreactLitAdapter {
|
|
|
113
100
|
<DateRangeSelector
|
|
114
101
|
dateRangeOptions={this.dateRangeOptions}
|
|
115
102
|
earliestDate={this.earliestDate}
|
|
116
|
-
|
|
117
|
-
initialDateFrom={this.initialDateFrom}
|
|
118
|
-
initialDateTo={this.initialDateTo}
|
|
103
|
+
value={this.value}
|
|
119
104
|
lapisDateField={this.lapisDateField}
|
|
120
105
|
width={this.width}
|
|
121
106
|
/>
|
|
@@ -150,15 +135,7 @@ type CustomSelectOptionsMatches = Expect<
|
|
|
150
135
|
type EarliestDateMatches = Expect<
|
|
151
136
|
Equals<typeof DateRangeSelectorComponent.prototype.earliestDate, DateRangeSelectorProps['earliestDate']>
|
|
152
137
|
>;
|
|
153
|
-
type
|
|
154
|
-
Equals<typeof DateRangeSelectorComponent.prototype.initialValue, DateRangeSelectorProps['initialValue']>
|
|
155
|
-
>;
|
|
156
|
-
type InitialDateFromMatches = Expect<
|
|
157
|
-
Equals<typeof DateRangeSelectorComponent.prototype.initialDateFrom, DateRangeSelectorProps['initialDateFrom']>
|
|
158
|
-
>;
|
|
159
|
-
type InitialDateToMatches = Expect<
|
|
160
|
-
Equals<typeof DateRangeSelectorComponent.prototype.initialDateTo, DateRangeSelectorProps['initialDateTo']>
|
|
161
|
-
>;
|
|
138
|
+
type ValueMatches = Expect<Equals<typeof DateRangeSelectorComponent.prototype.value, DateRangeSelectorProps['value']>>;
|
|
162
139
|
type WidthMatches = Expect<Equals<typeof DateRangeSelectorComponent.prototype.width, DateRangeSelectorProps['width']>>;
|
|
163
140
|
type DateColumnMatches = Expect<
|
|
164
141
|
Equals<typeof DateRangeSelectorComponent.prototype.lapisDateField, DateRangeSelectorProps['lapisDateField']>
|
|
@@ -181,7 +181,7 @@ export const FiresEvent: StoryObj<Required<LineageFilterProps>> = {
|
|
|
181
181
|
|
|
182
182
|
const inputField = () => canvas.getByPlaceholderText('Enter a lineage');
|
|
183
183
|
const listenerMock = fn();
|
|
184
|
-
await step('Setup event listener mock',
|
|
184
|
+
await step('Setup event listener mock', () => {
|
|
185
185
|
canvasElement.addEventListener('gs-lineage-filter-changed', listenerMock);
|
|
186
186
|
});
|
|
187
187
|
|
|
@@ -188,7 +188,7 @@ export const FiresEvent: StoryObj<LocationFilterProps> = {
|
|
|
188
188
|
const inputField = () => canvas.getByRole('combobox');
|
|
189
189
|
|
|
190
190
|
const listenerMock = fn();
|
|
191
|
-
await step('Setup event listener mock',
|
|
191
|
+
await step('Setup event listener mock', () => {
|
|
192
192
|
canvasElement.addEventListener('gs-location-changed', listenerMock);
|
|
193
193
|
});
|
|
194
194
|
|
|
@@ -72,7 +72,7 @@ export const FiresFilterChangedEvent: StoryObj<MutationFilterProps> = {
|
|
|
72
72
|
|
|
73
73
|
const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false });
|
|
74
74
|
const listenerMock = fn();
|
|
75
|
-
await step('Setup event listener mock',
|
|
75
|
+
await step('Setup event listener mock', () => {
|
|
76
76
|
canvasElement.addEventListener('gs-mutation-filter-changed', listenerMock);
|
|
77
77
|
});
|
|
78
78
|
|
|
@@ -154,18 +154,18 @@ export const MultiSegmentedReferenceGenomes: StoryObj<MutationFilterProps> = {
|
|
|
154
154
|
|
|
155
155
|
const inputField = () => canvas.getByPlaceholderText('Enter a mutation', { exact: false });
|
|
156
156
|
|
|
157
|
-
await waitFor(() => {
|
|
157
|
+
await waitFor(async () => {
|
|
158
158
|
const placeholderText = inputField().getAttribute('placeholder');
|
|
159
159
|
|
|
160
|
-
expect(placeholderText).toEqual(
|
|
160
|
+
await expect(placeholderText).toEqual(
|
|
161
161
|
'Enter a mutation (e.g. seg1:23T, ins_seg1:10462:A, gene1:57Q, ins_gene1:31:N)',
|
|
162
162
|
);
|
|
163
163
|
});
|
|
164
164
|
|
|
165
|
-
await waitFor(() => {
|
|
166
|
-
expect(canvas.getByText('seg1:123T')).toBeVisible();
|
|
167
|
-
expect(canvas.getByText('gene2:56')).toBeVisible();
|
|
168
|
-
|
|
165
|
+
await waitFor(async () => {
|
|
166
|
+
await expect(canvas.getByText('seg1:123T')).toBeVisible();
|
|
167
|
+
await expect(canvas.getByText('gene2:56')).toBeVisible();
|
|
168
|
+
await expect(canvas.getByText('ins_seg2:78:AAA')).toBeVisible();
|
|
169
169
|
});
|
|
170
170
|
},
|
|
171
171
|
};
|
|
@@ -113,7 +113,7 @@ export const FiresEvents: StoryObj<Required<TextInputProps>> = {
|
|
|
113
113
|
|
|
114
114
|
const inputField = () => canvas.getByPlaceholderText('Enter host name');
|
|
115
115
|
const listenerMock = fn();
|
|
116
|
-
await step('Setup event listener mock',
|
|
116
|
+
await step('Setup event listener mock', () => {
|
|
117
117
|
canvasElement.addEventListener('gs-text-input-changed', listenerMock);
|
|
118
118
|
});
|
|
119
119
|
|
|
@@ -140,8 +140,8 @@ export const FiresEvents: StoryObj<Required<TextInputProps>> = {
|
|
|
140
140
|
});
|
|
141
141
|
|
|
142
142
|
await step('Verify event is fired with correct detail', async () => {
|
|
143
|
-
await waitFor(() => {
|
|
144
|
-
expect(listenerMock).toHaveBeenCalledWith(
|
|
143
|
+
await waitFor(async () => {
|
|
144
|
+
await expect(listenerMock).toHaveBeenCalledWith(
|
|
145
145
|
expect.objectContaining({
|
|
146
146
|
detail: {
|
|
147
147
|
host: 'Homo sapiens',
|