@genspectrum/dashboard-components 1.8.0 → 1.8.1

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/util.d.ts CHANGED
@@ -1069,7 +1069,7 @@ declare global {
1069
1069
 
1070
1070
  declare global {
1071
1071
  interface HTMLElementTagNameMap {
1072
- 'gs-sequences-by-location': SequencesByLocationComponent;
1072
+ 'gs-statistics': StatisticsComponent;
1073
1073
  }
1074
1074
  }
1075
1075
 
@@ -1077,7 +1077,7 @@ declare global {
1077
1077
  declare global {
1078
1078
  namespace JSX {
1079
1079
  interface IntrinsicElements {
1080
- 'gs-sequences-by-location': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1080
+ 'gs-statistics': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1081
1081
  }
1082
1082
  }
1083
1083
  }
@@ -1085,7 +1085,7 @@ declare global {
1085
1085
 
1086
1086
  declare global {
1087
1087
  interface HTMLElementTagNameMap {
1088
- 'gs-statistics': StatisticsComponent;
1088
+ 'gs-sequences-by-location': SequencesByLocationComponent;
1089
1089
  }
1090
1090
  }
1091
1091
 
@@ -1093,7 +1093,7 @@ declare global {
1093
1093
  declare global {
1094
1094
  namespace JSX {
1095
1095
  interface IntrinsicElements {
1096
- 'gs-statistics': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1096
+ 'gs-sequences-by-location': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1097
1097
  }
1098
1098
  }
1099
1099
  }
@@ -1137,10 +1137,10 @@ declare global {
1137
1137
 
1138
1138
  declare global {
1139
1139
  interface HTMLElementTagNameMap {
1140
- 'gs-text-filter': TextFilterComponent;
1140
+ 'gs-location-filter': LocationFilterComponent;
1141
1141
  }
1142
1142
  interface HTMLElementEventMap {
1143
- [gsEventNames.textFilterChanged]: TextFilterChangedEvent;
1143
+ [gsEventNames.locationChanged]: LocationChangedEvent;
1144
1144
  }
1145
1145
  }
1146
1146
 
@@ -1148,7 +1148,7 @@ declare global {
1148
1148
  declare global {
1149
1149
  namespace JSX {
1150
1150
  interface IntrinsicElements {
1151
- 'gs-text-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1151
+ 'gs-location-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1152
1152
  }
1153
1153
  }
1154
1154
  }
@@ -1156,10 +1156,10 @@ declare global {
1156
1156
 
1157
1157
  declare global {
1158
1158
  interface HTMLElementTagNameMap {
1159
- 'gs-location-filter': LocationFilterComponent;
1159
+ 'gs-text-filter': TextFilterComponent;
1160
1160
  }
1161
1161
  interface HTMLElementEventMap {
1162
- [gsEventNames.locationChanged]: LocationChangedEvent;
1162
+ [gsEventNames.textFilterChanged]: TextFilterChangedEvent;
1163
1163
  }
1164
1164
  }
1165
1165
 
@@ -1167,7 +1167,7 @@ declare global {
1167
1167
  declare global {
1168
1168
  namespace JSX {
1169
1169
  interface IntrinsicElements {
1170
- 'gs-location-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1170
+ 'gs-text-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1171
1171
  }
1172
1172
  }
1173
1173
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genspectrum/dashboard-components",
3
- "version": "1.8.0",
3
+ "version": "1.8.1",
4
4
  "description": "GenSpectrum web components for building dashboards",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-only",
@@ -0,0 +1,88 @@
1
+ {
2
+ "data": [
3
+ {
4
+ "aminoAcidMutationFrequency": null,
5
+ "date": "2024-11-13",
6
+ "location": "Lugano",
7
+ "nucleotideMutationFrequency": "{\"A12183T\": null, \"C2554T\": null, \"C3422A\": 0.9598659873008728, \"A966C\": null, \"G6661A\": 0.5527499914169312, \"G7731A\": 0.9832900166511536, \"T4026G\": 0.9991809725761414, \"T5260C\": null, \"T5287C\": null}",
8
+ "reference": "RSV-B"
9
+ },
10
+ {
11
+ "aminoAcidMutationFrequency": null,
12
+ "date": "2024-11-17",
13
+ "location": "Genève",
14
+ "nucleotideMutationFrequency": "{\"A12183T\": 1.0, \"C2554T\": null, \"C3422A\": 0.0, \"A966C\": null, \"G6661A\": 0.8785049915313721, \"G7731A\": 0.9855599999427795, \"T4026G\": null, \"T5260C\": 1.0, \"T5287C\": 0.9932659864425659}",
15
+ "reference": "RSV-B"
16
+ },
17
+ {
18
+ "aminoAcidMutationFrequency": "{\"S4286C\": null, \"R346T\": 0.25, \"Q493E\": 0.60, \"G204P\": null}",
19
+ "date": "2024-11-17",
20
+ "location": "Lugano",
21
+ "nucleotideMutationFrequency": "{\"A12183T\": 0.998993992805481, \"C2554T\": null, \"C3422A\": null, \"A966C\": null, \"G6661A\": 0.8917459845542908, \"G7731A\": 0.9770470261573792, \"T4026G\": 0.0, \"T5260C\": null, \"T5287C\": null}",
22
+ "reference": "RSV-B"
23
+ },
24
+ {
25
+ "aminoAcidMutationFrequency": "{\"S4286C\": 0.42, \"R346T\": 0.22, \"Q493E\": 0.66, \"G204P\": null}",
26
+ "date": "2024-11-16",
27
+ "location": "Lugano",
28
+ "nucleotideMutationFrequency": "{\"A12183T\": null, \"C2554T\": null, \"C3422A\": null, \"A966C\": null, \"G6661A\": 0.9476320147514343, \"G7731A\": 0.9809200167655945, \"T4026G\": 0.9992259740829468, \"T5260C\": null, \"T5287C\": null}",
29
+ "reference": "RSV-B"
30
+ },
31
+ {
32
+ "aminoAcidMutationFrequency": null,
33
+ "date": "2024-11-18",
34
+ "location": "Genève",
35
+ "nucleotideMutationFrequency": "{\"A12183T\": null, \"C2554T\": 0.9978219866752625, \"C3422A\": null, \"A966C\": 1.0, \"G6661A\": null, \"G7731A\": null, \"T4026G\": null, \"T5260C\": null, \"T5287C\": null}",
36
+ "reference": "RSV-B"
37
+ },
38
+ {
39
+ "aminoAcidMutationFrequency": null,
40
+ "date": "2024-11-14",
41
+ "location": "Genève",
42
+ "nucleotideMutationFrequency": "{\"A12183T\": null, \"C2554T\": 0.9994590282440186, \"C3422A\": 0.05333299934864044, \"A966C\": 1.0, \"G6661A\": 0.9282640218734741, \"G7731A\": 0.9803630113601685, \"T4026G\": 0.0, \"T5260C\": 0.9970409870147705, \"T5287C\": 0.996694028377533}",
43
+ "reference": "RSV-B"
44
+ },
45
+ {
46
+ "aminoAcidMutationFrequency": null,
47
+ "date": "2024-11-13",
48
+ "location": "Laupen",
49
+ "nucleotideMutationFrequency": "{\"A12668G\": null, \"A3564G\": null, \"C10862T\": null, \"C12710T\": null, \"C3624T\": null, \"G11123A\": null, \"G3616A\": null, \"G7379A\": 0.9470750093460083, \"T11034A\": null, \"T3483C\": null}",
50
+ "reference": "RSV-A"
51
+ },
52
+ {
53
+ "aminoAcidMutationFrequency": null,
54
+ "date": "2024-11-13",
55
+ "location": "Zürich",
56
+ "nucleotideMutationFrequency": "{\"A12668G\": 0.9988809823989868, \"A3564G\": null, \"C10862T\": 1.0, \"C12710T\": 0.9991809725761414, \"C3624T\": null, \"G11123A\": 1.0, \"G3616A\": null, \"G7379A\": 0.9414680004119873, \"T11034A\": 0.9988250136375427, \"T3483C\": null}",
57
+ "reference": "RSV-A"
58
+ },
59
+ {
60
+ "aminoAcidMutationFrequency": null,
61
+ "date": "2024-11-16",
62
+ "location": "Zürich",
63
+ "nucleotideMutationFrequency": "{\"A12668G\": 0.999222993850708, \"A3564G\": 0.9998199939727783, \"C10862T\": 1.0, \"C12710T\": 0.9996299743652344, \"C3624T\": 0.9999099969863892, \"G11123A\": 1.0, \"G3616A\": 0.08799900114536285, \"G7379A\": null, \"T11034A\": 0.9970099925994873, \"T3483C\": 0.9993579983711243}",
64
+ "reference": "RSV-A"
65
+ },
66
+ {
67
+ "aminoAcidMutationFrequency": null,
68
+ "date": "2024-11-16",
69
+ "location": "Chur",
70
+ "nucleotideMutationFrequency": "{\"A12668G\": null, \"A3564G\": null, \"C10862T\": null, \"C12710T\": null, \"C3624T\": null, \"G11123A\": null, \"G3616A\": null, \"G7379A\": 0.6464089751243591, \"T11034A\": null, \"T3483C\": null}",
71
+ "reference": "RSV-A"
72
+ },
73
+ {
74
+ "aminoAcidMutationFrequency": null,
75
+ "date": "2024-11-18",
76
+ "location": "Basel",
77
+ "nucleotideMutationFrequency": "{\"A12668G\": null, \"A3564G\": 1.0, \"C10862T\": null, \"C12710T\": null, \"C3624T\": 1.0, \"G11123A\": null, \"G3616A\": 0.08222199976444244, \"G7379A\": null, \"T11034A\": null, \"T3483C\": 0.9998080134391785}",
78
+ "reference": "RSV-A"
79
+ }
80
+ ],
81
+ "info": {
82
+ "dataVersion": "1737327031",
83
+ "requestId": "5591b455-3d84-438c-8434-2e57ee2ad569",
84
+ "requestInfo": "RSV on api.wise-loculus.genspectrum.org at 2025-01-20T11:58:03.498206810",
85
+ "reportTo": "Please report to https://github.com/GenSpectrum/LAPIS/issues in case you encounter any unexpected issues. Please include the request ID and the requestInfo in your report.",
86
+ "lapisVersion": "0.3.10"
87
+ }
88
+ }
@@ -8,6 +8,7 @@ import referenceGenome from '../../../lapisApi/__mockData__/referenceGenome.json
8
8
  import { LapisUrlContextProvider } from '../../LapisUrlContext';
9
9
  import { ReferenceGenomeContext } from '../../ReferenceGenomeContext';
10
10
  import details from './__mockData__/details.json';
11
+ import detailsNonSegmented from './__mockData__/detailsAminAcidNonSegmented.json';
11
12
  import type { MutationsOverTimeProps } from '../../mutationsOverTime/mutations-over-time';
12
13
  import { playThatExpectsFinishedLoadingEvent } from '../../shared/stories/expectFinishedLoadingEvent';
13
14
 
@@ -113,6 +114,39 @@ export const AminoAcids: StoryObj<WastewaterMutationsOverTimeProps> = {
113
114
  },
114
115
  };
115
116
 
117
+ export const AminoAcidsNonSegmented: StoryObj<WastewaterMutationsOverTimeProps> = {
118
+ ...Default,
119
+ args: {
120
+ ...Default.args,
121
+ sequenceType: 'amino acid',
122
+ },
123
+ parameters: {
124
+ fetchMock: {
125
+ mocks: [
126
+ {
127
+ matcher: {
128
+ name: 'details',
129
+ url: WISE_DETAILS_ENDPOINT,
130
+ body: {
131
+ fields: ['date', 'location', 'nucleotideMutationFrequency', 'aminoAcidMutationFrequency'],
132
+ },
133
+ },
134
+ response: {
135
+ status: 200,
136
+ body: detailsNonSegmented,
137
+ },
138
+ },
139
+ ],
140
+ },
141
+ },
142
+ play: async ({ canvas }) => {
143
+ await expectMutationOnPage(canvas, 'G204P');
144
+ await expectMutationOnPage(canvas, 'R346T');
145
+ await expectMutationOnPage(canvas, 'Q493E');
146
+ await expectMutationOnPage(canvas, 'S4286C');
147
+ },
148
+ };
149
+
116
150
  export const UsesMutationFilter: StoryObj<MutationsOverTimeProps> = {
117
151
  ...Default,
118
152
  play: async ({ canvas, step }) => {
@@ -57,7 +57,7 @@ function transformMutations(input: unknown): { mutation: Substitution; proportio
57
57
  }
58
58
 
59
59
  return Object.entries(mutationFrequency.data).map(([key, value]) => {
60
- const mutation = SubstitutionClass.parse(key);
60
+ const mutation = SubstitutionClass.parse(key, true);
61
61
  if (mutation === null) {
62
62
  throw new Error(`Failed to parse mutation: "${key}"`);
63
63
  }
@@ -17,15 +17,19 @@ export interface MutationClass extends Mutation {
17
17
  const nucleotideChars = 'ACGTRYKMSWBDHVN';
18
18
  const aminoAcidChars = 'ACDEFGHIKLMNPQRSTVWY';
19
19
 
20
- function segmentPart(type: 'nucleotide' | 'aminoAcid') {
21
- return type === 'aminoAcid' ? `(?<segment>[A-Z0-9_-]+):` : `((?<segment>[A-Z0-9_-]+)(?=:):)?`;
20
+ function segmentPart(isOptional: boolean) {
21
+ const segmentPart = `(?<segment>[A-Z0-9_-]+):`;
22
+ if (isOptional) {
23
+ return `(${segmentPart})?`;
24
+ }
25
+ return segmentPart;
22
26
  }
23
27
 
24
- function buildSubstitutionRegex(type: 'nucleotide' | 'aminoAcid') {
28
+ function buildSubstitutionRegex(type: 'nucleotide' | 'aminoAcid', segmentPartIsOptional: boolean) {
25
29
  const chars = type === 'nucleotide' ? nucleotideChars : aminoAcidChars;
26
30
 
27
31
  return new RegExp(
28
- `^${segmentPart(type)}` +
32
+ `^${segmentPart(segmentPartIsOptional)}` +
29
33
  `(?<valueAtReference>[${chars}*])?` +
30
34
  `(?<position>\\d+)` +
31
35
  `(?<substitutionValue>[${chars}.*])?$`,
@@ -33,8 +37,9 @@ function buildSubstitutionRegex(type: 'nucleotide' | 'aminoAcid') {
33
37
  );
34
38
  }
35
39
 
36
- const nucleotideSubstitutionRegex = buildSubstitutionRegex('nucleotide');
37
- const aminoAcidSubstitutionRegex = buildSubstitutionRegex('aminoAcid');
40
+ const nucleotideSubstitutionRegex = buildSubstitutionRegex('nucleotide', true);
41
+ const aminoAcidSubstitutionRegex = buildSubstitutionRegex('aminoAcid', false);
42
+ const aminoAcidSubstitutionWithoutSegmentRegex = buildSubstitutionRegex('aminoAcid', true);
38
43
 
39
44
  export interface Substitution extends Mutation {
40
45
  type: 'substitution';
@@ -74,10 +79,13 @@ export class SubstitutionClass implements MutationClass, Substitution {
74
79
  return this.code;
75
80
  }
76
81
 
77
- static parse(mutationStr: string): SubstitutionClass | null {
82
+ static parse(mutationStr: string, segmentIsOptional: boolean = false): SubstitutionClass | null {
78
83
  const matchNucleotide = nucleotideSubstitutionRegex.exec(mutationStr);
79
84
  const matchAminoAcid = aminoAcidSubstitutionRegex.exec(mutationStr);
80
- const match = matchNucleotide ?? matchAminoAcid;
85
+ const matchAminAcidWithoutSegment = segmentIsOptional
86
+ ? aminoAcidSubstitutionWithoutSegmentRegex.exec(mutationStr)
87
+ : undefined;
88
+ const match = matchNucleotide ?? matchAminoAcid ?? matchAminAcidWithoutSegment;
81
89
  if (match?.groups === undefined) {
82
90
  return null;
83
91
  }
@@ -94,7 +102,7 @@ function buildDeletionRegex(type: 'nucleotide' | 'aminoAcid') {
94
102
  const chars = type === 'nucleotide' ? nucleotideChars : aminoAcidChars;
95
103
 
96
104
  return new RegExp(
97
- `^${segmentPart(type)}` + `(?<valueAtReference>[${chars}*])?` + `(?<position>\\d+)` + `(-)$`,
105
+ `^${segmentPart(type === 'nucleotide')}` + `(?<valueAtReference>[${chars}*])?` + `(?<position>\\d+)` + `(-)$`,
98
106
  'i',
99
107
  );
100
108
  }
@@ -158,7 +166,7 @@ function buildInsertionRegex(type: 'nucleotide' | 'aminoAcid') {
158
166
  const wildcardToken = `(?:\\.\\*)`;
159
167
 
160
168
  return new RegExp(
161
- `^ins_${segmentPart(type)}(?<position>\\d+):(?<insertedSymbols>(?:[${chars}?*]|${wildcardToken})+)$`,
169
+ `^ins_${segmentPart(type === 'nucleotide')}(?<position>\\d+):(?<insertedSymbols>(?:[${chars}?*]|${wildcardToken})+)$`,
162
170
  'i',
163
171
  );
164
172
  }