@genspectrum/dashboard-components 0.19.5 → 0.19.7
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/README.md +24 -8
- package/custom-elements.json +101 -2
- package/dist/{LineageFilterChangedEvent-GgkxoF3X.js → NumberRangeFilterChangedEvent-RZ8haPHq.js} +31 -5
- package/dist/NumberRangeFilterChangedEvent-RZ8haPHq.js.map +1 -0
- package/dist/assets/mutationOverTimeWorker-DQGh08AS.js.map +1 -0
- package/dist/components.d.ts +43 -12
- package/dist/components.js +78 -63
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +21 -10
- package/dist/util.js +3 -1
- package/package.json +1 -1
- package/src/preact/aggregatedData/aggregate.stories.tsx +6 -0
- package/src/preact/aggregatedData/aggregate.tsx +10 -1
- package/src/preact/components/tabs.tsx +4 -4
- package/src/preact/genomeViewer/CDSPlot.tsx +4 -1
- package/src/preact/genomeViewer/genome-data-viewer.stories.tsx +6 -0
- package/src/preact/mutationComparison/mutation-comparison.stories.tsx +6 -0
- package/src/preact/mutationComparison/mutation-comparison.tsx +4 -0
- package/src/preact/mutations/mutations.stories.tsx +6 -0
- package/src/preact/mutations/mutations.tsx +4 -1
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +6 -0
- package/src/preact/mutationsOverTime/mutations-over-time.tsx +4 -1
- package/src/preact/numberRangeFilter/NumberRangeFilterChangedEvent.ts +1 -1
- package/src/preact/numberSequencesOverTime/number-sequences-over-time.stories.tsx +3 -1
- package/src/preact/numberSequencesOverTime/number-sequences-over-time.tsx +4 -0
- package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +6 -0
- package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +4 -1
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +6 -0
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +4 -1
- package/src/preact/sequencesByLocation/sequences-by-location.stories.tsx +6 -0
- package/src/preact/sequencesByLocation/sequences-by-location.tsx +4 -0
- package/src/preact/shared/stories/expectFinishedLoadingEvent.ts +12 -0
- package/src/preact/statistic/statistics.stories.tsx +6 -0
- package/src/preact/statistic/statistics.tsx +4 -1
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.stories.tsx +2 -0
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +4 -1
- package/src/utilEntrypoint.ts +6 -1
- package/src/utils/gsEventNames.ts +1 -0
- package/src/utils/useDispatchFinishedLoadingEvent.ts +19 -0
- package/src/web-components/input/gs-number-range-filter.tsx +2 -2
- package/src/web-components/visualization/gs-aggregate.tsx +3 -0
- package/src/web-components/visualization/gs-genome-data-viewer.tsx +2 -0
- package/src/web-components/visualization/gs-mutation-comparison.tsx +3 -0
- package/src/web-components/visualization/gs-mutations-over-time.tsx +3 -0
- package/src/web-components/visualization/gs-mutations.tsx +2 -0
- package/src/web-components/visualization/gs-number-sequences-over-time.tsx +3 -0
- package/src/web-components/visualization/gs-prevalence-over-time.tsx +3 -0
- package/src/web-components/visualization/gs-relative-growth-advantage.tsx +3 -0
- package/src/web-components/visualization/gs-sequences-by-location.tsx +3 -0
- package/src/web-components/visualization/gs-statistics.tsx +3 -0
- package/src/web-components/wastewaterVisualization/gs-wastewater-mutations-over-time.tsx +3 -0
- package/standalone-bundle/assets/mutationOverTimeWorker-DAf2_NiP.js.map +1 -0
- package/standalone-bundle/dashboard-components.js +6980 -6945
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/dist/LineageFilterChangedEvent-GgkxoF3X.js.map +0 -1
- package/dist/assets/mutationOverTimeWorker-ChQTFL68.js.map +0 -1
- package/standalone-bundle/assets/mutationOverTimeWorker-jChgWnwp.js.map +0 -1
package/dist/util.d.ts
CHANGED
|
@@ -151,6 +151,7 @@ declare const dateRangeValueSchema: default_2.ZodNullable<default_2.ZodUnion<[de
|
|
|
151
151
|
|
|
152
152
|
export declare const gsEventNames: {
|
|
153
153
|
readonly error: "gs-error";
|
|
154
|
+
readonly componentFinishedLoading: "gs-component-finished-loading";
|
|
154
155
|
readonly dateRangeFilterChanged: "gs-date-range-filter-changed";
|
|
155
156
|
readonly dateRangeOptionChanged: "gs-date-range-option-changed";
|
|
156
157
|
readonly mutationFilterChanged: "gs-mutation-filter-changed";
|
|
@@ -186,6 +187,8 @@ declare type LapisLocationFilter = default_2.infer<typeof lapisLocationFilterSch
|
|
|
186
187
|
|
|
187
188
|
declare const lapisLocationFilterSchema: default_2.ZodRecord<default_2.ZodString, default_2.ZodUnion<[default_2.ZodString, default_2.ZodUndefined]>>;
|
|
188
189
|
|
|
190
|
+
export declare type LapisNumberFilter = Record<string, number | undefined>;
|
|
191
|
+
|
|
189
192
|
declare type LapisTextFilter = Record<string, string | undefined>;
|
|
190
193
|
|
|
191
194
|
export declare class LineageFilterChangedEvent extends CustomEvent<LapisLineageFilter> {
|
|
@@ -488,6 +491,10 @@ declare const namedLapisFilterSchema: default_2.ZodObject<{
|
|
|
488
491
|
|
|
489
492
|
export declare type NumberRange = default_2.infer<typeof numberRangeSchema>;
|
|
490
493
|
|
|
494
|
+
export declare class NumberRangeFilterChangedEvent extends CustomEvent<LapisNumberFilter> {
|
|
495
|
+
constructor(detail: LapisNumberFilter);
|
|
496
|
+
}
|
|
497
|
+
|
|
491
498
|
declare const numberRangeSchema: default_2.ZodObject<{
|
|
492
499
|
min: default_2.ZodOptional<default_2.ZodNumber>;
|
|
493
500
|
max: default_2.ZodOptional<default_2.ZodNumber>;
|
|
@@ -499,6 +506,10 @@ declare const numberRangeSchema: default_2.ZodObject<{
|
|
|
499
506
|
max?: number | undefined;
|
|
500
507
|
}>;
|
|
501
508
|
|
|
509
|
+
export declare class NumberRangeValueChangedEvent extends CustomEvent<NumberRange> {
|
|
510
|
+
constructor(detail: NumberRange);
|
|
511
|
+
}
|
|
512
|
+
|
|
502
513
|
export declare type NumberSequencesOverTimeProps = default_2.infer<typeof numberSequencesOverTimePropsSchema>;
|
|
503
514
|
|
|
504
515
|
declare const numberSequencesOverTimePropsSchema: default_2.ZodObject<{
|
|
@@ -943,7 +954,7 @@ declare global {
|
|
|
943
954
|
|
|
944
955
|
declare global {
|
|
945
956
|
interface HTMLElementTagNameMap {
|
|
946
|
-
'gs-
|
|
957
|
+
'gs-mutations-component': MutationsComponent;
|
|
947
958
|
}
|
|
948
959
|
}
|
|
949
960
|
|
|
@@ -951,7 +962,7 @@ declare global {
|
|
|
951
962
|
declare global {
|
|
952
963
|
namespace JSX {
|
|
953
964
|
interface IntrinsicElements {
|
|
954
|
-
'gs-
|
|
965
|
+
'gs-mutations-component': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
955
966
|
}
|
|
956
967
|
}
|
|
957
968
|
}
|
|
@@ -959,7 +970,7 @@ declare global {
|
|
|
959
970
|
|
|
960
971
|
declare global {
|
|
961
972
|
interface HTMLElementTagNameMap {
|
|
962
|
-
'gs-
|
|
973
|
+
'gs-mutation-comparison-component': MutationComparisonComponent;
|
|
963
974
|
}
|
|
964
975
|
}
|
|
965
976
|
|
|
@@ -967,7 +978,7 @@ declare global {
|
|
|
967
978
|
declare global {
|
|
968
979
|
namespace JSX {
|
|
969
980
|
interface IntrinsicElements {
|
|
970
|
-
'gs-
|
|
981
|
+
'gs-mutation-comparison-component': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
971
982
|
}
|
|
972
983
|
}
|
|
973
984
|
}
|
|
@@ -1123,10 +1134,10 @@ declare global {
|
|
|
1123
1134
|
|
|
1124
1135
|
declare global {
|
|
1125
1136
|
interface HTMLElementTagNameMap {
|
|
1126
|
-
'gs-
|
|
1137
|
+
'gs-location-filter': LocationFilterComponent;
|
|
1127
1138
|
}
|
|
1128
1139
|
interface HTMLElementEventMap {
|
|
1129
|
-
[gsEventNames.
|
|
1140
|
+
[gsEventNames.locationChanged]: LocationChangedEvent;
|
|
1130
1141
|
}
|
|
1131
1142
|
}
|
|
1132
1143
|
|
|
@@ -1134,7 +1145,7 @@ declare global {
|
|
|
1134
1145
|
declare global {
|
|
1135
1146
|
namespace JSX {
|
|
1136
1147
|
interface IntrinsicElements {
|
|
1137
|
-
'gs-
|
|
1148
|
+
'gs-location-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1138
1149
|
}
|
|
1139
1150
|
}
|
|
1140
1151
|
}
|
|
@@ -1142,10 +1153,10 @@ declare global {
|
|
|
1142
1153
|
|
|
1143
1154
|
declare global {
|
|
1144
1155
|
interface HTMLElementTagNameMap {
|
|
1145
|
-
'gs-
|
|
1156
|
+
'gs-text-filter': TextFilterComponent;
|
|
1146
1157
|
}
|
|
1147
1158
|
interface HTMLElementEventMap {
|
|
1148
|
-
[gsEventNames.
|
|
1159
|
+
[gsEventNames.textFilterChanged]: TextFilterChangedEvent;
|
|
1149
1160
|
}
|
|
1150
1161
|
}
|
|
1151
1162
|
|
|
@@ -1153,7 +1164,7 @@ declare global {
|
|
|
1153
1164
|
declare global {
|
|
1154
1165
|
namespace JSX {
|
|
1155
1166
|
interface IntrinsicElements {
|
|
1156
|
-
'gs-
|
|
1167
|
+
'gs-text-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1157
1168
|
}
|
|
1158
1169
|
}
|
|
1159
1170
|
}
|
package/dist/util.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { D, a, L, T, d, g, v } from "./
|
|
1
|
+
import { D, a, L, N, b, T, d, g, v } from "./NumberRangeFilterChangedEvent-RZ8haPHq.js";
|
|
2
2
|
export {
|
|
3
3
|
D as DateRangeOptionChangedEvent,
|
|
4
4
|
a as LineageFilterChangedEvent,
|
|
5
5
|
L as LocationChangedEvent,
|
|
6
|
+
N as NumberRangeFilterChangedEvent,
|
|
7
|
+
b as NumberRangeValueChangedEvent,
|
|
6
8
|
T as TextFilterChangedEvent,
|
|
7
9
|
d as dateRangeOptionPresets,
|
|
8
10
|
g as gsEventNames,
|
package/package.json
CHANGED
|
@@ -6,6 +6,7 @@ import { Aggregate, type AggregateProps } from './aggregate';
|
|
|
6
6
|
import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
7
7
|
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
8
8
|
import { expectInvalidAttributesErrorMessage, playThatExpectsErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
9
|
+
import { playThatExpectsFinishedLoadingEvent } from '../shared/stories/expectFinishedLoadingEvent';
|
|
9
10
|
|
|
10
11
|
const meta: Meta<AggregateProps> = {
|
|
11
12
|
title: 'Visualization/Aggregate',
|
|
@@ -62,6 +63,11 @@ export const Default: StoryObj<AggregateProps> = {
|
|
|
62
63
|
},
|
|
63
64
|
};
|
|
64
65
|
|
|
66
|
+
export const FiresFinishedLoadingEvent: StoryObj<AggregateProps> = {
|
|
67
|
+
...Default,
|
|
68
|
+
play: playThatExpectsFinishedLoadingEvent(),
|
|
69
|
+
};
|
|
70
|
+
|
|
65
71
|
export const FailsLoadingData: StoryObj<AggregateProps> = {
|
|
66
72
|
...Default,
|
|
67
73
|
parameters: {
|
|
@@ -5,6 +5,7 @@ import { useLapisUrl } from '../LapisUrlContext';
|
|
|
5
5
|
import { AggregateTable } from './aggregate-table';
|
|
6
6
|
import { type AggregateData, queryAggregateData } from '../../query/queryAggregateData';
|
|
7
7
|
import { lapisFilterSchema, views } from '../../types';
|
|
8
|
+
import { useDispatchFinishedLoadingEvent } from '../../utils/useDispatchFinishedLoadingEvent';
|
|
8
9
|
import { CsvDownloadButton } from '../components/csv-download-button';
|
|
9
10
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
10
11
|
import { Fullscreen } from '../components/fullscreen';
|
|
@@ -75,6 +76,8 @@ type AggregatedDataTabsProps = {
|
|
|
75
76
|
};
|
|
76
77
|
|
|
77
78
|
const AggregatedDataTabs: FunctionComponent<AggregatedDataTabsProps> = ({ data, originalComponentProps }) => {
|
|
79
|
+
const tabsRef = useDispatchFinishedLoadingEvent();
|
|
80
|
+
|
|
78
81
|
const maintainAspectRatio = getMaintainAspectRatio(originalComponentProps.height);
|
|
79
82
|
|
|
80
83
|
const getTab = (view: AggregateView) => {
|
|
@@ -109,7 +112,13 @@ const AggregatedDataTabs: FunctionComponent<AggregatedDataTabsProps> = ({ data,
|
|
|
109
112
|
|
|
110
113
|
const tabs = originalComponentProps.views.map((view) => getTab(view));
|
|
111
114
|
|
|
112
|
-
return
|
|
115
|
+
return (
|
|
116
|
+
<Tabs
|
|
117
|
+
ref={tabsRef}
|
|
118
|
+
tabs={tabs}
|
|
119
|
+
toolbar={<Toolbar data={data} originalComponentProps={originalComponentProps} />}
|
|
120
|
+
/>
|
|
121
|
+
);
|
|
113
122
|
};
|
|
114
123
|
|
|
115
124
|
type ToolbarProps = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { forwardRef } from 'preact/compat';
|
|
2
2
|
import { useState } from 'preact/hooks';
|
|
3
3
|
import { type JSXInternal } from 'preact/src/jsx';
|
|
4
4
|
|
|
@@ -12,7 +12,7 @@ interface ComponentTabsProps {
|
|
|
12
12
|
toolbar?: JSXInternal.Element | ((activeTab: string) => JSXInternal.Element);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const Tabs
|
|
15
|
+
const Tabs = forwardRef<HTMLDivElement, ComponentTabsProps>(({ tabs, toolbar }, ref) => {
|
|
16
16
|
const [activeTab, setActiveTab] = useState(tabs[0]?.title);
|
|
17
17
|
|
|
18
18
|
const tabElements = (
|
|
@@ -40,7 +40,7 @@ const Tabs: FunctionComponent<ComponentTabsProps> = ({ tabs, toolbar }) => {
|
|
|
40
40
|
const toolbarElement = typeof toolbar === 'function' ? toolbar(activeTab) : toolbar;
|
|
41
41
|
|
|
42
42
|
return (
|
|
43
|
-
<div className='h-full w-full flex flex-col'>
|
|
43
|
+
<div ref={ref} className='h-full w-full flex flex-col'>
|
|
44
44
|
<div className='flex flex-row justify-between flex-wrap'>
|
|
45
45
|
{tabElements}
|
|
46
46
|
{toolbar && <div className='py-2 flex flex-wrap gap-y-1'>{toolbarElement}</div>}
|
|
@@ -54,6 +54,6 @@ const Tabs: FunctionComponent<ComponentTabsProps> = ({ tabs, toolbar }) => {
|
|
|
54
54
|
</div>
|
|
55
55
|
</div>
|
|
56
56
|
);
|
|
57
|
-
};
|
|
57
|
+
});
|
|
58
58
|
|
|
59
59
|
export default Tabs;
|
|
@@ -2,6 +2,7 @@ import { Fragment, type FunctionComponent } from 'preact';
|
|
|
2
2
|
import { useMemo, useState } from 'preact/hooks';
|
|
3
3
|
|
|
4
4
|
import { type CDSFeature } from './loadGff3';
|
|
5
|
+
import { useDispatchFinishedLoadingEvent } from '../../utils/useDispatchFinishedLoadingEvent';
|
|
5
6
|
import { MinMaxRangeSlider } from '../components/min-max-range-slider';
|
|
6
7
|
import Tooltip from '../components/tooltip';
|
|
7
8
|
import { singleGraphColorRGBByName } from '../shared/charts/colors';
|
|
@@ -183,6 +184,8 @@ interface CDSProps {
|
|
|
183
184
|
}
|
|
184
185
|
|
|
185
186
|
const CDSPlot: FunctionComponent<CDSProps> = (componentProps) => {
|
|
187
|
+
const ref = useDispatchFinishedLoadingEvent();
|
|
188
|
+
|
|
186
189
|
const { gffData, genomeLength, width } = componentProps;
|
|
187
190
|
|
|
188
191
|
const [zoomStart, setZoomStart] = useState(0);
|
|
@@ -197,7 +200,7 @@ const CDSPlot: FunctionComponent<CDSProps> = (componentProps) => {
|
|
|
197
200
|
};
|
|
198
201
|
|
|
199
202
|
return (
|
|
200
|
-
<div class='p-4'>
|
|
203
|
+
<div ref={ref} class='p-4'>
|
|
201
204
|
<CDSBars gffData={gffData} zoomStart={zoomStart} zoomEnd={zoomEnd} />
|
|
202
205
|
<XAxis zoomStart={zoomStart} zoomEnd={zoomEnd} fullWidth={width} />
|
|
203
206
|
<div class='relative w-full h-5'>
|
|
@@ -2,6 +2,7 @@ import { type Meta, type StoryObj } from '@storybook/preact';
|
|
|
2
2
|
|
|
3
3
|
import { GenomeDataViewer, type GenomeDataViewerProps } from './genome-data-viewer';
|
|
4
4
|
import { playThatExpectsErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
5
|
+
import { playThatExpectsFinishedLoadingEvent } from '../shared/stories/expectFinishedLoadingEvent';
|
|
5
6
|
|
|
6
7
|
const meta: Meta<GenomeDataViewerProps> = {
|
|
7
8
|
title: 'Visualization/GenomeDataViewer',
|
|
@@ -75,6 +76,11 @@ export const Default: StoryObj<GenomeDataViewerProps> = {
|
|
|
75
76
|
},
|
|
76
77
|
};
|
|
77
78
|
|
|
79
|
+
export const FiresFinishedLoadingEvent: StoryObj<GenomeDataViewerProps> = {
|
|
80
|
+
...Default,
|
|
81
|
+
play: playThatExpectsFinishedLoadingEvent(),
|
|
82
|
+
};
|
|
83
|
+
|
|
78
84
|
export const InvalidProps: StoryObj<GenomeDataViewerProps> = {
|
|
79
85
|
...Default,
|
|
80
86
|
args: {
|
|
@@ -10,6 +10,7 @@ import { type MutationAnnotations } from '../../web-components/mutation-annotati
|
|
|
10
10
|
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
11
11
|
import { MutationAnnotationsContextProvider } from '../MutationAnnotationsContext';
|
|
12
12
|
import { ReferenceGenomeContext } from '../ReferenceGenomeContext';
|
|
13
|
+
import { playThatExpectsFinishedLoadingEvent } from '../shared/stories/expectFinishedLoadingEvent';
|
|
13
14
|
import { expectMutationAnnotation } from '../shared/stories/expectMutationAnnotation';
|
|
14
15
|
|
|
15
16
|
const dateToSomeDataset = '2022-01-01';
|
|
@@ -142,6 +143,11 @@ export const TwoVariants: StoryObj<MutationComparisonProps> = {
|
|
|
142
143
|
},
|
|
143
144
|
};
|
|
144
145
|
|
|
146
|
+
export const FiresFinishedLoadingEvent: StoryObj<MutationComparisonProps> = {
|
|
147
|
+
...TwoVariants,
|
|
148
|
+
play: playThatExpectsFinishedLoadingEvent(),
|
|
149
|
+
};
|
|
150
|
+
|
|
145
151
|
export const FilterForOnlyDeletions: StoryObj<MutationComparisonProps> = {
|
|
146
152
|
...TwoVariants,
|
|
147
153
|
play: async ({ canvasElement }) => {
|
|
@@ -7,6 +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 { useDispatchFinishedLoadingEvent } from '../../utils/useDispatchFinishedLoadingEvent';
|
|
10
11
|
import { useLapisUrl } from '../LapisUrlContext';
|
|
11
12
|
import { CsvDownloadButton } from '../components/csv-download-button';
|
|
12
13
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
@@ -80,6 +81,8 @@ type MutationComparisonTabsProps = {
|
|
|
80
81
|
};
|
|
81
82
|
|
|
82
83
|
const MutationComparisonTabs: FunctionComponent<MutationComparisonTabsProps> = ({ data, originalComponentProps }) => {
|
|
84
|
+
const tabsRef = useDispatchFinishedLoadingEvent();
|
|
85
|
+
|
|
83
86
|
const [proportionInterval, setProportionInterval] = useState({ min: 0.5, max: 1 });
|
|
84
87
|
const [displayedMutationTypes, setDisplayedMutationTypes] = useState<DisplayedMutationType[]>([
|
|
85
88
|
{ label: 'Substitutions', checked: true, type: 'substitution' },
|
|
@@ -127,6 +130,7 @@ const MutationComparisonTabs: FunctionComponent<MutationComparisonTabsProps> = (
|
|
|
127
130
|
|
|
128
131
|
return (
|
|
129
132
|
<Tabs
|
|
133
|
+
ref={tabsRef}
|
|
130
134
|
tabs={tabs}
|
|
131
135
|
toolbar={
|
|
132
136
|
<Toolbar
|
|
@@ -17,6 +17,7 @@ import { type MutationAnnotations } from '../../web-components/mutation-annotati
|
|
|
17
17
|
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
18
18
|
import { MutationAnnotationsContextProvider } from '../MutationAnnotationsContext';
|
|
19
19
|
import { ReferenceGenomeContext } from '../ReferenceGenomeContext';
|
|
20
|
+
import { playThatExpectsFinishedLoadingEvent } from '../shared/stories/expectFinishedLoadingEvent';
|
|
20
21
|
import { expectMutationAnnotation } from '../shared/stories/expectMutationAnnotation';
|
|
21
22
|
|
|
22
23
|
const meta: Meta<MutationsProps> = {
|
|
@@ -147,6 +148,11 @@ export const Default: StoryObj<MutationsProps> = {
|
|
|
147
148
|
},
|
|
148
149
|
};
|
|
149
150
|
|
|
151
|
+
export const FiresFinishedLoadingEvent: StoryObj<MutationsProps> = {
|
|
152
|
+
...Default,
|
|
153
|
+
play: playThatExpectsFinishedLoadingEvent(),
|
|
154
|
+
};
|
|
155
|
+
|
|
150
156
|
export const GridTab: StoryObj<MutationsProps> = {
|
|
151
157
|
...Default,
|
|
152
158
|
play: async ({ canvasElement, step }) => {
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
type SubstitutionOrDeletionEntry,
|
|
16
16
|
views,
|
|
17
17
|
} from '../../types';
|
|
18
|
+
import { useDispatchFinishedLoadingEvent } from '../../utils/useDispatchFinishedLoadingEvent';
|
|
18
19
|
import { useLapisUrl } from '../LapisUrlContext';
|
|
19
20
|
import { CsvDownloadButton } from '../components/csv-download-button';
|
|
20
21
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
@@ -87,6 +88,8 @@ type MutationTabsProps = {
|
|
|
87
88
|
};
|
|
88
89
|
|
|
89
90
|
const MutationsTabs: FunctionComponent<MutationTabsProps> = ({ mutationsData, originalComponentProps }) => {
|
|
91
|
+
const tabsRef = useDispatchFinishedLoadingEvent();
|
|
92
|
+
|
|
90
93
|
const [proportionInterval, setProportionInterval] = useState({ min: 0.05, max: 1 });
|
|
91
94
|
|
|
92
95
|
const [displayedSegments, setDisplayedSegments] = useDisplayedSegments(originalComponentProps.sequenceType);
|
|
@@ -153,7 +156,7 @@ const MutationsTabs: FunctionComponent<MutationTabsProps> = ({ mutationsData, or
|
|
|
153
156
|
/>
|
|
154
157
|
);
|
|
155
158
|
|
|
156
|
-
return <Tabs tabs={tabs} toolbar={toolbar} />;
|
|
159
|
+
return <Tabs ref={tabsRef} tabs={tabs} toolbar={toolbar} />;
|
|
157
160
|
};
|
|
158
161
|
|
|
159
162
|
type ToolbarProps = {
|
|
@@ -10,6 +10,7 @@ import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
|
10
10
|
import { MutationAnnotationsContextProvider } from '../MutationAnnotationsContext';
|
|
11
11
|
import { ReferenceGenomeContext } from '../ReferenceGenomeContext';
|
|
12
12
|
import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
13
|
+
import { playThatExpectsFinishedLoadingEvent } from '../shared/stories/expectFinishedLoadingEvent';
|
|
13
14
|
import { expectMutationAnnotation } from '../shared/stories/expectMutationAnnotation';
|
|
14
15
|
|
|
15
16
|
const meta: Meta<MutationsOverTimeProps> = {
|
|
@@ -83,6 +84,11 @@ export const Default: StoryObj<MutationsOverTimeProps> = {
|
|
|
83
84
|
},
|
|
84
85
|
};
|
|
85
86
|
|
|
87
|
+
export const FiresFinishedLoadingEvent: StoryObj<MutationsOverTimeProps> = {
|
|
88
|
+
...Default,
|
|
89
|
+
play: playThatExpectsFinishedLoadingEvent(),
|
|
90
|
+
};
|
|
91
|
+
|
|
86
92
|
export const ShowsMutationAnnotations: StoryObj<MutationsOverTimeProps> = {
|
|
87
93
|
...Default,
|
|
88
94
|
play: async ({ canvasElement }) => {
|
|
@@ -18,6 +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 { useDispatchFinishedLoadingEvent } from '../../utils/useDispatchFinishedLoadingEvent';
|
|
21
22
|
import { useLapisUrl } from '../LapisUrlContext';
|
|
22
23
|
import { useMutationAnnotationsProvider } from '../MutationAnnotationsContext';
|
|
23
24
|
import { type ColorScale } from '../components/color-scale-selector';
|
|
@@ -126,6 +127,8 @@ const MutationsOverTimeTabs: FunctionComponent<MutationOverTimeTabsProps> = ({
|
|
|
126
127
|
originalComponentProps,
|
|
127
128
|
overallMutationData,
|
|
128
129
|
}) => {
|
|
130
|
+
const tabsRef = useDispatchFinishedLoadingEvent();
|
|
131
|
+
|
|
129
132
|
const [mutationFilterValue, setMutationFilterValue] = useState('');
|
|
130
133
|
const annotationProvider = useMutationAnnotationsProvider();
|
|
131
134
|
|
|
@@ -207,7 +210,7 @@ const MutationsOverTimeTabs: FunctionComponent<MutationOverTimeTabsProps> = ({
|
|
|
207
210
|
|
|
208
211
|
return (
|
|
209
212
|
<PageSizeContextProvider pageSizes={originalComponentProps.pageSizes}>
|
|
210
|
-
<Tabs tabs={tabs} toolbar={toolbar} />
|
|
213
|
+
<Tabs ref={tabsRef} tabs={tabs} toolbar={toolbar} />
|
|
211
214
|
</PageSizeContextProvider>
|
|
212
215
|
);
|
|
213
216
|
};
|
|
@@ -2,7 +2,7 @@ import z from 'zod';
|
|
|
2
2
|
|
|
3
3
|
import { gsEventNames } from '../../utils/gsEventNames';
|
|
4
4
|
|
|
5
|
-
type LapisNumberFilter = Record<string, number | undefined>;
|
|
5
|
+
export type LapisNumberFilter = Record<string, number | undefined>;
|
|
6
6
|
|
|
7
7
|
export const numberRangeSchema = z.object({
|
|
8
8
|
min: z.number().optional(),
|
|
@@ -7,6 +7,7 @@ import twoVariantsEG from '../../preact/numberSequencesOverTime/__mockData__/two
|
|
|
7
7
|
import twoVariantsJN1 from '../../preact/numberSequencesOverTime/__mockData__/twoVariantsJN1.json';
|
|
8
8
|
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
9
9
|
import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
10
|
+
import { playThatExpectsFinishedLoadingEvent } from '../shared/stories/expectFinishedLoadingEvent';
|
|
10
11
|
|
|
11
12
|
export default {
|
|
12
13
|
title: 'Visualization/NumberSequencesOverTime',
|
|
@@ -71,8 +72,9 @@ const Template: StoryObj<NumberSequencesOverTimeProps> = {
|
|
|
71
72
|
},
|
|
72
73
|
};
|
|
73
74
|
|
|
74
|
-
export const
|
|
75
|
+
export const FiresFinishedLoadingEvent: StoryObj<NumberSequencesOverTimeProps> = {
|
|
75
76
|
...Template,
|
|
77
|
+
play: playThatExpectsFinishedLoadingEvent(),
|
|
76
78
|
};
|
|
77
79
|
|
|
78
80
|
export const TwoVariants: StoryObj<NumberSequencesOverTimeProps> = {
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
queryNumberOfSequencesOverTime,
|
|
12
12
|
} from '../../query/queryNumberOfSequencesOverTime';
|
|
13
13
|
import { namedLapisFilterSchema, temporalGranularitySchema, views } from '../../types';
|
|
14
|
+
import { useDispatchFinishedLoadingEvent } from '../../utils/useDispatchFinishedLoadingEvent';
|
|
14
15
|
import { useLapisUrl } from '../LapisUrlContext';
|
|
15
16
|
import { CsvDownloadButton } from '../components/csv-download-button';
|
|
16
17
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
@@ -88,6 +89,8 @@ interface NumberSequencesOverTimeTabsProps {
|
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
const NumberSequencesOverTimeTabs = ({ data, originalComponentProps }: NumberSequencesOverTimeTabsProps) => {
|
|
92
|
+
const tabsRef = useDispatchFinishedLoadingEvent();
|
|
93
|
+
|
|
91
94
|
const [yAxisScaleType, setYAxisScaleType] = useState<ScaleType>('linear');
|
|
92
95
|
|
|
93
96
|
const maintainAspectRatio = getMaintainAspectRatio(originalComponentProps.height);
|
|
@@ -134,6 +137,7 @@ const NumberSequencesOverTimeTabs = ({ data, originalComponentProps }: NumberSeq
|
|
|
134
137
|
|
|
135
138
|
return (
|
|
136
139
|
<Tabs
|
|
140
|
+
ref={tabsRef}
|
|
137
141
|
tabs={originalComponentProps.views.map((view) => getTab(view))}
|
|
138
142
|
toolbar={(activeTab) => (
|
|
139
143
|
<Toolbar
|
|
@@ -11,6 +11,7 @@ import numeratorOneDataset from './__mockData__/numeratorFilterOneDataset.json';
|
|
|
11
11
|
import { PrevalenceOverTime, type PrevalenceOverTimeProps } from './prevalence-over-time';
|
|
12
12
|
import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
13
13
|
import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
14
|
+
import { playThatExpectsFinishedLoadingEvent } from '../shared/stories/expectFinishedLoadingEvent';
|
|
14
15
|
|
|
15
16
|
export default {
|
|
16
17
|
title: 'Visualization/PrevalenceOverTime',
|
|
@@ -121,6 +122,11 @@ export const TwoVariants: StoryObj<PrevalenceOverTimeProps> = {
|
|
|
121
122
|
},
|
|
122
123
|
};
|
|
123
124
|
|
|
125
|
+
export const FiresFinishedLoadingEvent: StoryObj<PrevalenceOverTimeProps> = {
|
|
126
|
+
...TwoVariants,
|
|
127
|
+
play: playThatExpectsFinishedLoadingEvent(),
|
|
128
|
+
};
|
|
129
|
+
|
|
124
130
|
export const OneVariant: StoryObj<PrevalenceOverTimeProps> = {
|
|
125
131
|
...Template,
|
|
126
132
|
args: {
|
|
@@ -9,6 +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 { useDispatchFinishedLoadingEvent } from '../../utils/useDispatchFinishedLoadingEvent';
|
|
12
13
|
import { useLapisUrl } from '../LapisUrlContext';
|
|
13
14
|
import { ConfidenceIntervalSelector } from '../components/confidence-interval-selector';
|
|
14
15
|
import { CsvDownloadButton } from '../components/csv-download-button';
|
|
@@ -101,6 +102,8 @@ type PrevalenceOverTimeTabsProps = PrevalenceOverTimeProps & {
|
|
|
101
102
|
};
|
|
102
103
|
|
|
103
104
|
const PrevalenceOverTimeTabs: FunctionComponent<PrevalenceOverTimeTabsProps> = ({ data, ...componentProps }) => {
|
|
105
|
+
const tabsRef = useDispatchFinishedLoadingEvent();
|
|
106
|
+
|
|
104
107
|
const { views, granularity, confidenceIntervalMethods, pageSize, yAxisMaxLinear, yAxisMaxLogarithmic } =
|
|
105
108
|
componentProps;
|
|
106
109
|
const [yAxisScaleType, setYAxisScaleType] = useState<ScaleType>('linear');
|
|
@@ -182,7 +185,7 @@ const PrevalenceOverTimeTabs: FunctionComponent<PrevalenceOverTimeTabsProps> = (
|
|
|
182
185
|
/>
|
|
183
186
|
);
|
|
184
187
|
|
|
185
|
-
return <Tabs tabs={tabs} toolbar={toolbar} />;
|
|
188
|
+
return <Tabs ref={tabsRef} tabs={tabs} toolbar={toolbar} />;
|
|
186
189
|
};
|
|
187
190
|
|
|
188
191
|
type ToolbarProps = PrevalenceOverTimeProps & {
|
|
@@ -7,6 +7,7 @@ import { RelativeGrowthAdvantage, type RelativeGrowthAdvantageProps } from './re
|
|
|
7
7
|
import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
|
|
8
8
|
import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
9
9
|
import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
10
|
+
import { playThatExpectsFinishedLoadingEvent } from '../shared/stories/expectFinishedLoadingEvent';
|
|
10
11
|
|
|
11
12
|
export default {
|
|
12
13
|
title: 'Visualization/RelativeGrowthAdvantage',
|
|
@@ -90,6 +91,11 @@ export const Primary: StoryObj<RelativeGrowthAdvantageProps> = {
|
|
|
90
91
|
},
|
|
91
92
|
};
|
|
92
93
|
|
|
94
|
+
export const FiresFinishedLoadingEvent: StoryObj<RelativeGrowthAdvantageProps> = {
|
|
95
|
+
...Primary,
|
|
96
|
+
play: playThatExpectsFinishedLoadingEvent(),
|
|
97
|
+
};
|
|
98
|
+
|
|
93
99
|
export const TooFewDataToComputeGrowthAdvantage: StoryObj<RelativeGrowthAdvantageProps> = {
|
|
94
100
|
...Primary,
|
|
95
101
|
args: {
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type RelativeGrowthAdvantageData,
|
|
10
10
|
} from '../../query/queryRelativeGrowthAdvantage';
|
|
11
11
|
import { lapisFilterSchema, views } from '../../types';
|
|
12
|
+
import { useDispatchFinishedLoadingEvent } from '../../utils/useDispatchFinishedLoadingEvent';
|
|
12
13
|
import { useLapisUrl } from '../LapisUrlContext';
|
|
13
14
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
14
15
|
import { Fullscreen } from '../components/fullscreen';
|
|
@@ -103,6 +104,8 @@ const RelativeGrowthAdvantageTabs: FunctionComponent<RelativeGrowthAdvantageTabs
|
|
|
103
104
|
setYAxisScaleType,
|
|
104
105
|
originalComponentProps,
|
|
105
106
|
}) => {
|
|
107
|
+
const tabsRef = useDispatchFinishedLoadingEvent();
|
|
108
|
+
|
|
106
109
|
const maintainAspectRatio = getMaintainAspectRatio(originalComponentProps.height);
|
|
107
110
|
|
|
108
111
|
const getTab = (view: RelativeGrowthAdvantageView) => {
|
|
@@ -138,7 +141,7 @@ const RelativeGrowthAdvantageTabs: FunctionComponent<RelativeGrowthAdvantageTabs
|
|
|
138
141
|
/>
|
|
139
142
|
);
|
|
140
143
|
|
|
141
|
-
return <Tabs tabs={tabs} toolbar={toolbar} />;
|
|
144
|
+
return <Tabs ref={tabsRef} tabs={tabs} toolbar={toolbar} />;
|
|
142
145
|
};
|
|
143
146
|
|
|
144
147
|
type RelativeGrowthAdvantageToolbarProps = {
|
|
@@ -7,6 +7,7 @@ import { LapisUrlContextProvider } from '../LapisUrlContext';
|
|
|
7
7
|
import aggregatedWorld from './__mockData__/aggregatedWorld.json';
|
|
8
8
|
import { SequencesByLocation, type SequencesByLocationProps } from './sequences-by-location';
|
|
9
9
|
import { expectInvalidAttributesErrorMessage, playThatExpectsErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
10
|
+
import { playThatExpectsFinishedLoadingEvent } from '../shared/stories/expectFinishedLoadingEvent';
|
|
10
11
|
|
|
11
12
|
import 'leaflet/dist/leaflet.css';
|
|
12
13
|
import './leafletStyleModifications.css';
|
|
@@ -92,6 +93,11 @@ export const Default: StoryObj<SequencesByLocationProps> = {
|
|
|
92
93
|
},
|
|
93
94
|
};
|
|
94
95
|
|
|
96
|
+
export const FiresFinishedLoadingEvent: StoryObj<SequencesByLocationProps> = {
|
|
97
|
+
...Default,
|
|
98
|
+
play: playThatExpectsFinishedLoadingEvent(),
|
|
99
|
+
};
|
|
100
|
+
|
|
95
101
|
export const NoData: StoryObj<SequencesByLocationProps> = {
|
|
96
102
|
...Default,
|
|
97
103
|
parameters: {
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from '../../query/computeMapLocationData';
|
|
12
12
|
import { type AggregateData } from '../../query/queryAggregateData';
|
|
13
13
|
import { querySequencesByLocationData } from '../../query/querySequencesByLocationData';
|
|
14
|
+
import { useDispatchFinishedLoadingEvent } from '../../utils/useDispatchFinishedLoadingEvent';
|
|
14
15
|
import { CsvDownloadButton } from '../components/csv-download-button';
|
|
15
16
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
16
17
|
import { Fullscreen } from '../components/fullscreen';
|
|
@@ -93,6 +94,8 @@ const SequencesByLocationMapTabs: FunctionComponent<SequencesByLocationMapTabsPr
|
|
|
93
94
|
originalComponentProps,
|
|
94
95
|
data,
|
|
95
96
|
}) => {
|
|
97
|
+
const tabsRef = useDispatchFinishedLoadingEvent();
|
|
98
|
+
|
|
96
99
|
const maintainAspectRatio = getMaintainAspectRatio(originalComponentProps.height);
|
|
97
100
|
|
|
98
101
|
const getTab = (view: SequencesByLocationMapView) => {
|
|
@@ -136,6 +139,7 @@ const SequencesByLocationMapTabs: FunctionComponent<SequencesByLocationMapTabsPr
|
|
|
136
139
|
|
|
137
140
|
return (
|
|
138
141
|
<Tabs
|
|
142
|
+
ref={tabsRef}
|
|
139
143
|
tabs={tabs}
|
|
140
144
|
toolbar={<Toolbar originalComponentProps={originalComponentProps} tableData={data.tableData} />}
|
|
141
145
|
/>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { expect, fn, waitFor } from '@storybook/test';
|
|
2
|
+
|
|
3
|
+
import { gsEventNames } from '../../../utils/gsEventNames';
|
|
4
|
+
|
|
5
|
+
export function playThatExpectsFinishedLoadingEvent() {
|
|
6
|
+
return async ({ canvasElement }: { canvasElement: HTMLElement }) => {
|
|
7
|
+
const componentFinishedLoadingListenerMock = fn();
|
|
8
|
+
canvasElement.addEventListener(gsEventNames.componentFinishedLoading, componentFinishedLoadingListenerMock);
|
|
9
|
+
|
|
10
|
+
await waitFor(() => expect(componentFinishedLoadingListenerMock).toHaveBeenCalled());
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -6,6 +6,7 @@ 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';
|
|
9
|
+
import { playThatExpectsFinishedLoadingEvent } from '../shared/stories/expectFinishedLoadingEvent';
|
|
9
10
|
|
|
10
11
|
const meta: Meta<StatisticsProps> = {
|
|
11
12
|
title: 'Visualization/Statistics',
|
|
@@ -78,3 +79,8 @@ export const Default: StoryObj<StatisticsProps> = {
|
|
|
78
79
|
});
|
|
79
80
|
},
|
|
80
81
|
};
|
|
82
|
+
|
|
83
|
+
export const FiresFinishedLoadingEvent: StoryObj<StatisticsProps> = {
|
|
84
|
+
...Default,
|
|
85
|
+
play: playThatExpectsFinishedLoadingEvent(),
|
|
86
|
+
};
|