@genspectrum/dashboard-components 0.19.4 → 0.19.5
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/dist/components.d.ts +22 -22
- package/dist/components.js +34 -7
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +35 -22
- package/package.json +1 -1
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTimeData.ts +4 -2
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.stories.tsx +35 -1
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +40 -3
- package/src/utilEntrypoint.ts +2 -0
- package/standalone-bundle/dashboard-components.js +2218 -2196
- package/standalone-bundle/dashboard-components.js.map +1 -1
package/dist/util.d.ts
CHANGED
|
@@ -486,6 +486,19 @@ declare const namedLapisFilterSchema: default_2.ZodObject<{
|
|
|
486
486
|
displayName: string;
|
|
487
487
|
}>;
|
|
488
488
|
|
|
489
|
+
export declare type NumberRange = default_2.infer<typeof numberRangeSchema>;
|
|
490
|
+
|
|
491
|
+
declare const numberRangeSchema: default_2.ZodObject<{
|
|
492
|
+
min: default_2.ZodOptional<default_2.ZodNumber>;
|
|
493
|
+
max: default_2.ZodOptional<default_2.ZodNumber>;
|
|
494
|
+
}, "strip", default_2.ZodTypeAny, {
|
|
495
|
+
min?: number | undefined;
|
|
496
|
+
max?: number | undefined;
|
|
497
|
+
}, {
|
|
498
|
+
min?: number | undefined;
|
|
499
|
+
max?: number | undefined;
|
|
500
|
+
}>;
|
|
501
|
+
|
|
489
502
|
export declare type NumberSequencesOverTimeProps = default_2.infer<typeof numberSequencesOverTimePropsSchema>;
|
|
490
503
|
|
|
491
504
|
declare const numberSequencesOverTimePropsSchema: default_2.ZodObject<{
|
|
@@ -1058,11 +1071,7 @@ declare global {
|
|
|
1058
1071
|
|
|
1059
1072
|
declare global {
|
|
1060
1073
|
interface HTMLElementTagNameMap {
|
|
1061
|
-
'gs-
|
|
1062
|
-
}
|
|
1063
|
-
interface HTMLElementEventMap {
|
|
1064
|
-
[gsEventNames.dateRangeFilterChanged]: CustomEvent<Record<string, string>>;
|
|
1065
|
-
[gsEventNames.dateRangeOptionChanged]: DateRangeOptionChangedEvent;
|
|
1074
|
+
'gs-statistics': StatisticsComponent;
|
|
1066
1075
|
}
|
|
1067
1076
|
}
|
|
1068
1077
|
|
|
@@ -1070,7 +1079,7 @@ declare global {
|
|
|
1070
1079
|
declare global {
|
|
1071
1080
|
namespace JSX {
|
|
1072
1081
|
interface IntrinsicElements {
|
|
1073
|
-
'gs-
|
|
1082
|
+
'gs-statistics': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1074
1083
|
}
|
|
1075
1084
|
}
|
|
1076
1085
|
}
|
|
@@ -1078,10 +1087,7 @@ declare global {
|
|
|
1078
1087
|
|
|
1079
1088
|
declare global {
|
|
1080
1089
|
interface HTMLElementTagNameMap {
|
|
1081
|
-
'gs-
|
|
1082
|
-
}
|
|
1083
|
-
interface HTMLElementEventMap {
|
|
1084
|
-
[gsEventNames.locationChanged]: LocationChangedEvent;
|
|
1090
|
+
'gs-wastewater-mutations-over-time': WastewaterMutationsOverTimeComponent;
|
|
1085
1091
|
}
|
|
1086
1092
|
}
|
|
1087
1093
|
|
|
@@ -1089,7 +1095,7 @@ declare global {
|
|
|
1089
1095
|
declare global {
|
|
1090
1096
|
namespace JSX {
|
|
1091
1097
|
interface IntrinsicElements {
|
|
1092
|
-
'gs-
|
|
1098
|
+
'gs-wastewater-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1093
1099
|
}
|
|
1094
1100
|
}
|
|
1095
1101
|
}
|
|
@@ -1097,7 +1103,11 @@ declare global {
|
|
|
1097
1103
|
|
|
1098
1104
|
declare global {
|
|
1099
1105
|
interface HTMLElementTagNameMap {
|
|
1100
|
-
'gs-
|
|
1106
|
+
'gs-date-range-filter': DateRangeFilterComponent;
|
|
1107
|
+
}
|
|
1108
|
+
interface HTMLElementEventMap {
|
|
1109
|
+
[gsEventNames.dateRangeFilterChanged]: CustomEvent<Record<string, string>>;
|
|
1110
|
+
[gsEventNames.dateRangeOptionChanged]: DateRangeOptionChangedEvent;
|
|
1101
1111
|
}
|
|
1102
1112
|
}
|
|
1103
1113
|
|
|
@@ -1105,7 +1115,7 @@ declare global {
|
|
|
1105
1115
|
declare global {
|
|
1106
1116
|
namespace JSX {
|
|
1107
1117
|
interface IntrinsicElements {
|
|
1108
|
-
'gs-
|
|
1118
|
+
'gs-date-range-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1109
1119
|
}
|
|
1110
1120
|
}
|
|
1111
1121
|
}
|
|
@@ -1132,10 +1142,10 @@ declare global {
|
|
|
1132
1142
|
|
|
1133
1143
|
declare global {
|
|
1134
1144
|
interface HTMLElementTagNameMap {
|
|
1135
|
-
'gs-
|
|
1145
|
+
'gs-location-filter': LocationFilterComponent;
|
|
1136
1146
|
}
|
|
1137
1147
|
interface HTMLElementEventMap {
|
|
1138
|
-
[gsEventNames.
|
|
1148
|
+
[gsEventNames.locationChanged]: LocationChangedEvent;
|
|
1139
1149
|
}
|
|
1140
1150
|
}
|
|
1141
1151
|
|
|
@@ -1143,7 +1153,7 @@ declare global {
|
|
|
1143
1153
|
declare global {
|
|
1144
1154
|
namespace JSX {
|
|
1145
1155
|
interface IntrinsicElements {
|
|
1146
|
-
'gs-
|
|
1156
|
+
'gs-location-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1147
1157
|
}
|
|
1148
1158
|
}
|
|
1149
1159
|
}
|
|
@@ -1170,11 +1180,10 @@ declare global {
|
|
|
1170
1180
|
|
|
1171
1181
|
declare global {
|
|
1172
1182
|
interface HTMLElementTagNameMap {
|
|
1173
|
-
'gs-
|
|
1183
|
+
'gs-lineage-filter': LineageFilterComponent;
|
|
1174
1184
|
}
|
|
1175
1185
|
interface HTMLElementEventMap {
|
|
1176
|
-
[gsEventNames.
|
|
1177
|
-
[gsEventNames.numberRangeValueChanged]: NumberRangeValueChangedEvent;
|
|
1186
|
+
[gsEventNames.lineageFilterChanged]: LineageFilterChangedEvent;
|
|
1178
1187
|
}
|
|
1179
1188
|
}
|
|
1180
1189
|
|
|
@@ -1182,7 +1191,7 @@ declare global {
|
|
|
1182
1191
|
declare global {
|
|
1183
1192
|
namespace JSX {
|
|
1184
1193
|
interface IntrinsicElements {
|
|
1185
|
-
'gs-
|
|
1194
|
+
'gs-lineage-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1186
1195
|
}
|
|
1187
1196
|
}
|
|
1188
1197
|
}
|
|
@@ -1190,7 +1199,11 @@ declare global {
|
|
|
1190
1199
|
|
|
1191
1200
|
declare global {
|
|
1192
1201
|
interface HTMLElementTagNameMap {
|
|
1193
|
-
'gs-
|
|
1202
|
+
'gs-number-range-filter': NumberRangeFilterComponent;
|
|
1203
|
+
}
|
|
1204
|
+
interface HTMLElementEventMap {
|
|
1205
|
+
[gsEventNames.numberRangeFilterChanged]: NumberRangeFilterChangedEvent;
|
|
1206
|
+
[gsEventNames.numberRangeValueChanged]: NumberRangeValueChangedEvent;
|
|
1194
1207
|
}
|
|
1195
1208
|
}
|
|
1196
1209
|
|
|
@@ -1198,7 +1211,7 @@ declare global {
|
|
|
1198
1211
|
declare global {
|
|
1199
1212
|
namespace JSX {
|
|
1200
1213
|
interface IntrinsicElements {
|
|
1201
|
-
'gs-
|
|
1214
|
+
'gs-number-range-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1202
1215
|
}
|
|
1203
1216
|
}
|
|
1204
1217
|
}
|
package/package.json
CHANGED
|
@@ -51,7 +51,9 @@ export function getFilteredMutationOverTimeData({
|
|
|
51
51
|
return true;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
if (
|
|
54
|
+
if (
|
|
55
|
+
mutationOrAnnotationDoNotMatchFilter(entry.mutation, sequenceType, mutationFilterValue, annotationProvider)
|
|
56
|
+
) {
|
|
55
57
|
return true;
|
|
56
58
|
}
|
|
57
59
|
|
|
@@ -67,7 +69,7 @@ export function getFilteredMutationOverTimeData({
|
|
|
67
69
|
return filteredData;
|
|
68
70
|
}
|
|
69
71
|
|
|
70
|
-
export function
|
|
72
|
+
export function mutationOrAnnotationDoNotMatchFilter(
|
|
71
73
|
mutation: Mutation,
|
|
72
74
|
sequenceType: SequenceType,
|
|
73
75
|
filterValue: string,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Meta, type StoryObj } from '@storybook/preact';
|
|
2
|
-
import { expect, userEvent } from '@storybook/test';
|
|
2
|
+
import { expect, userEvent, waitFor } from '@storybook/test';
|
|
3
|
+
import type { Canvas } from '@storybook/types';
|
|
3
4
|
|
|
4
5
|
import { WastewaterMutationsOverTime, type WastewaterMutationsOverTimeProps } from './wastewater-mutations-over-time';
|
|
5
6
|
import { WISE_DETAILS_ENDPOINT, WISE_LAPIS_URL } from '../../../constants';
|
|
@@ -7,6 +8,7 @@ import referenceGenome from '../../../lapisApi/__mockData__/referenceGenome.json
|
|
|
7
8
|
import { LapisUrlContextProvider } from '../../LapisUrlContext';
|
|
8
9
|
import { ReferenceGenomeContext } from '../../ReferenceGenomeContext';
|
|
9
10
|
import details from './__mockData__/details.json';
|
|
11
|
+
import type { MutationsOverTimeProps } from '../../mutationsOverTime/mutations-over-time';
|
|
10
12
|
|
|
11
13
|
const meta: Meta<WastewaterMutationsOverTimeProps> = {
|
|
12
14
|
title: 'Wastewater visualization/Wastewater mutations over time',
|
|
@@ -108,3 +110,35 @@ export const AminoAcids: StoryObj<WastewaterMutationsOverTimeProps> = {
|
|
|
108
110
|
});
|
|
109
111
|
},
|
|
110
112
|
};
|
|
113
|
+
|
|
114
|
+
export const UsesMutationFilter: StoryObj<MutationsOverTimeProps> = {
|
|
115
|
+
...Default,
|
|
116
|
+
play: async ({ canvas, step }) => {
|
|
117
|
+
await expectMutationOnPage(canvas, 'A966C');
|
|
118
|
+
|
|
119
|
+
await step('input filter', async () => {
|
|
120
|
+
const filterButton = canvas.getByRole('button', { name: 'Filter mutations' });
|
|
121
|
+
await userEvent.click(filterButton);
|
|
122
|
+
|
|
123
|
+
const filterInput = canvas.getByPlaceholderText('Filter');
|
|
124
|
+
await userEvent.type(filterInput, '26');
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
await step('should show only matching filter', async () => {
|
|
128
|
+
await expectMutationOnPage(canvas, 'T4026G');
|
|
129
|
+
await expectMutationOnPage(canvas, 'T5260C');
|
|
130
|
+
|
|
131
|
+
await waitFor(async () => {
|
|
132
|
+
const filteredMutation = canvas.queryByText('A966C');
|
|
133
|
+
await expect(filteredMutation).not.toBeInTheDocument();
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
async function expectMutationOnPage(canvas: Canvas, mutation: string) {
|
|
140
|
+
await waitFor(async () => {
|
|
141
|
+
const mutationOnFirstPage = canvas.getAllByText(mutation)[0];
|
|
142
|
+
await expect(mutationOnFirstPage).toBeVisible();
|
|
143
|
+
});
|
|
144
|
+
}
|
|
@@ -3,20 +3,23 @@ import { type Dispatch, type StateUpdater, useMemo, useState } from 'preact/hook
|
|
|
3
3
|
import z from 'zod';
|
|
4
4
|
|
|
5
5
|
import { computeWastewaterMutationsOverTimeDataPerLocation } from './computeWastewaterMutationsOverTimeDataPerLocation';
|
|
6
|
-
import { lapisFilterSchema, sequenceTypeSchema } from '../../../types';
|
|
6
|
+
import { lapisFilterSchema, type SequenceType, sequenceTypeSchema } from '../../../types';
|
|
7
7
|
import { Map2dView } from '../../../utils/map2d';
|
|
8
8
|
import { useLapisUrl } from '../../LapisUrlContext';
|
|
9
|
+
import { useMutationAnnotationsProvider } from '../../MutationAnnotationsContext';
|
|
9
10
|
import { type ColorScale } from '../../components/color-scale-selector';
|
|
10
11
|
import { ColorScaleSelectorDropdown } from '../../components/color-scale-selector-dropdown';
|
|
11
12
|
import { ErrorBoundary } from '../../components/error-boundary';
|
|
12
13
|
import { Fullscreen } from '../../components/fullscreen';
|
|
13
14
|
import Info, { InfoComponentCode, InfoHeadline1, InfoParagraph } from '../../components/info';
|
|
14
15
|
import { LoadingDisplay } from '../../components/loading-display';
|
|
16
|
+
import { MutationsOverTimeTextFilter } from '../../components/mutations-over-time-text-filter';
|
|
15
17
|
import { NoDataDisplay } from '../../components/no-data-display';
|
|
16
18
|
import { ResizeContainer } from '../../components/resize-container';
|
|
17
19
|
import { type DisplayedSegment, SegmentSelector } from '../../components/segment-selector';
|
|
18
20
|
import Tabs from '../../components/tabs';
|
|
19
21
|
import { type MutationOverTimeDataMap } from '../../mutationsOverTime/MutationOverTimeData';
|
|
22
|
+
import { mutationOrAnnotationDoNotMatchFilter } from '../../mutationsOverTime/getFilteredMutationsOverTimeData';
|
|
20
23
|
import MutationsOverTimeGrid from '../../mutationsOverTime/mutations-over-time-grid';
|
|
21
24
|
import { pageSizesSchema } from '../../shared/tanstackTable/pagination';
|
|
22
25
|
import { PageSizeContextProvider } from '../../shared/tanstackTable/pagination-context';
|
|
@@ -111,13 +114,23 @@ type MutationOverTimeTabsProps = {
|
|
|
111
114
|
function getFilteredMutationOverTimeData({
|
|
112
115
|
data,
|
|
113
116
|
displayedSegments,
|
|
117
|
+
mutationFilterValue,
|
|
118
|
+
annotationProvider,
|
|
119
|
+
sequenceType,
|
|
114
120
|
}: {
|
|
115
121
|
data: MutationOverTimeDataMap;
|
|
116
122
|
displayedSegments: DisplayedSegment[];
|
|
123
|
+
mutationFilterValue: string;
|
|
124
|
+
sequenceType: SequenceType;
|
|
125
|
+
annotationProvider: ReturnType<typeof useMutationAnnotationsProvider>;
|
|
117
126
|
}): MutationOverTimeDataMap {
|
|
118
127
|
const filteredData = new Map2dView(data);
|
|
119
128
|
|
|
120
129
|
const mutationsToFilterOut = data.getFirstAxisKeys().filter((entry) => {
|
|
130
|
+
if (mutationOrAnnotationDoNotMatchFilter(entry, sequenceType, mutationFilterValue, annotationProvider)) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
|
|
121
134
|
return displayedSegments.some((segment) => segment.segment === entry.segment && !segment.checked);
|
|
122
135
|
});
|
|
123
136
|
|
|
@@ -132,6 +145,9 @@ const MutationsOverTimeTabs: FunctionComponent<MutationOverTimeTabsProps> = ({
|
|
|
132
145
|
mutationOverTimeDataPerLocation,
|
|
133
146
|
originalComponentProps,
|
|
134
147
|
}) => {
|
|
148
|
+
const [mutationFilterValue, setMutationFilterValue] = useState('');
|
|
149
|
+
const annotationProvider = useMutationAnnotationsProvider();
|
|
150
|
+
|
|
135
151
|
const [colorScale, setColorScale] = useState<ColorScale>({ min: 0, max: 1, color: 'indigo' });
|
|
136
152
|
const [displayedSegments, setDisplayedSegments] = useDisplayedSegments(mutationOverTimeDataPerLocation);
|
|
137
153
|
|
|
@@ -141,14 +157,28 @@ const MutationsOverTimeTabs: FunctionComponent<MutationOverTimeTabsProps> = ({
|
|
|
141
157
|
title: location,
|
|
142
158
|
content: (
|
|
143
159
|
<MutationsOverTimeGrid
|
|
144
|
-
data={getFilteredMutationOverTimeData({
|
|
160
|
+
data={getFilteredMutationOverTimeData({
|
|
161
|
+
data,
|
|
162
|
+
displayedSegments,
|
|
163
|
+
mutationFilterValue,
|
|
164
|
+
annotationProvider,
|
|
165
|
+
sequenceType: originalComponentProps.sequenceType,
|
|
166
|
+
})}
|
|
145
167
|
colorScale={colorScale}
|
|
146
168
|
pageSizes={originalComponentProps.pageSizes}
|
|
147
169
|
sequenceType={originalComponentProps.sequenceType}
|
|
148
170
|
/>
|
|
149
171
|
),
|
|
150
172
|
})),
|
|
151
|
-
[
|
|
173
|
+
[
|
|
174
|
+
mutationOverTimeDataPerLocation,
|
|
175
|
+
displayedSegments,
|
|
176
|
+
mutationFilterValue,
|
|
177
|
+
annotationProvider,
|
|
178
|
+
colorScale,
|
|
179
|
+
originalComponentProps.pageSizes,
|
|
180
|
+
originalComponentProps.sequenceType,
|
|
181
|
+
],
|
|
152
182
|
);
|
|
153
183
|
|
|
154
184
|
const toolbar = (
|
|
@@ -159,6 +189,8 @@ const MutationsOverTimeTabs: FunctionComponent<MutationOverTimeTabsProps> = ({
|
|
|
159
189
|
data={mutationOverTimeDataPerLocation}
|
|
160
190
|
displayedSegments={displayedSegments}
|
|
161
191
|
setDisplayedSegments={setDisplayedSegments}
|
|
192
|
+
setFilterValue={setMutationFilterValue}
|
|
193
|
+
mutationFilterValue={mutationFilterValue}
|
|
162
194
|
/>
|
|
163
195
|
);
|
|
164
196
|
|
|
@@ -176,6 +208,8 @@ type ToolbarProps = {
|
|
|
176
208
|
data: MutationOverTimeDataPerLocation;
|
|
177
209
|
displayedSegments: DisplayedSegment[];
|
|
178
210
|
setDisplayedSegments: (segments: DisplayedSegment[]) => void;
|
|
211
|
+
mutationFilterValue: string;
|
|
212
|
+
setFilterValue: (filterValue: string) => void;
|
|
179
213
|
};
|
|
180
214
|
|
|
181
215
|
const Toolbar: FunctionComponent<ToolbarProps> = ({
|
|
@@ -184,9 +218,12 @@ const Toolbar: FunctionComponent<ToolbarProps> = ({
|
|
|
184
218
|
originalComponentProps,
|
|
185
219
|
displayedSegments,
|
|
186
220
|
setDisplayedSegments,
|
|
221
|
+
setFilterValue,
|
|
222
|
+
mutationFilterValue,
|
|
187
223
|
}) => {
|
|
188
224
|
return (
|
|
189
225
|
<>
|
|
226
|
+
<MutationsOverTimeTextFilter setFilterValue={setFilterValue} value={mutationFilterValue} />
|
|
190
227
|
<ColorScaleSelectorDropdown colorScale={colorScale} setColorScale={setColorScale} />
|
|
191
228
|
<SegmentSelector
|
|
192
229
|
displayedSegments={displayedSegments}
|
package/src/utilEntrypoint.ts
CHANGED
|
@@ -40,3 +40,5 @@ export { TextFilterChangedEvent } from './preact/textFilter/TextFilterChangedEve
|
|
|
40
40
|
export type { MutationAnnotations, MutationAnnotation } from './web-components/mutation-annotations-context';
|
|
41
41
|
|
|
42
42
|
export { gsEventNames } from './utils/gsEventNames';
|
|
43
|
+
|
|
44
|
+
export { type NumberRange } from './preact/numberRangeFilter/NumberRangeFilterChangedEvent';
|