@genspectrum/dashboard-components 1.14.2 → 1.16.0
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 +7 -7
- package/dist/components.d.ts +68 -67
- package/dist/components.js +67 -13
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +83 -65
- package/package.json +2 -9
- package/src/lapisApi/lapisTypes.ts +1 -1
- package/src/preact/mutationsOverTime/getFilteredMutationsOverTimeData.ts +3 -1
- package/src/preact/queriesOverTime/queries-over-time-row-label-tooltip.stories.tsx +58 -0
- package/src/preact/queriesOverTime/queries-over-time-row-label-tooltip.tsx +24 -0
- package/src/preact/queriesOverTime/queries-over-time.stories.tsx +24 -0
- package/src/preact/queriesOverTime/queries-over-time.tsx +63 -14
- package/src/utilEntrypoint.ts +1 -1
- package/src/web-components/gs-app.ts +2 -3
- package/src/web-components/input/gs-date-range-filter.tsx +2 -3
- package/src/web-components/input/gs-lineage-filter.tsx +2 -3
- package/src/web-components/input/gs-location-filter.tsx +2 -3
- package/src/web-components/input/gs-mutation-filter.tsx +3 -4
- package/src/web-components/input/gs-number-range-filter.tsx +2 -3
- package/src/web-components/input/gs-text-filter.tsx +2 -3
- package/src/web-components/mutation-annotations-context.ts +3 -1
- package/src/web-components/visualization/gs-aggregate.tsx +2 -3
- package/src/web-components/visualization/gs-genome-data-viewer.tsx +2 -3
- package/src/web-components/visualization/gs-mutation-comparison.tsx +2 -3
- package/src/web-components/visualization/gs-mutations-over-time.tsx +2 -3
- package/src/web-components/visualization/gs-mutations.tsx +7 -8
- package/src/web-components/visualization/gs-number-sequences-over-time.tsx +2 -3
- package/src/web-components/visualization/gs-prevalence-over-time.tsx +2 -3
- package/src/web-components/visualization/gs-queries-over-time.stories.ts +4 -0
- package/src/web-components/visualization/gs-queries-over-time.tsx +5 -4
- package/src/web-components/visualization/gs-relative-growth-advantage.tsx +2 -3
- package/src/web-components/visualization/gs-sequences-by-location.tsx +2 -3
- package/src/web-components/visualization/gs-statistics.tsx +2 -3
- package/src/web-components/wastewaterVisualization/gs-wastewater-mutations-over-time.tsx +2 -3
- package/standalone-bundle/dashboard-components.js +3573 -3527
- package/standalone-bundle/dashboard-components.js.map +1 -1
package/dist/util.d.ts
CHANGED
|
@@ -71,6 +71,25 @@ export declare type ConfidenceIntervalMethod = default_2.infer<typeof confidence
|
|
|
71
71
|
|
|
72
72
|
declare const confidenceIntervalMethodSchema: default_2.ZodUnion<[default_2.ZodLiteral<"wilson">, default_2.ZodLiteral<"none">]>;
|
|
73
73
|
|
|
74
|
+
export declare type CountCoverageQuery = default_2.infer<typeof countCoverageQuerySchema>;
|
|
75
|
+
|
|
76
|
+
declare const countCoverageQuerySchema: default_2.ZodObject<{
|
|
77
|
+
displayLabel: default_2.ZodString;
|
|
78
|
+
description: default_2.ZodOptional<default_2.ZodString>;
|
|
79
|
+
countQuery: default_2.ZodString;
|
|
80
|
+
coverageQuery: default_2.ZodString;
|
|
81
|
+
}, "strip", default_2.ZodTypeAny, {
|
|
82
|
+
displayLabel: string;
|
|
83
|
+
countQuery: string;
|
|
84
|
+
coverageQuery: string;
|
|
85
|
+
description?: string | undefined;
|
|
86
|
+
}, {
|
|
87
|
+
displayLabel: string;
|
|
88
|
+
countQuery: string;
|
|
89
|
+
coverageQuery: string;
|
|
90
|
+
description?: string | undefined;
|
|
91
|
+
}>;
|
|
92
|
+
|
|
74
93
|
export declare type CustomColumn = default_2.infer<typeof customColumnSchema>;
|
|
75
94
|
|
|
76
95
|
declare const customColumnSchema: default_2.ZodObject<{
|
|
@@ -753,19 +772,32 @@ declare const queriesOverTimeSchema: default_2.ZodObject<{
|
|
|
753
772
|
nucleotideInsertions?: string[] | undefined;
|
|
754
773
|
aminoAcidInsertions?: string[] | undefined;
|
|
755
774
|
}>>;
|
|
756
|
-
queries: default_2.ZodArray<default_2.ZodObject<{
|
|
775
|
+
queries: default_2.ZodEffects<default_2.ZodArray<default_2.ZodObject<{
|
|
757
776
|
displayLabel: default_2.ZodString;
|
|
777
|
+
description: default_2.ZodOptional<default_2.ZodString>;
|
|
758
778
|
countQuery: default_2.ZodString;
|
|
759
779
|
coverageQuery: default_2.ZodString;
|
|
760
780
|
}, "strip", default_2.ZodTypeAny, {
|
|
761
781
|
displayLabel: string;
|
|
762
782
|
countQuery: string;
|
|
763
783
|
coverageQuery: string;
|
|
784
|
+
description?: string | undefined;
|
|
764
785
|
}, {
|
|
765
786
|
displayLabel: string;
|
|
766
787
|
countQuery: string;
|
|
767
788
|
coverageQuery: string;
|
|
768
|
-
|
|
789
|
+
description?: string | undefined;
|
|
790
|
+
}>, "many">, {
|
|
791
|
+
displayLabel: string;
|
|
792
|
+
countQuery: string;
|
|
793
|
+
coverageQuery: string;
|
|
794
|
+
description?: string | undefined;
|
|
795
|
+
}[], {
|
|
796
|
+
displayLabel: string;
|
|
797
|
+
countQuery: string;
|
|
798
|
+
coverageQuery: string;
|
|
799
|
+
description?: string | undefined;
|
|
800
|
+
}[]>;
|
|
769
801
|
views: default_2.ZodArray<default_2.ZodLiteral<"grid">, "many">;
|
|
770
802
|
granularity: default_2.ZodUnion<[default_2.ZodLiteral<"day">, default_2.ZodLiteral<"week">, default_2.ZodLiteral<"month">, default_2.ZodLiteral<"year">]>;
|
|
771
803
|
lapisDateField: default_2.ZodString;
|
|
@@ -804,6 +836,7 @@ declare const queriesOverTimeSchema: default_2.ZodObject<{
|
|
|
804
836
|
displayLabel: string;
|
|
805
837
|
countQuery: string;
|
|
806
838
|
coverageQuery: string;
|
|
839
|
+
description?: string | undefined;
|
|
807
840
|
}[];
|
|
808
841
|
width: string;
|
|
809
842
|
views: "grid"[];
|
|
@@ -831,6 +864,7 @@ declare const queriesOverTimeSchema: default_2.ZodObject<{
|
|
|
831
864
|
displayLabel: string;
|
|
832
865
|
countQuery: string;
|
|
833
866
|
coverageQuery: string;
|
|
867
|
+
description?: string | undefined;
|
|
834
868
|
}[];
|
|
835
869
|
width: string;
|
|
836
870
|
views: "grid"[];
|
|
@@ -853,22 +887,6 @@ export declare type QueriesOverTimeView = default_2.infer<typeof queriesOverTime
|
|
|
853
887
|
|
|
854
888
|
declare const queriesOverTimeViewSchema: default_2.ZodLiteral<"grid">;
|
|
855
889
|
|
|
856
|
-
export declare type QueryDefinition = default_2.infer<typeof queryDefinition>;
|
|
857
|
-
|
|
858
|
-
declare const queryDefinition: default_2.ZodObject<{
|
|
859
|
-
displayLabel: default_2.ZodString;
|
|
860
|
-
countQuery: default_2.ZodString;
|
|
861
|
-
coverageQuery: default_2.ZodString;
|
|
862
|
-
}, "strip", default_2.ZodTypeAny, {
|
|
863
|
-
displayLabel: string;
|
|
864
|
-
countQuery: string;
|
|
865
|
-
coverageQuery: string;
|
|
866
|
-
}, {
|
|
867
|
-
displayLabel: string;
|
|
868
|
-
countQuery: string;
|
|
869
|
-
coverageQuery: string;
|
|
870
|
-
}>;
|
|
871
|
-
|
|
872
890
|
export declare type RelativeGrowthAdvantageProps = default_2.infer<typeof relativeGrowthAdvantagePropsSchema>;
|
|
873
891
|
|
|
874
892
|
declare const relativeGrowthAdvantagePropsSchema: default_2.ZodObject<{
|
|
@@ -1080,9 +1098,9 @@ declare global {
|
|
|
1080
1098
|
|
|
1081
1099
|
|
|
1082
1100
|
declare global {
|
|
1083
|
-
namespace JSX {
|
|
1101
|
+
namespace React.JSX {
|
|
1084
1102
|
interface IntrinsicElements {
|
|
1085
|
-
'gs-app':
|
|
1103
|
+
'gs-app': AppComponent;
|
|
1086
1104
|
}
|
|
1087
1105
|
}
|
|
1088
1106
|
}
|
|
@@ -1090,15 +1108,15 @@ declare global {
|
|
|
1090
1108
|
|
|
1091
1109
|
declare global {
|
|
1092
1110
|
interface HTMLElementTagNameMap {
|
|
1093
|
-
'gs-
|
|
1111
|
+
'gs-genome-data-viewer': GenomeDataViewerComponent;
|
|
1094
1112
|
}
|
|
1095
1113
|
}
|
|
1096
1114
|
|
|
1097
1115
|
|
|
1098
1116
|
declare global {
|
|
1099
|
-
namespace JSX {
|
|
1117
|
+
namespace React.JSX {
|
|
1100
1118
|
interface IntrinsicElements {
|
|
1101
|
-
'gs-
|
|
1119
|
+
'gs-genome-data-viewer': GenomeDataViewerComponent;
|
|
1102
1120
|
}
|
|
1103
1121
|
}
|
|
1104
1122
|
}
|
|
@@ -1106,15 +1124,15 @@ declare global {
|
|
|
1106
1124
|
|
|
1107
1125
|
declare global {
|
|
1108
1126
|
interface HTMLElementTagNameMap {
|
|
1109
|
-
'gs-
|
|
1127
|
+
'gs-mutation-comparison': MutationComparisonComponent;
|
|
1110
1128
|
}
|
|
1111
1129
|
}
|
|
1112
1130
|
|
|
1113
1131
|
|
|
1114
1132
|
declare global {
|
|
1115
|
-
namespace JSX {
|
|
1133
|
+
namespace React.JSX {
|
|
1116
1134
|
interface IntrinsicElements {
|
|
1117
|
-
'gs-
|
|
1135
|
+
'gs-mutation-comparison': MutationComparisonComponent;
|
|
1118
1136
|
}
|
|
1119
1137
|
}
|
|
1120
1138
|
}
|
|
@@ -1122,15 +1140,15 @@ declare global {
|
|
|
1122
1140
|
|
|
1123
1141
|
declare global {
|
|
1124
1142
|
interface HTMLElementTagNameMap {
|
|
1125
|
-
'gs-
|
|
1143
|
+
'gs-mutations': MutationsComponent;
|
|
1126
1144
|
}
|
|
1127
1145
|
}
|
|
1128
1146
|
|
|
1129
1147
|
|
|
1130
1148
|
declare global {
|
|
1131
|
-
namespace JSX {
|
|
1149
|
+
namespace React.JSX {
|
|
1132
1150
|
interface IntrinsicElements {
|
|
1133
|
-
'gs-
|
|
1151
|
+
'gs-mutations': MutationsComponent;
|
|
1134
1152
|
}
|
|
1135
1153
|
}
|
|
1136
1154
|
}
|
|
@@ -1138,15 +1156,15 @@ declare global {
|
|
|
1138
1156
|
|
|
1139
1157
|
declare global {
|
|
1140
1158
|
interface HTMLElementTagNameMap {
|
|
1141
|
-
'gs-
|
|
1159
|
+
'gs-prevalence-over-time': PrevalenceOverTimeComponent;
|
|
1142
1160
|
}
|
|
1143
1161
|
}
|
|
1144
1162
|
|
|
1145
1163
|
|
|
1146
1164
|
declare global {
|
|
1147
|
-
namespace JSX {
|
|
1165
|
+
namespace React.JSX {
|
|
1148
1166
|
interface IntrinsicElements {
|
|
1149
|
-
'gs-
|
|
1167
|
+
'gs-prevalence-over-time': PrevalenceOverTimeComponent;
|
|
1150
1168
|
}
|
|
1151
1169
|
}
|
|
1152
1170
|
}
|
|
@@ -1160,9 +1178,9 @@ declare global {
|
|
|
1160
1178
|
|
|
1161
1179
|
|
|
1162
1180
|
declare global {
|
|
1163
|
-
namespace JSX {
|
|
1181
|
+
namespace React.JSX {
|
|
1164
1182
|
interface IntrinsicElements {
|
|
1165
|
-
'gs-relative-growth-advantage':
|
|
1183
|
+
'gs-relative-growth-advantage': RelativeGrowthAdvantageComponent;
|
|
1166
1184
|
}
|
|
1167
1185
|
}
|
|
1168
1186
|
}
|
|
@@ -1170,15 +1188,15 @@ declare global {
|
|
|
1170
1188
|
|
|
1171
1189
|
declare global {
|
|
1172
1190
|
interface HTMLElementTagNameMap {
|
|
1173
|
-
'gs-
|
|
1191
|
+
'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
|
|
1174
1192
|
}
|
|
1175
1193
|
}
|
|
1176
1194
|
|
|
1177
1195
|
|
|
1178
1196
|
declare global {
|
|
1179
|
-
namespace JSX {
|
|
1197
|
+
namespace React.JSX {
|
|
1180
1198
|
interface IntrinsicElements {
|
|
1181
|
-
'gs-
|
|
1199
|
+
'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
|
|
1182
1200
|
}
|
|
1183
1201
|
}
|
|
1184
1202
|
}
|
|
@@ -1192,9 +1210,9 @@ declare global {
|
|
|
1192
1210
|
|
|
1193
1211
|
|
|
1194
1212
|
declare global {
|
|
1195
|
-
namespace JSX {
|
|
1213
|
+
namespace React.JSX {
|
|
1196
1214
|
interface IntrinsicElements {
|
|
1197
|
-
'gs-aggregate':
|
|
1215
|
+
'gs-aggregate': AggregateComponent;
|
|
1198
1216
|
}
|
|
1199
1217
|
}
|
|
1200
1218
|
}
|
|
@@ -1202,15 +1220,15 @@ declare global {
|
|
|
1202
1220
|
|
|
1203
1221
|
declare global {
|
|
1204
1222
|
interface HTMLElementTagNameMap {
|
|
1205
|
-
'gs-
|
|
1223
|
+
'gs-mutations-over-time': MutationsOverTimeComponent;
|
|
1206
1224
|
}
|
|
1207
1225
|
}
|
|
1208
1226
|
|
|
1209
1227
|
|
|
1210
1228
|
declare global {
|
|
1211
|
-
namespace JSX {
|
|
1229
|
+
namespace React.JSX {
|
|
1212
1230
|
interface IntrinsicElements {
|
|
1213
|
-
'gs-
|
|
1231
|
+
'gs-mutations-over-time': MutationsOverTimeComponent;
|
|
1214
1232
|
}
|
|
1215
1233
|
}
|
|
1216
1234
|
}
|
|
@@ -1218,15 +1236,15 @@ declare global {
|
|
|
1218
1236
|
|
|
1219
1237
|
declare global {
|
|
1220
1238
|
interface HTMLElementTagNameMap {
|
|
1221
|
-
'gs-
|
|
1239
|
+
'gs-queries-over-time': QueriesOverTimeComponent;
|
|
1222
1240
|
}
|
|
1223
1241
|
}
|
|
1224
1242
|
|
|
1225
1243
|
|
|
1226
1244
|
declare global {
|
|
1227
|
-
namespace JSX {
|
|
1245
|
+
namespace React.JSX {
|
|
1228
1246
|
interface IntrinsicElements {
|
|
1229
|
-
'gs-
|
|
1247
|
+
'gs-queries-over-time': QueriesOverTimeComponent;
|
|
1230
1248
|
}
|
|
1231
1249
|
}
|
|
1232
1250
|
}
|
|
@@ -1234,15 +1252,15 @@ declare global {
|
|
|
1234
1252
|
|
|
1235
1253
|
declare global {
|
|
1236
1254
|
interface HTMLElementTagNameMap {
|
|
1237
|
-
'gs-
|
|
1255
|
+
'gs-statistics': StatisticsComponent;
|
|
1238
1256
|
}
|
|
1239
1257
|
}
|
|
1240
1258
|
|
|
1241
1259
|
|
|
1242
1260
|
declare global {
|
|
1243
|
-
namespace JSX {
|
|
1261
|
+
namespace React.JSX {
|
|
1244
1262
|
interface IntrinsicElements {
|
|
1245
|
-
'gs-
|
|
1263
|
+
'gs-statistics': StatisticsComponent;
|
|
1246
1264
|
}
|
|
1247
1265
|
}
|
|
1248
1266
|
}
|
|
@@ -1256,9 +1274,9 @@ declare global {
|
|
|
1256
1274
|
|
|
1257
1275
|
|
|
1258
1276
|
declare global {
|
|
1259
|
-
namespace JSX {
|
|
1277
|
+
namespace React.JSX {
|
|
1260
1278
|
interface IntrinsicElements {
|
|
1261
|
-
'gs-sequences-by-location':
|
|
1279
|
+
'gs-sequences-by-location': SequencesByLocationComponent;
|
|
1262
1280
|
}
|
|
1263
1281
|
}
|
|
1264
1282
|
}
|
|
@@ -1266,15 +1284,15 @@ declare global {
|
|
|
1266
1284
|
|
|
1267
1285
|
declare global {
|
|
1268
1286
|
interface HTMLElementTagNameMap {
|
|
1269
|
-
'gs-
|
|
1287
|
+
'gs-wastewater-mutations-over-time': WastewaterMutationsOverTimeComponent;
|
|
1270
1288
|
}
|
|
1271
1289
|
}
|
|
1272
1290
|
|
|
1273
1291
|
|
|
1274
1292
|
declare global {
|
|
1275
|
-
namespace JSX {
|
|
1293
|
+
namespace React.JSX {
|
|
1276
1294
|
interface IntrinsicElements {
|
|
1277
|
-
'gs-
|
|
1295
|
+
'gs-wastewater-mutations-over-time': WastewaterMutationsOverTimeComponent;
|
|
1278
1296
|
}
|
|
1279
1297
|
}
|
|
1280
1298
|
}
|
|
@@ -1292,9 +1310,9 @@ declare global {
|
|
|
1292
1310
|
|
|
1293
1311
|
|
|
1294
1312
|
declare global {
|
|
1295
|
-
namespace JSX {
|
|
1313
|
+
namespace React.JSX {
|
|
1296
1314
|
interface IntrinsicElements {
|
|
1297
|
-
'gs-date-range-filter':
|
|
1315
|
+
'gs-date-range-filter': DateRangeFilterComponent;
|
|
1298
1316
|
}
|
|
1299
1317
|
}
|
|
1300
1318
|
}
|
|
@@ -1311,9 +1329,9 @@ declare global {
|
|
|
1311
1329
|
|
|
1312
1330
|
|
|
1313
1331
|
declare global {
|
|
1314
|
-
namespace JSX {
|
|
1332
|
+
namespace React.JSX {
|
|
1315
1333
|
interface IntrinsicElements {
|
|
1316
|
-
'gs-location-filter':
|
|
1334
|
+
'gs-location-filter': LocationFilterComponent;
|
|
1317
1335
|
}
|
|
1318
1336
|
}
|
|
1319
1337
|
}
|
|
@@ -1330,9 +1348,9 @@ declare global {
|
|
|
1330
1348
|
|
|
1331
1349
|
|
|
1332
1350
|
declare global {
|
|
1333
|
-
namespace JSX {
|
|
1351
|
+
namespace React.JSX {
|
|
1334
1352
|
interface IntrinsicElements {
|
|
1335
|
-
'gs-text-filter':
|
|
1353
|
+
'gs-text-filter': TextFilterComponent;
|
|
1336
1354
|
}
|
|
1337
1355
|
}
|
|
1338
1356
|
}
|
|
@@ -1349,9 +1367,9 @@ declare global {
|
|
|
1349
1367
|
|
|
1350
1368
|
|
|
1351
1369
|
declare global {
|
|
1352
|
-
namespace JSX {
|
|
1370
|
+
namespace React.JSX {
|
|
1353
1371
|
interface IntrinsicElements {
|
|
1354
|
-
'gs-mutation-filter':
|
|
1372
|
+
'gs-mutation-filter': MutationFilterComponent;
|
|
1355
1373
|
}
|
|
1356
1374
|
}
|
|
1357
1375
|
}
|
|
@@ -1369,9 +1387,9 @@ declare global {
|
|
|
1369
1387
|
|
|
1370
1388
|
|
|
1371
1389
|
declare global {
|
|
1372
|
-
namespace JSX {
|
|
1390
|
+
namespace React.JSX {
|
|
1373
1391
|
interface IntrinsicElements {
|
|
1374
|
-
'gs-lineage-filter':
|
|
1392
|
+
'gs-lineage-filter': LineageFilterComponent;
|
|
1375
1393
|
}
|
|
1376
1394
|
}
|
|
1377
1395
|
}
|
|
@@ -1389,9 +1407,9 @@ declare global {
|
|
|
1389
1407
|
|
|
1390
1408
|
|
|
1391
1409
|
declare global {
|
|
1392
|
-
namespace JSX {
|
|
1410
|
+
namespace React.JSX {
|
|
1393
1411
|
interface IntrinsicElements {
|
|
1394
|
-
'gs-number-range-filter':
|
|
1412
|
+
'gs-number-range-filter': NumberRangeFilterComponent;
|
|
1395
1413
|
}
|
|
1396
1414
|
}
|
|
1397
1415
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genspectrum/dashboard-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "GenSpectrum web components for building dashboards",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -15,13 +15,6 @@
|
|
|
15
15
|
"publishConfig": {
|
|
16
16
|
"access": "public"
|
|
17
17
|
},
|
|
18
|
-
"imports": {
|
|
19
|
-
"#*": [
|
|
20
|
-
"./*",
|
|
21
|
-
"./*.ts",
|
|
22
|
-
"./*.tsx"
|
|
23
|
-
]
|
|
24
|
-
},
|
|
25
18
|
"exports": {
|
|
26
19
|
"./components": {
|
|
27
20
|
"types": "./dist/components.d.ts",
|
|
@@ -136,7 +129,7 @@
|
|
|
136
129
|
"msw": "^2.2.14",
|
|
137
130
|
"postcss": "^8.4.38",
|
|
138
131
|
"prettier": "^3.2.5",
|
|
139
|
-
"react": "^
|
|
132
|
+
"react": "^19.0.0",
|
|
140
133
|
"storybook": "^8.0.9",
|
|
141
134
|
"storybook-addon-fetch-mock": "^2.0.0",
|
|
142
135
|
"tailwindcss": "^4.0.9",
|
|
@@ -68,7 +68,7 @@ export const mutationsOverTimeResponse = makeLapisResponse(
|
|
|
68
68
|
export type MutationsOverTimeResponse = z.infer<typeof mutationsOverTimeResponse>;
|
|
69
69
|
|
|
70
70
|
const queryDefinition = z.object({
|
|
71
|
-
displayLabel: z.string(),
|
|
71
|
+
displayLabel: z.string().optional(),
|
|
72
72
|
countQuery: z.string(),
|
|
73
73
|
coverageQuery: z.string(),
|
|
74
74
|
});
|
|
@@ -8,7 +8,9 @@ import { type useMutationAnnotationsProvider } from '../MutationAnnotationsConte
|
|
|
8
8
|
import type { DisplayedMutationType } from '../components/mutation-type-selector';
|
|
9
9
|
import type { DisplayedSegment } from '../components/segment-selector';
|
|
10
10
|
|
|
11
|
-
export const displayMutationsSchema = z.array(z.string()
|
|
11
|
+
export const displayMutationsSchema = z.array(z.string(), {
|
|
12
|
+
errorMap: () => ({ message: `invalid display mutations` }),
|
|
13
|
+
});
|
|
12
14
|
export type DisplayMutations = z.infer<typeof displayMutationsSchema>;
|
|
13
15
|
|
|
14
16
|
export type MutationFilter = {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { type Meta, type StoryObj } from '@storybook/preact';
|
|
2
|
+
import { expect, within } from '@storybook/test';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
QueriesOverTimeRowLabelTooltip,
|
|
6
|
+
type QueriesOverTimeRowLabelTooltipProps,
|
|
7
|
+
} from './queries-over-time-row-label-tooltip';
|
|
8
|
+
|
|
9
|
+
const meta: Meta<QueriesOverTimeRowLabelTooltipProps> = {
|
|
10
|
+
title: 'Component/Queries over time row label tooltip',
|
|
11
|
+
component: QueriesOverTimeRowLabelTooltip,
|
|
12
|
+
argTypes: {
|
|
13
|
+
query: { control: 'object' },
|
|
14
|
+
},
|
|
15
|
+
parameters: {
|
|
16
|
+
fetchMock: {},
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default meta;
|
|
21
|
+
|
|
22
|
+
export const Default: StoryObj<QueriesOverTimeRowLabelTooltipProps> = {
|
|
23
|
+
render: (args) => <QueriesOverTimeRowLabelTooltip {...args} />,
|
|
24
|
+
args: {
|
|
25
|
+
query: {
|
|
26
|
+
displayLabel: 'Foo variant',
|
|
27
|
+
description: 'These mutations are associated with increased transmissibility.',
|
|
28
|
+
countQuery: 'S:451L & S:452L & S:453L & S:454L & S:455L & S:456L & S:457L & S:458L & S:459L & S:460L',
|
|
29
|
+
coverageQuery: '!S:456N',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
play: async ({ canvasElement }) => {
|
|
33
|
+
const canvas = within(canvasElement);
|
|
34
|
+
await expect(canvas.getByText('Foo variant', { exact: true })).toBeVisible();
|
|
35
|
+
await expect(canvas.getByText('These mutations are associated with increased transmissibility.')).toBeVisible();
|
|
36
|
+
await expect(canvas.getByText('Count query:')).toBeVisible();
|
|
37
|
+
await expect(
|
|
38
|
+
canvas.getByText('S:451L & S:452L & S:453L & S:454L & S:455L & S:456L & S:457L & S:458L & S:459L & S:460L'),
|
|
39
|
+
).toBeVisible();
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const WithoutDescription: StoryObj<QueriesOverTimeRowLabelTooltipProps> = {
|
|
44
|
+
render: (args) => <QueriesOverTimeRowLabelTooltip {...args} />,
|
|
45
|
+
args: {
|
|
46
|
+
query: {
|
|
47
|
+
displayLabel: 'S:R346T',
|
|
48
|
+
countQuery: 'S:346T',
|
|
49
|
+
coverageQuery: '!S:346N',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
play: async ({ canvasElement }) => {
|
|
53
|
+
const canvas = within(canvasElement);
|
|
54
|
+
await expect(canvas.getByText('S:R346T', { exact: true })).toBeVisible();
|
|
55
|
+
await expect(canvas.getByText('Count query:')).toBeVisible();
|
|
56
|
+
await expect(canvas.getByText('S:346T')).toBeVisible();
|
|
57
|
+
},
|
|
58
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { FunctionComponent } from 'preact';
|
|
2
|
+
|
|
3
|
+
import type { CountCoverageQuery } from './queries-over-time';
|
|
4
|
+
|
|
5
|
+
export type QueriesOverTimeRowLabelTooltipProps = {
|
|
6
|
+
query: CountCoverageQuery;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const QueriesOverTimeRowLabelTooltip: FunctionComponent<QueriesOverTimeRowLabelTooltipProps> = ({ query }) => {
|
|
10
|
+
return (
|
|
11
|
+
<div className='flex flex-col gap-2 max-w-xl'>
|
|
12
|
+
<div className='font-bold'>{query.displayLabel}</div>
|
|
13
|
+
{query.description && <div className='text-sm text-gray-700'>{query.description}</div>}
|
|
14
|
+
<div className='text-sm'>
|
|
15
|
+
<span className='text-gray-600'>Count query:</span>
|
|
16
|
+
<div className='p-2 border border-gray-200 rounded bg-gray-50'>
|
|
17
|
+
<pre className='text-xs whitespace-pre-wrap'>
|
|
18
|
+
<code>{query.countQuery}</code>
|
|
19
|
+
</pre>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
};
|
|
@@ -466,6 +466,30 @@ export const WithNoLapisDateFieldField: StoryObj<QueriesOverTimeProps> = {
|
|
|
466
466
|
},
|
|
467
467
|
};
|
|
468
468
|
|
|
469
|
+
export const WithDuplicateDisplayLabels: StoryObj<QueriesOverTimeProps> = {
|
|
470
|
+
...Default,
|
|
471
|
+
args: {
|
|
472
|
+
...Default.args,
|
|
473
|
+
queries: [
|
|
474
|
+
{
|
|
475
|
+
displayLabel: 'S:F456L (single mutation)',
|
|
476
|
+
countQuery: 'S:456L',
|
|
477
|
+
coverageQuery: '!S:456N',
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
displayLabel: 'S:F456L (single mutation)',
|
|
481
|
+
countQuery: 'S:346T & S:456L',
|
|
482
|
+
coverageQuery: '!S:346N & !S:456N',
|
|
483
|
+
},
|
|
484
|
+
],
|
|
485
|
+
},
|
|
486
|
+
play: async ({ canvasElement, step }) => {
|
|
487
|
+
await step('expect error message', async () => {
|
|
488
|
+
await expectInvalidAttributesErrorMessage(canvasElement, 'Display labels must be unique');
|
|
489
|
+
});
|
|
490
|
+
},
|
|
491
|
+
};
|
|
492
|
+
|
|
469
493
|
async function expectQueryOnPage(canvas: Canvas, query: string) {
|
|
470
494
|
await waitFor(async () => {
|
|
471
495
|
const queryOnPage = canvas.getAllByText(query)[0];
|
|
@@ -5,6 +5,7 @@ import z from 'zod';
|
|
|
5
5
|
import { getFilteredQueryOverTimeData, type QueryFilter } from './getFilteredQueriesOverTimeData';
|
|
6
6
|
import { QueriesOverTimeFilter } from './queries-over-time-filter';
|
|
7
7
|
import { QueriesOverTimeGridTooltip } from './queries-over-time-grid-tooltip';
|
|
8
|
+
import { QueriesOverTimeRowLabelTooltip } from './queries-over-time-row-label-tooltip';
|
|
8
9
|
import { type ProportionValue, getProportion } from '../../query/queryMutationsOverTime';
|
|
9
10
|
import { queryQueriesOverTimeData } from '../../query/queryQueriesOverTime';
|
|
10
11
|
import { lapisFilterSchema, temporalGranularitySchema, views } from '../../types';
|
|
@@ -20,6 +21,7 @@ import { Fullscreen } from '../components/fullscreen';
|
|
|
20
21
|
import Info, { InfoComponentCode, InfoHeadline1, InfoParagraph } from '../components/info';
|
|
21
22
|
import { LoadingDisplay } from '../components/loading-display';
|
|
22
23
|
import { NoDataDisplay } from '../components/no-data-display';
|
|
24
|
+
import PortalTooltip from '../components/portal-tooltip';
|
|
23
25
|
import type { ProportionInterval } from '../components/proportion-selector';
|
|
24
26
|
import { ProportionSelectorDropdown } from '../components/proportion-selector-dropdown';
|
|
25
27
|
import { ResizeContainer } from '../components/resize-container';
|
|
@@ -37,17 +39,28 @@ const meanProportionIntervalSchema = z.object({
|
|
|
37
39
|
});
|
|
38
40
|
export type MeanProportionInterval = z.infer<typeof meanProportionIntervalSchema>;
|
|
39
41
|
|
|
42
|
+
const countCoverageQuerySchema = z.object({
|
|
43
|
+
displayLabel: z.string(),
|
|
44
|
+
description: z.string().optional(),
|
|
45
|
+
countQuery: z.string(),
|
|
46
|
+
coverageQuery: z.string(),
|
|
47
|
+
});
|
|
48
|
+
export type CountCoverageQuery = z.infer<typeof countCoverageQuerySchema>;
|
|
49
|
+
|
|
40
50
|
const queriesOverTimeSchema = z.object({
|
|
41
51
|
lapisFilter: lapisFilterSchema,
|
|
42
52
|
queries: z
|
|
43
|
-
.array(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
53
|
+
.array(countCoverageQuerySchema)
|
|
54
|
+
.min(1)
|
|
55
|
+
.superRefine((queries, ctx) => {
|
|
56
|
+
const duplicateDisplayLabels = findDuplicateStrings(queries.map((v) => v.displayLabel));
|
|
57
|
+
if (duplicateDisplayLabels.length > 0) {
|
|
58
|
+
ctx.addIssue({
|
|
59
|
+
code: z.ZodIssueCode.custom,
|
|
60
|
+
message: `Display labels must be unique. Duplicates: ${duplicateDisplayLabels.join(', ')}`,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}),
|
|
51
64
|
views: z.array(queriesOverTimeViewSchema),
|
|
52
65
|
granularity: temporalGranularitySchema,
|
|
53
66
|
lapisDateField: z.string().min(1),
|
|
@@ -136,19 +149,45 @@ const QueriesOverTimeTabs: FunctionComponent<QueriesOverTimeTabsProps> = ({
|
|
|
136
149
|
});
|
|
137
150
|
}, [queryOverTimeData, proportionInterval, hideGaps, queryFilterValue]);
|
|
138
151
|
|
|
152
|
+
const queryLookupMap = useMemo(
|
|
153
|
+
() => new Map(originalComponentProps.queries.map((query) => [query.displayLabel, query])),
|
|
154
|
+
[originalComponentProps.queries],
|
|
155
|
+
);
|
|
156
|
+
|
|
139
157
|
const queryRenderer = useMemo<FeatureRenderer<string>>(
|
|
140
158
|
() => ({
|
|
141
159
|
asString: (value: string) => value,
|
|
142
|
-
renderRowLabel: (value: string) =>
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
160
|
+
renderRowLabel: (value: string) => {
|
|
161
|
+
const queryObject = queryLookupMap.get(value);
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
<PortalTooltip
|
|
165
|
+
content={
|
|
166
|
+
<QueriesOverTimeRowLabelTooltip
|
|
167
|
+
query={
|
|
168
|
+
queryObject ?? {
|
|
169
|
+
displayLabel: value,
|
|
170
|
+
description: undefined,
|
|
171
|
+
countQuery: '',
|
|
172
|
+
coverageQuery: '',
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/>
|
|
176
|
+
}
|
|
177
|
+
position='right'
|
|
178
|
+
portalTarget={tooltipPortalTarget}
|
|
179
|
+
>
|
|
180
|
+
<div className='text-center whitespace-nowrap mr-2'>
|
|
181
|
+
<span>{value}</span>
|
|
182
|
+
</div>
|
|
183
|
+
</PortalTooltip>
|
|
184
|
+
);
|
|
185
|
+
},
|
|
147
186
|
renderTooltip: (value: string, temporal: Temporal, proportionValue: ProportionValue) => (
|
|
148
187
|
<QueriesOverTimeGridTooltip query={value} date={temporal} value={proportionValue} />
|
|
149
188
|
),
|
|
150
189
|
}),
|
|
151
|
-
[],
|
|
190
|
+
[tooltipPortalTarget, queryLookupMap],
|
|
152
191
|
);
|
|
153
192
|
|
|
154
193
|
const getTab = (view: QueriesOverTimeView) => {
|
|
@@ -302,3 +341,13 @@ function getDownloadData(filteredData: ReturnType<typeof getFilteredQueryOverTim
|
|
|
302
341
|
);
|
|
303
342
|
});
|
|
304
343
|
}
|
|
344
|
+
|
|
345
|
+
function findDuplicateStrings(items: string[]): string[] {
|
|
346
|
+
const counts = new Map<string, number>();
|
|
347
|
+
|
|
348
|
+
for (const item of items) {
|
|
349
|
+
counts.set(item, (counts.get(item) ?? 0) + 1);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return [...counts.entries()].filter(([, count]) => count > 1).map(([key]) => key);
|
|
353
|
+
}
|
package/src/utilEntrypoint.ts
CHANGED
|
@@ -54,4 +54,4 @@ export {
|
|
|
54
54
|
export { type MeanProportionInterval } from './preact/mutationsOverTime/mutations-over-time';
|
|
55
55
|
export { type CustomColumn } from './preact/components/features-over-time-grid';
|
|
56
56
|
|
|
57
|
-
export { type
|
|
57
|
+
export { type CountCoverageQuery } from './preact/queriesOverTime/queries-over-time';
|