@genspectrum/dashboard-components 0.18.2 → 0.18.4
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 +2 -2
- package/dist/assets/{mutationOverTimeWorker-ChQTFL68.js.map → mutationOverTimeWorker--b8ZHlji.js.map} +1 -1
- package/dist/components.d.ts +62 -54
- package/dist/components.js +114 -39
- package/dist/components.js.map +1 -1
- package/dist/style.css +2 -2
- package/dist/util.d.ts +70 -58
- package/package.json +4 -4
- package/src/preact/MutationAnnotationsContext.spec.tsx +103 -34
- package/src/preact/MutationAnnotationsContext.tsx +49 -7
- package/src/preact/components/annotated-mutation.stories.tsx +0 -5
- package/src/preact/components/annotated-mutation.tsx +6 -2
- package/src/preact/mutationComparison/mutation-comparison.stories.tsx +3 -1
- package/src/preact/mutations/mutations.stories.tsx +4 -1
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +3 -1
- package/src/preact/sequencesByLocation/leafletStyleModifications.css +5 -0
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.stories.tsx +25 -0
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +65 -13
- package/src/web-components/MutationAnnotations.mdx +8 -0
- package/src/web-components/gs-app.stories.ts +2 -0
- package/src/web-components/gs-app.ts +4 -2
- package/src/web-components/mutation-annotations-context.ts +6 -2
- package/standalone-bundle/assets/mutationOverTimeWorker-jChgWnwp.js.map +1 -1
- package/standalone-bundle/dashboard-components.js +5699 -5643
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/standalone-bundle/style.css +1 -1
package/dist/util.d.ts
CHANGED
|
@@ -208,40 +208,52 @@ declare const mutationAnnotationSchema: default_2.ZodObject<{
|
|
|
208
208
|
name: default_2.ZodString;
|
|
209
209
|
description: default_2.ZodString;
|
|
210
210
|
symbol: default_2.ZodString;
|
|
211
|
-
nucleotideMutations: default_2.ZodArray<default_2.ZodString, "many"
|
|
212
|
-
|
|
211
|
+
nucleotideMutations: default_2.ZodOptional<default_2.ZodArray<default_2.ZodString, "many">>;
|
|
212
|
+
nucleotidePositions: default_2.ZodOptional<default_2.ZodArray<default_2.ZodString, "many">>;
|
|
213
|
+
aminoAcidMutations: default_2.ZodOptional<default_2.ZodArray<default_2.ZodString, "many">>;
|
|
214
|
+
aminoAcidPositions: default_2.ZodOptional<default_2.ZodArray<default_2.ZodString, "many">>;
|
|
213
215
|
}, "strip", default_2.ZodTypeAny, {
|
|
214
216
|
symbol: string;
|
|
215
217
|
name: string;
|
|
216
218
|
description: string;
|
|
217
|
-
nucleotideMutations
|
|
218
|
-
|
|
219
|
+
nucleotideMutations?: string[] | undefined;
|
|
220
|
+
nucleotidePositions?: string[] | undefined;
|
|
221
|
+
aminoAcidMutations?: string[] | undefined;
|
|
222
|
+
aminoAcidPositions?: string[] | undefined;
|
|
219
223
|
}, {
|
|
220
224
|
symbol: string;
|
|
221
225
|
name: string;
|
|
222
226
|
description: string;
|
|
223
|
-
nucleotideMutations
|
|
224
|
-
|
|
227
|
+
nucleotideMutations?: string[] | undefined;
|
|
228
|
+
nucleotidePositions?: string[] | undefined;
|
|
229
|
+
aminoAcidMutations?: string[] | undefined;
|
|
230
|
+
aminoAcidPositions?: string[] | undefined;
|
|
225
231
|
}>;
|
|
226
232
|
|
|
227
233
|
declare const mutationAnnotationsSchema: default_2.ZodArray<default_2.ZodObject<{
|
|
228
234
|
name: default_2.ZodString;
|
|
229
235
|
description: default_2.ZodString;
|
|
230
236
|
symbol: default_2.ZodString;
|
|
231
|
-
nucleotideMutations: default_2.ZodArray<default_2.ZodString, "many"
|
|
232
|
-
|
|
237
|
+
nucleotideMutations: default_2.ZodOptional<default_2.ZodArray<default_2.ZodString, "many">>;
|
|
238
|
+
nucleotidePositions: default_2.ZodOptional<default_2.ZodArray<default_2.ZodString, "many">>;
|
|
239
|
+
aminoAcidMutations: default_2.ZodOptional<default_2.ZodArray<default_2.ZodString, "many">>;
|
|
240
|
+
aminoAcidPositions: default_2.ZodOptional<default_2.ZodArray<default_2.ZodString, "many">>;
|
|
233
241
|
}, "strip", default_2.ZodTypeAny, {
|
|
234
242
|
symbol: string;
|
|
235
243
|
name: string;
|
|
236
244
|
description: string;
|
|
237
|
-
nucleotideMutations
|
|
238
|
-
|
|
245
|
+
nucleotideMutations?: string[] | undefined;
|
|
246
|
+
nucleotidePositions?: string[] | undefined;
|
|
247
|
+
aminoAcidMutations?: string[] | undefined;
|
|
248
|
+
aminoAcidPositions?: string[] | undefined;
|
|
239
249
|
}, {
|
|
240
250
|
symbol: string;
|
|
241
251
|
name: string;
|
|
242
252
|
description: string;
|
|
243
|
-
nucleotideMutations
|
|
244
|
-
|
|
253
|
+
nucleotideMutations?: string[] | undefined;
|
|
254
|
+
nucleotidePositions?: string[] | undefined;
|
|
255
|
+
aminoAcidMutations?: string[] | undefined;
|
|
256
|
+
aminoAcidPositions?: string[] | undefined;
|
|
245
257
|
}>, "many">;
|
|
246
258
|
|
|
247
259
|
export declare type MutationComparisonProps = default_2.infer<typeof mutationComparisonPropsSchema>;
|
|
@@ -890,7 +902,7 @@ declare global {
|
|
|
890
902
|
|
|
891
903
|
declare global {
|
|
892
904
|
interface HTMLElementTagNameMap {
|
|
893
|
-
'gs-
|
|
905
|
+
'gs-wastewater-mutations-over-time': WastewaterMutationsOverTimeComponent;
|
|
894
906
|
}
|
|
895
907
|
}
|
|
896
908
|
|
|
@@ -898,7 +910,7 @@ declare global {
|
|
|
898
910
|
declare global {
|
|
899
911
|
namespace JSX {
|
|
900
912
|
interface IntrinsicElements {
|
|
901
|
-
'gs-
|
|
913
|
+
'gs-wastewater-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
902
914
|
}
|
|
903
915
|
}
|
|
904
916
|
}
|
|
@@ -906,7 +918,11 @@ declare global {
|
|
|
906
918
|
|
|
907
919
|
declare global {
|
|
908
920
|
interface HTMLElementTagNameMap {
|
|
909
|
-
'gs-
|
|
921
|
+
'gs-date-range-filter': DateRangeFilterComponent;
|
|
922
|
+
}
|
|
923
|
+
interface HTMLElementEventMap {
|
|
924
|
+
'gs-date-range-filter-changed': CustomEvent<Record<string, string>>;
|
|
925
|
+
'gs-date-range-option-changed': DateRangeOptionChangedEvent;
|
|
910
926
|
}
|
|
911
927
|
}
|
|
912
928
|
|
|
@@ -914,7 +930,7 @@ declare global {
|
|
|
914
930
|
declare global {
|
|
915
931
|
namespace JSX {
|
|
916
932
|
interface IntrinsicElements {
|
|
917
|
-
'gs-
|
|
933
|
+
'gs-date-range-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
918
934
|
}
|
|
919
935
|
}
|
|
920
936
|
}
|
|
@@ -922,7 +938,10 @@ declare global {
|
|
|
922
938
|
|
|
923
939
|
declare global {
|
|
924
940
|
interface HTMLElementTagNameMap {
|
|
925
|
-
'gs-
|
|
941
|
+
'gs-location-filter': LocationFilterComponent;
|
|
942
|
+
}
|
|
943
|
+
interface HTMLElementEventMap {
|
|
944
|
+
'gs-location-changed': LocationChangedEvent;
|
|
926
945
|
}
|
|
927
946
|
}
|
|
928
947
|
|
|
@@ -930,7 +949,7 @@ declare global {
|
|
|
930
949
|
declare global {
|
|
931
950
|
namespace JSX {
|
|
932
951
|
interface IntrinsicElements {
|
|
933
|
-
'gs-
|
|
952
|
+
'gs-location-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
934
953
|
}
|
|
935
954
|
}
|
|
936
955
|
}
|
|
@@ -938,7 +957,10 @@ declare global {
|
|
|
938
957
|
|
|
939
958
|
declare global {
|
|
940
959
|
interface HTMLElementTagNameMap {
|
|
941
|
-
'gs-
|
|
960
|
+
'gs-text-filter': TextFilterComponent;
|
|
961
|
+
}
|
|
962
|
+
interface HTMLElementEventMap {
|
|
963
|
+
'gs-text-filter-changed': TextFilterChangedEvent;
|
|
942
964
|
}
|
|
943
965
|
}
|
|
944
966
|
|
|
@@ -946,7 +968,7 @@ declare global {
|
|
|
946
968
|
declare global {
|
|
947
969
|
namespace JSX {
|
|
948
970
|
interface IntrinsicElements {
|
|
949
|
-
'gs-
|
|
971
|
+
'gs-text-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
950
972
|
}
|
|
951
973
|
}
|
|
952
974
|
}
|
|
@@ -954,7 +976,10 @@ declare global {
|
|
|
954
976
|
|
|
955
977
|
declare global {
|
|
956
978
|
interface HTMLElementTagNameMap {
|
|
957
|
-
'gs-
|
|
979
|
+
'gs-lineage-filter': LineageFilterComponent;
|
|
980
|
+
}
|
|
981
|
+
interface HTMLElementEventMap {
|
|
982
|
+
'gs-lineage-filter-changed': LineageFilterChangedEvent;
|
|
958
983
|
}
|
|
959
984
|
}
|
|
960
985
|
|
|
@@ -962,7 +987,7 @@ declare global {
|
|
|
962
987
|
declare global {
|
|
963
988
|
namespace JSX {
|
|
964
989
|
interface IntrinsicElements {
|
|
965
|
-
'gs-
|
|
990
|
+
'gs-lineage-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
966
991
|
}
|
|
967
992
|
}
|
|
968
993
|
}
|
|
@@ -970,7 +995,10 @@ declare global {
|
|
|
970
995
|
|
|
971
996
|
declare global {
|
|
972
997
|
interface HTMLElementTagNameMap {
|
|
973
|
-
'gs-
|
|
998
|
+
'gs-mutation-filter': MutationFilterComponent;
|
|
999
|
+
}
|
|
1000
|
+
interface HTMLElementEventMap {
|
|
1001
|
+
'gs-mutation-filter-changed': CustomEvent<MutationsFilter>;
|
|
974
1002
|
}
|
|
975
1003
|
}
|
|
976
1004
|
|
|
@@ -978,7 +1006,7 @@ declare global {
|
|
|
978
1006
|
declare global {
|
|
979
1007
|
namespace JSX {
|
|
980
1008
|
interface IntrinsicElements {
|
|
981
|
-
'gs-
|
|
1009
|
+
'gs-mutation-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
982
1010
|
}
|
|
983
1011
|
}
|
|
984
1012
|
}
|
|
@@ -986,7 +1014,7 @@ declare global {
|
|
|
986
1014
|
|
|
987
1015
|
declare global {
|
|
988
1016
|
interface HTMLElementTagNameMap {
|
|
989
|
-
'gs-
|
|
1017
|
+
'gs-mutation-comparison-component': MutationComparisonComponent;
|
|
990
1018
|
}
|
|
991
1019
|
}
|
|
992
1020
|
|
|
@@ -994,7 +1022,7 @@ declare global {
|
|
|
994
1022
|
declare global {
|
|
995
1023
|
namespace JSX {
|
|
996
1024
|
interface IntrinsicElements {
|
|
997
|
-
'gs-
|
|
1025
|
+
'gs-mutation-comparison-component': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
998
1026
|
}
|
|
999
1027
|
}
|
|
1000
1028
|
}
|
|
@@ -1002,7 +1030,7 @@ declare global {
|
|
|
1002
1030
|
|
|
1003
1031
|
declare global {
|
|
1004
1032
|
interface HTMLElementTagNameMap {
|
|
1005
|
-
'gs-
|
|
1033
|
+
'gs-mutations-component': MutationsComponent;
|
|
1006
1034
|
}
|
|
1007
1035
|
}
|
|
1008
1036
|
|
|
@@ -1010,7 +1038,7 @@ declare global {
|
|
|
1010
1038
|
declare global {
|
|
1011
1039
|
namespace JSX {
|
|
1012
1040
|
interface IntrinsicElements {
|
|
1013
|
-
'gs-
|
|
1041
|
+
'gs-mutations-component': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1014
1042
|
}
|
|
1015
1043
|
}
|
|
1016
1044
|
}
|
|
@@ -1018,7 +1046,7 @@ declare global {
|
|
|
1018
1046
|
|
|
1019
1047
|
declare global {
|
|
1020
1048
|
interface HTMLElementTagNameMap {
|
|
1021
|
-
'gs-
|
|
1049
|
+
'gs-prevalence-over-time': PrevalenceOverTimeComponent;
|
|
1022
1050
|
}
|
|
1023
1051
|
}
|
|
1024
1052
|
|
|
@@ -1026,7 +1054,7 @@ declare global {
|
|
|
1026
1054
|
declare global {
|
|
1027
1055
|
namespace JSX {
|
|
1028
1056
|
interface IntrinsicElements {
|
|
1029
|
-
'gs-
|
|
1057
|
+
'gs-prevalence-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1030
1058
|
}
|
|
1031
1059
|
}
|
|
1032
1060
|
}
|
|
@@ -1034,11 +1062,7 @@ declare global {
|
|
|
1034
1062
|
|
|
1035
1063
|
declare global {
|
|
1036
1064
|
interface HTMLElementTagNameMap {
|
|
1037
|
-
'gs-
|
|
1038
|
-
}
|
|
1039
|
-
interface HTMLElementEventMap {
|
|
1040
|
-
'gs-date-range-filter-changed': CustomEvent<Record<string, string>>;
|
|
1041
|
-
'gs-date-range-option-changed': DateRangeOptionChangedEvent;
|
|
1065
|
+
'gs-relative-growth-advantage': RelativeGrowthAdvantageComponent;
|
|
1042
1066
|
}
|
|
1043
1067
|
}
|
|
1044
1068
|
|
|
@@ -1046,7 +1070,7 @@ declare global {
|
|
|
1046
1070
|
declare global {
|
|
1047
1071
|
namespace JSX {
|
|
1048
1072
|
interface IntrinsicElements {
|
|
1049
|
-
'gs-
|
|
1073
|
+
'gs-relative-growth-advantage': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1050
1074
|
}
|
|
1051
1075
|
}
|
|
1052
1076
|
}
|
|
@@ -1054,10 +1078,7 @@ declare global {
|
|
|
1054
1078
|
|
|
1055
1079
|
declare global {
|
|
1056
1080
|
interface HTMLElementTagNameMap {
|
|
1057
|
-
'gs-
|
|
1058
|
-
}
|
|
1059
|
-
interface HTMLElementEventMap {
|
|
1060
|
-
'gs-location-changed': LocationChangedEvent;
|
|
1081
|
+
'gs-aggregate': AggregateComponent;
|
|
1061
1082
|
}
|
|
1062
1083
|
}
|
|
1063
1084
|
|
|
@@ -1065,7 +1086,7 @@ declare global {
|
|
|
1065
1086
|
declare global {
|
|
1066
1087
|
namespace JSX {
|
|
1067
1088
|
interface IntrinsicElements {
|
|
1068
|
-
'gs-
|
|
1089
|
+
'gs-aggregate': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1069
1090
|
}
|
|
1070
1091
|
}
|
|
1071
1092
|
}
|
|
@@ -1073,10 +1094,7 @@ declare global {
|
|
|
1073
1094
|
|
|
1074
1095
|
declare global {
|
|
1075
1096
|
interface HTMLElementTagNameMap {
|
|
1076
|
-
'gs-
|
|
1077
|
-
}
|
|
1078
|
-
interface HTMLElementEventMap {
|
|
1079
|
-
'gs-text-filter-changed': TextFilterChangedEvent;
|
|
1097
|
+
'gs-mutations-over-time': MutationsOverTimeComponent;
|
|
1080
1098
|
}
|
|
1081
1099
|
}
|
|
1082
1100
|
|
|
@@ -1084,7 +1102,7 @@ declare global {
|
|
|
1084
1102
|
declare global {
|
|
1085
1103
|
namespace JSX {
|
|
1086
1104
|
interface IntrinsicElements {
|
|
1087
|
-
'gs-
|
|
1105
|
+
'gs-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1088
1106
|
}
|
|
1089
1107
|
}
|
|
1090
1108
|
}
|
|
@@ -1092,10 +1110,7 @@ declare global {
|
|
|
1092
1110
|
|
|
1093
1111
|
declare global {
|
|
1094
1112
|
interface HTMLElementTagNameMap {
|
|
1095
|
-
'gs-
|
|
1096
|
-
}
|
|
1097
|
-
interface HTMLElementEventMap {
|
|
1098
|
-
'gs-mutation-filter-changed': CustomEvent<MutationsFilter>;
|
|
1113
|
+
'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
|
|
1099
1114
|
}
|
|
1100
1115
|
}
|
|
1101
1116
|
|
|
@@ -1103,7 +1118,7 @@ declare global {
|
|
|
1103
1118
|
declare global {
|
|
1104
1119
|
namespace JSX {
|
|
1105
1120
|
interface IntrinsicElements {
|
|
1106
|
-
'gs-
|
|
1121
|
+
'gs-number-sequences-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1107
1122
|
}
|
|
1108
1123
|
}
|
|
1109
1124
|
}
|
|
@@ -1111,10 +1126,7 @@ declare global {
|
|
|
1111
1126
|
|
|
1112
1127
|
declare global {
|
|
1113
1128
|
interface HTMLElementTagNameMap {
|
|
1114
|
-
'gs-
|
|
1115
|
-
}
|
|
1116
|
-
interface HTMLElementEventMap {
|
|
1117
|
-
'gs-lineage-filter-changed': LineageFilterChangedEvent;
|
|
1129
|
+
'gs-sequences-by-location': SequencesByLocationComponent;
|
|
1118
1130
|
}
|
|
1119
1131
|
}
|
|
1120
1132
|
|
|
@@ -1122,7 +1134,7 @@ declare global {
|
|
|
1122
1134
|
declare global {
|
|
1123
1135
|
namespace JSX {
|
|
1124
1136
|
interface IntrinsicElements {
|
|
1125
|
-
'gs-
|
|
1137
|
+
'gs-sequences-by-location': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1126
1138
|
}
|
|
1127
1139
|
}
|
|
1128
1140
|
}
|
|
@@ -1130,7 +1142,7 @@ declare global {
|
|
|
1130
1142
|
|
|
1131
1143
|
declare global {
|
|
1132
1144
|
interface HTMLElementTagNameMap {
|
|
1133
|
-
'gs-
|
|
1145
|
+
'gs-statistics': StatisticsComponent;
|
|
1134
1146
|
}
|
|
1135
1147
|
}
|
|
1136
1148
|
|
|
@@ -1138,7 +1150,7 @@ declare global {
|
|
|
1138
1150
|
declare global {
|
|
1139
1151
|
namespace JSX {
|
|
1140
1152
|
interface IntrinsicElements {
|
|
1141
|
-
'gs-
|
|
1153
|
+
'gs-statistics': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1142
1154
|
}
|
|
1143
1155
|
}
|
|
1144
1156
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genspectrum/dashboard-components",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.4",
|
|
4
4
|
"description": "GenSpectrum web components for building dashboards",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"@storybook/preact": "^8.0.9",
|
|
113
113
|
"@storybook/preact-vite": "^8.0.9",
|
|
114
114
|
"@storybook/test": "^8.0.0",
|
|
115
|
-
"@storybook/test-runner": "^0.
|
|
115
|
+
"@storybook/test-runner": "^0.22.0",
|
|
116
116
|
"@storybook/types": "^8.0.9",
|
|
117
117
|
"@storybook/web-components": "^8.0.9",
|
|
118
118
|
"@storybook/web-components-vite": "^8.0.9",
|
|
@@ -143,9 +143,9 @@
|
|
|
143
143
|
"storybook": "^8.0.9",
|
|
144
144
|
"storybook-addon-fetch-mock": "^2.0.0",
|
|
145
145
|
"tailwindcss": "^4.0.9",
|
|
146
|
-
"typescript": "
|
|
146
|
+
"typescript": "^5.8.2",
|
|
147
147
|
"vite": "^6.0.3",
|
|
148
|
-
"vite-plugin-dts": "
|
|
148
|
+
"vite-plugin-dts": "4.5.0",
|
|
149
149
|
"vitest": "^3.0.2"
|
|
150
150
|
}
|
|
151
151
|
}
|
|
@@ -3,56 +3,125 @@ import { type FunctionalComponent } from 'preact';
|
|
|
3
3
|
import { describe, expect, it } from 'vitest';
|
|
4
4
|
|
|
5
5
|
import { MutationAnnotationsContextProvider, useMutationAnnotationsProvider } from './MutationAnnotationsContext';
|
|
6
|
+
import { SubstitutionClass } from '../utils/mutations';
|
|
6
7
|
import { type MutationAnnotations } from '../web-components/mutation-annotations-context';
|
|
7
8
|
|
|
8
9
|
describe('useMutationAnnotation', () => {
|
|
9
|
-
|
|
10
|
-
{
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
nucleotideMutations: ['A123', 'A456'],
|
|
15
|
-
aminoAcidMutations: ['B123'],
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
name: 'Annotation 2',
|
|
19
|
-
description: 'Description 2',
|
|
20
|
-
symbol: 'A2',
|
|
21
|
-
nucleotideMutations: ['A456', 'A789'],
|
|
22
|
-
aminoAcidMutations: ['B456', 'B789'],
|
|
23
|
-
},
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
const wrapper: FunctionalComponent = ({ children }) => (
|
|
27
|
-
<MutationAnnotationsContextProvider value={mockAnnotations}>{children}</MutationAnnotationsContextProvider>
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
function renderAnnotationsHook() {
|
|
10
|
+
function renderAnnotationsHook(mockAnnotations: MutationAnnotations) {
|
|
11
|
+
const wrapper: FunctionalComponent = ({ children }) => (
|
|
12
|
+
<MutationAnnotationsContextProvider value={mockAnnotations}>{children}</MutationAnnotationsContextProvider>
|
|
13
|
+
);
|
|
14
|
+
|
|
31
15
|
const { result } = renderHook(() => useMutationAnnotationsProvider(), { wrapper });
|
|
32
16
|
return result.current;
|
|
33
17
|
}
|
|
34
18
|
|
|
35
|
-
|
|
36
|
-
const
|
|
19
|
+
describe('annotations for nucleotide mutations', () => {
|
|
20
|
+
const mockAnnotations: MutationAnnotations = [
|
|
21
|
+
{
|
|
22
|
+
name: 'Annotation 1',
|
|
23
|
+
description: 'Description 1',
|
|
24
|
+
symbol: 'A1',
|
|
25
|
+
nucleotideMutations: ['A123', 'A456'],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'Annotation 2',
|
|
29
|
+
description: 'Description 2',
|
|
30
|
+
symbol: 'A2',
|
|
31
|
+
nucleotideMutations: ['A456', 'A789'],
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
it('should return the correct annotation for a given mutation', () => {
|
|
36
|
+
const result = renderAnnotationsHook(mockAnnotations)(SubstitutionClass.parse('A123')!, 'nucleotide');
|
|
37
|
+
|
|
38
|
+
expect(result).toEqual([mockAnnotations[0]]);
|
|
39
|
+
});
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
it('should return the correct annotations if multiple contain a mutation', () => {
|
|
42
|
+
const result = renderAnnotationsHook(mockAnnotations)(SubstitutionClass.parse('A456')!, 'nucleotide');
|
|
43
|
+
|
|
44
|
+
expect(result).toEqual([mockAnnotations[0], mockAnnotations[1]]);
|
|
45
|
+
});
|
|
39
46
|
});
|
|
40
47
|
|
|
41
|
-
|
|
42
|
-
const
|
|
48
|
+
describe('annotations for amino acid mutations', () => {
|
|
49
|
+
const mockAnnotations: MutationAnnotations = [
|
|
50
|
+
{
|
|
51
|
+
name: 'Annotation 1',
|
|
52
|
+
description: 'Description 1',
|
|
53
|
+
symbol: 'A1',
|
|
54
|
+
aminoAcidMutations: ['B456', 'B789'],
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
it('should return the correct mutation annotation for a given mutations', () => {
|
|
59
|
+
const result = renderAnnotationsHook(mockAnnotations)(SubstitutionClass.parse('B456')!, 'amino acid');
|
|
43
60
|
|
|
44
|
-
|
|
61
|
+
expect(result).toEqual([mockAnnotations[0]]);
|
|
62
|
+
});
|
|
45
63
|
});
|
|
46
64
|
|
|
47
|
-
|
|
48
|
-
const
|
|
65
|
+
describe('annotations for nucleotide positions', () => {
|
|
66
|
+
const mockAnnotations: MutationAnnotations = [
|
|
67
|
+
{
|
|
68
|
+
name: 'Annotation 1',
|
|
69
|
+
description: 'Description 1',
|
|
70
|
+
symbol: 'A1',
|
|
71
|
+
nucleotideMutations: ['A321T', 'A432T'],
|
|
72
|
+
nucleotidePositions: ['321', '543'],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'Annotation 2',
|
|
76
|
+
description: 'Description 2',
|
|
77
|
+
symbol: 'A2',
|
|
78
|
+
nucleotidePositions: ['432'],
|
|
79
|
+
},
|
|
80
|
+
];
|
|
49
81
|
|
|
50
|
-
|
|
82
|
+
it('should return the correct mutation annotation covered by position only', () => {
|
|
83
|
+
const result = renderAnnotationsHook(mockAnnotations)(SubstitutionClass.parse('A543T')!, 'nucleotide');
|
|
84
|
+
expect(result).toEqual([mockAnnotations[0]]);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('should return the correct mutation annotation covered both by position and mutation', () => {
|
|
88
|
+
const result = renderAnnotationsHook(mockAnnotations)(SubstitutionClass.parse('A321T')!, 'nucleotide');
|
|
89
|
+
expect(result).toEqual([mockAnnotations[0]]);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should return both annotations if one matches the mutations and the other the position', () => {
|
|
93
|
+
const result = renderAnnotationsHook(mockAnnotations)(SubstitutionClass.parse('A432T')!, 'nucleotide');
|
|
94
|
+
expect(result).toEqual([mockAnnotations[1], mockAnnotations[0]]);
|
|
95
|
+
});
|
|
51
96
|
});
|
|
52
97
|
|
|
53
|
-
|
|
54
|
-
const
|
|
98
|
+
describe('annotations for amino acid positions', () => {
|
|
99
|
+
const mockAnnotations: MutationAnnotations = [
|
|
100
|
+
{
|
|
101
|
+
name: 'Annotation 1',
|
|
102
|
+
description: 'Description 1',
|
|
103
|
+
symbol: 'A1',
|
|
104
|
+
aminoAcidMutations: ['Gene:B321C', 'Gene:B432G'],
|
|
105
|
+
aminoAcidPositions: ['Gene:432', 'Gene:543'],
|
|
106
|
+
},
|
|
107
|
+
];
|
|
108
|
+
|
|
109
|
+
it('should return the correct mutation annotation covered both by position and mutation', () => {
|
|
110
|
+
const result = renderAnnotationsHook(mockAnnotations)(SubstitutionClass.parse('Gene:B432G')!, 'amino acid');
|
|
111
|
+
expect(result).toEqual([mockAnnotations[0]]);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should return the correct mutation annotation covered both by position only', () => {
|
|
115
|
+
const result = renderAnnotationsHook(mockAnnotations)(SubstitutionClass.parse('Gene:B543G')!, 'amino acid');
|
|
116
|
+
expect(result).toEqual([mockAnnotations[0]]);
|
|
117
|
+
});
|
|
55
118
|
|
|
56
|
-
|
|
119
|
+
it('should return no mutation annotation for an amino acid position of wrong gene', () => {
|
|
120
|
+
const result = renderAnnotationsHook(mockAnnotations)(
|
|
121
|
+
SubstitutionClass.parse('NotTheGene:B543G')!,
|
|
122
|
+
'amino acid',
|
|
123
|
+
);
|
|
124
|
+
expect(result).toBeUndefined();
|
|
125
|
+
});
|
|
57
126
|
});
|
|
58
127
|
});
|
|
@@ -9,10 +9,22 @@ import {
|
|
|
9
9
|
} from '../web-components/mutation-annotations-context';
|
|
10
10
|
import { ErrorDisplay } from './components/error-display';
|
|
11
11
|
import { ResizeContainer } from './components/resize-container';
|
|
12
|
+
import { type Mutation } from '../utils/mutations';
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
type MutationAnnotationPerSequenceType = {
|
|
15
|
+
mutation: Map<string, MutationAnnotations>;
|
|
16
|
+
position: Map<string, MutationAnnotations>;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const MutationAnnotationsContext = createContext<Record<SequenceType, MutationAnnotationPerSequenceType>>({
|
|
20
|
+
nucleotide: {
|
|
21
|
+
mutation: new Map(),
|
|
22
|
+
position: new Map(),
|
|
23
|
+
},
|
|
24
|
+
'amino acid': {
|
|
25
|
+
mutation: new Map(),
|
|
26
|
+
position: new Map(),
|
|
27
|
+
},
|
|
16
28
|
});
|
|
17
29
|
|
|
18
30
|
export const MutationAnnotationsContextProvider: FunctionalComponent<
|
|
@@ -26,7 +38,9 @@ export const MutationAnnotationsContextProvider: FunctionalComponent<
|
|
|
26
38
|
}
|
|
27
39
|
|
|
28
40
|
const nucleotideMap = new Map<string, MutationAnnotations>();
|
|
41
|
+
const nucleotidePositions = new Map<string, MutationAnnotations>();
|
|
29
42
|
const aminoAcidMap = new Map<string, MutationAnnotations>();
|
|
43
|
+
const aminoAcidPositions = new Map<string, MutationAnnotations>();
|
|
30
44
|
|
|
31
45
|
value.forEach((annotation) => {
|
|
32
46
|
new Set(annotation.nucleotideMutations).forEach((code) => {
|
|
@@ -35,13 +49,19 @@ export const MutationAnnotationsContextProvider: FunctionalComponent<
|
|
|
35
49
|
new Set(annotation.aminoAcidMutations).forEach((code) => {
|
|
36
50
|
addAnnotationToMap(aminoAcidMap, code, annotation);
|
|
37
51
|
});
|
|
52
|
+
new Set(annotation.nucleotidePositions).forEach((position) => {
|
|
53
|
+
addAnnotationToMap(nucleotidePositions, position, annotation);
|
|
54
|
+
});
|
|
55
|
+
new Set(annotation.aminoAcidPositions).forEach((position) => {
|
|
56
|
+
addAnnotationToMap(aminoAcidPositions, position, annotation);
|
|
57
|
+
});
|
|
38
58
|
});
|
|
39
59
|
|
|
40
60
|
return {
|
|
41
61
|
success: true as const,
|
|
42
62
|
value: {
|
|
43
|
-
nucleotide: nucleotideMap,
|
|
44
|
-
'amino acid': aminoAcidMap,
|
|
63
|
+
nucleotide: { mutation: nucleotideMap, position: nucleotidePositions },
|
|
64
|
+
'amino acid': { mutation: aminoAcidMap, position: aminoAcidPositions },
|
|
45
65
|
},
|
|
46
66
|
};
|
|
47
67
|
}, [value]);
|
|
@@ -67,6 +87,28 @@ function addAnnotationToMap(map: Map<string, MutationAnnotations>, code: string,
|
|
|
67
87
|
export function useMutationAnnotationsProvider() {
|
|
68
88
|
const mutationAnnotations = useContext(MutationAnnotationsContext);
|
|
69
89
|
|
|
70
|
-
return (
|
|
71
|
-
|
|
90
|
+
return (mutation: Mutation, sequenceType: SequenceType) => {
|
|
91
|
+
const position =
|
|
92
|
+
mutation.segment === undefined
|
|
93
|
+
? `${mutation.position}`
|
|
94
|
+
: `${mutation.segment.toUpperCase()}:${mutation.position}`;
|
|
95
|
+
|
|
96
|
+
const possiblePositionAnnotations = mutationAnnotations[sequenceType].position.get(position);
|
|
97
|
+
const possibleExactAnnotations = mutationAnnotations[sequenceType].mutation.get(mutation.code.toUpperCase());
|
|
98
|
+
|
|
99
|
+
const annotations =
|
|
100
|
+
possiblePositionAnnotations && possibleExactAnnotations
|
|
101
|
+
? [...possiblePositionAnnotations, ...possibleExactAnnotations]
|
|
102
|
+
: (possiblePositionAnnotations ?? possibleExactAnnotations);
|
|
103
|
+
|
|
104
|
+
const uniqueNames = new Set<string>();
|
|
105
|
+
|
|
106
|
+
return annotations?.filter((item) => {
|
|
107
|
+
if (uniqueNames.has(item.name)) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
uniqueNames.add(item.name);
|
|
111
|
+
return true;
|
|
112
|
+
});
|
|
113
|
+
};
|
|
72
114
|
}
|
|
@@ -46,7 +46,6 @@ export const MutationWithoutAnnotationEntry: StoryObj<AnnotatedMutationProps & {
|
|
|
46
46
|
description: 'This is a test annotation',
|
|
47
47
|
symbol: '*',
|
|
48
48
|
nucleotideMutations: ['123T'],
|
|
49
|
-
aminoAcidMutations: [],
|
|
50
49
|
},
|
|
51
50
|
],
|
|
52
51
|
},
|
|
@@ -69,7 +68,6 @@ export const MutationWithAnnotationEntry: StoryObj<AnnotatedMutationProps & { an
|
|
|
69
68
|
description: 'This is a test annotation <a class="link" href="/">with a link.</a>',
|
|
70
69
|
symbol: '*',
|
|
71
70
|
nucleotideMutations: ['A23403G'],
|
|
72
|
-
aminoAcidMutations: [],
|
|
73
71
|
},
|
|
74
72
|
],
|
|
75
73
|
},
|
|
@@ -97,14 +95,12 @@ export const MutationWithMultipleAnnotationEntries: StoryObj<
|
|
|
97
95
|
description: 'This is a test annotation',
|
|
98
96
|
symbol: '*',
|
|
99
97
|
nucleotideMutations: ['A23403G'],
|
|
100
|
-
aminoAcidMutations: [],
|
|
101
98
|
},
|
|
102
99
|
{
|
|
103
100
|
name: 'Another test annotation',
|
|
104
101
|
description: 'This is a test annotation',
|
|
105
102
|
symbol: '+',
|
|
106
103
|
nucleotideMutations: ['A23403G'],
|
|
107
|
-
aminoAcidMutations: [],
|
|
108
104
|
},
|
|
109
105
|
],
|
|
110
106
|
},
|
|
@@ -139,7 +135,6 @@ export const AminoAcidMutationWithAnnotationEntry: StoryObj<
|
|
|
139
135
|
name: 'Test annotation',
|
|
140
136
|
description: 'This is a test annotation',
|
|
141
137
|
symbol: '*',
|
|
142
|
-
nucleotideMutations: [],
|
|
143
138
|
aminoAcidMutations: ['S:A501G'],
|
|
144
139
|
},
|
|
145
140
|
],
|