@genspectrum/dashboard-components 1.1.0 → 1.3.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 +22 -3
- package/dist/{NumberRangeFilterChangedEvent-B64OQZjX.js → NumberRangeFilterChangedEvent-CQ32Qy8D.js} +2 -2
- package/dist/NumberRangeFilterChangedEvent-CQ32Qy8D.js.map +1 -0
- package/dist/assets/mutationOverTimeWorker-C7saVShx.js.map +1 -0
- package/dist/components.d.ts +33 -27
- package/dist/components.js +119 -127
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +27 -27
- package/dist/util.js +1 -1
- package/package.json +7 -3
- package/src/lapisApi/lapisApi.ts +31 -2
- package/src/lapisApi/lapisTypes.ts +35 -1
- package/src/operator/DivisionOperator.ts +4 -2
- package/src/operator/FetchDetailsOperator.ts +1 -1
- package/src/operator/RenameFieldOperator.ts +3 -3
- package/src/preact/aggregatedData/aggregate.tsx +0 -5
- package/src/preact/components/annotated-mutation.tsx +0 -1
- package/src/preact/components/clearable-select.stories.tsx +1 -1
- package/src/preact/components/confidence-interval-selector.tsx +1 -1
- package/src/preact/components/error-boundary.tsx +1 -5
- package/src/preact/components/error-display.tsx +1 -1
- package/src/preact/components/fullscreen.tsx +2 -5
- package/src/preact/components/info.stories.tsx +1 -1
- package/src/preact/components/min-max-range-slider.tsx +1 -1
- package/src/preact/components/proportion-selector.tsx +4 -4
- package/src/preact/components/select.tsx +1 -1
- package/src/preact/components/table.tsx +1 -1
- package/src/preact/components/tabs.tsx +1 -1
- package/src/preact/components/tooltip.stories.tsx +1 -1
- package/src/preact/components/tooltip.tsx +1 -1
- package/src/preact/genomeViewer/CDSPlot.tsx +3 -3
- package/src/preact/genomeViewer/loadGff3.ts +5 -8
- package/src/preact/lineageFilter/lineage-filter.tsx +1 -1
- package/src/preact/locationFilter/location-filter.tsx +4 -4
- package/src/preact/mutationComparison/getMutationComparisonTableData.ts +1 -3
- package/src/preact/mutationComparison/mutation-comparison-venn.tsx +1 -1
- package/src/preact/mutationComparison/mutation-comparison.tsx +0 -5
- package/src/preact/mutationFilter/mutation-filter-info.tsx +2 -2
- package/src/preact/mutationFilter/mutation-filter.tsx +1 -1
- package/src/preact/mutations/getMutationsGridData.ts +2 -6
- package/src/preact/mutations/getMutationsTableData.ts +1 -1
- package/src/preact/mutations/mutations-grid.tsx +1 -1
- package/src/preact/mutations/mutations.tsx +0 -5
- package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay.ts +1 -0
- package/src/preact/mutationsOverTime/__mockData__/byWeek.ts +1 -0
- package/src/preact/mutationsOverTime/__mockData__/defaultMockData.ts +1 -0
- package/src/preact/mutationsOverTime/__mockData__/noDataWhenNoMutationsAreInFilter.ts +1 -0
- package/src/preact/mutationsOverTime/__mockData__/noDataWhenThereAreNoDatesInFilter.ts +1 -0
- package/src/preact/mutationsOverTime/__mockData__/showsMessageWhenTooManyMutations.ts +1 -0
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +2 -0
- package/src/preact/mutationsOverTime/mutations-over-time.tsx +11 -11
- package/src/preact/numberRangeFilter/number-range-filter.tsx +4 -4
- package/src/preact/numberSequencesOverTime/getNumberOfSequencesOverTimeTableData.ts +1 -4
- package/src/preact/numberSequencesOverTime/number-sequences-over-time.tsx +0 -5
- package/src/preact/prevalenceOverTime/prevalence-over-time-bar-chart.tsx +1 -1
- package/src/preact/prevalenceOverTime/prevalence-over-time-bubble-chart.tsx +1 -1
- package/src/preact/prevalenceOverTime/prevalence-over-time-line-chart.tsx +1 -1
- package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +1 -1
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage-chart.tsx +5 -5
- package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +1 -4
- package/src/preact/sequencesByLocation/loadMapSource.tsx +5 -2
- package/src/preact/shared/aspectRatio/AspectRatio.tsx +1 -1
- package/src/preact/shared/floating-ui/hooks.ts +2 -2
- package/src/preact/shared/sort/sortMutationPositions.ts +2 -2
- package/src/preact/shared/tanstackTable/pagination.tsx +2 -2
- package/src/preact/shared/tanstackTable/tanstackTable.tsx +1 -1
- package/src/preact/statistic/statistics.tsx +0 -5
- package/src/preact/textFilter/fetchStringAutocompleteList.ts +1 -10
- package/src/preact/textFilter/text-filter.tsx +1 -6
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +1 -1
- package/src/preact/webWorkers/useWebWorker.ts +2 -1
- package/src/preact/webWorkers/workerFunction.ts +2 -2
- package/src/query/computeMapLocationData.ts +1 -1
- package/src/query/queryAggregatedDataOverTime.ts +3 -3
- package/src/query/queryMutationsOverTime.spec.ts +9 -9
- package/src/query/queryMutationsOverTime.ts +121 -37
- package/src/query/queryMutationsOverTimeNewEndpoint.spec.ts +935 -0
- package/src/query/queryRelativeGrowthAdvantage.ts +5 -9
- package/src/query/queryWastewaterMutationsOverTime.ts +1 -1
- package/src/types.ts +1 -1
- package/src/utils/mutations.ts +10 -10
- package/src/utils/type-utils.ts +1 -1
- package/src/utils/typeAssertions.spec.ts +1 -1
- package/src/web-components/gs-app.spec-d.ts +1 -1
- package/src/web-components/gs-app.stories.ts +1 -1
- package/src/web-components/input/gs-date-range-filter.tsx +2 -2
- package/src/web-components/input/gs-lineage-filter.tsx +2 -2
- package/src/web-components/input/gs-location-filter.tsx +3 -3
- package/src/web-components/input/gs-mutation-filter.tsx +2 -2
- package/src/web-components/input/gs-number-range-filter.spec.ts +1 -1
- package/src/web-components/input/gs-text-filter.tsx +2 -2
- package/src/web-components/visualization/gs-aggregate.tsx +2 -2
- package/src/web-components/visualization/gs-genome-data-viewer.spec-d.ts +1 -1
- package/src/web-components/visualization/gs-mutation-comparison.tsx +2 -2
- package/src/web-components/visualization/gs-mutations-over-time.spec-d.ts +3 -0
- package/src/web-components/visualization/gs-mutations-over-time.stories.ts +3 -0
- package/src/web-components/visualization/gs-mutations-over-time.tsx +9 -0
- package/src/web-components/visualization/gs-mutations.tsx +2 -2
- package/src/web-components/visualization/gs-number-sequences-over-time.tsx +2 -2
- package/src/web-components/visualization/gs-prevalence-over-time.tsx +2 -2
- package/src/web-components/visualization/gs-relative-growth-advantage.tsx +2 -2
- package/src/web-components/visualization/gs-sequences-by-location.tsx +2 -2
- package/src/web-components/visualization/gs-statistics.tsx +2 -2
- package/standalone-bundle/assets/mutationOverTimeWorker-DRRi3aMG.js.map +1 -0
- package/standalone-bundle/dashboard-components.js +4454 -4430
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/dist/NumberRangeFilterChangedEvent-B64OQZjX.js.map +0 -1
- package/dist/assets/mutationOverTimeWorker-DjH04AQB.js.map +0 -1
- package/standalone-bundle/assets/mutationOverTimeWorker-B6bf3R3j.js.map +0 -1
package/dist/util.d.ts
CHANGED
|
@@ -164,7 +164,7 @@ declare type LapisLineageFilter = Record<string, string | undefined>;
|
|
|
164
164
|
|
|
165
165
|
declare type LapisLocationFilter = default_2.infer<typeof lapisLocationFilterSchema>;
|
|
166
166
|
|
|
167
|
-
declare const lapisLocationFilterSchema: default_2.ZodRecord<default_2.ZodString, default_2.ZodUnion<[default_2.ZodString, default_2.ZodUndefined]>>;
|
|
167
|
+
declare const lapisLocationFilterSchema: default_2.ZodRecord<default_2.ZodString, default_2.ZodUnion<[default_2.ZodString, default_2.ZodUndefined, default_2.ZodNull]>>;
|
|
168
168
|
|
|
169
169
|
export declare type LapisNumberFilter = Record<string, number | undefined>;
|
|
170
170
|
|
|
@@ -949,7 +949,7 @@ declare global {
|
|
|
949
949
|
|
|
950
950
|
declare global {
|
|
951
951
|
interface HTMLElementTagNameMap {
|
|
952
|
-
'gs-
|
|
952
|
+
'gs-mutations': MutationsComponent;
|
|
953
953
|
}
|
|
954
954
|
}
|
|
955
955
|
|
|
@@ -957,7 +957,7 @@ declare global {
|
|
|
957
957
|
declare global {
|
|
958
958
|
namespace JSX {
|
|
959
959
|
interface IntrinsicElements {
|
|
960
|
-
'gs-
|
|
960
|
+
'gs-mutations': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
961
961
|
}
|
|
962
962
|
}
|
|
963
963
|
}
|
|
@@ -965,7 +965,7 @@ declare global {
|
|
|
965
965
|
|
|
966
966
|
declare global {
|
|
967
967
|
interface HTMLElementTagNameMap {
|
|
968
|
-
'gs-
|
|
968
|
+
'gs-relative-growth-advantage': RelativeGrowthAdvantageComponent;
|
|
969
969
|
}
|
|
970
970
|
}
|
|
971
971
|
|
|
@@ -973,7 +973,7 @@ declare global {
|
|
|
973
973
|
declare global {
|
|
974
974
|
namespace JSX {
|
|
975
975
|
interface IntrinsicElements {
|
|
976
|
-
'gs-
|
|
976
|
+
'gs-relative-growth-advantage': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
977
977
|
}
|
|
978
978
|
}
|
|
979
979
|
}
|
|
@@ -981,7 +981,7 @@ declare global {
|
|
|
981
981
|
|
|
982
982
|
declare global {
|
|
983
983
|
interface HTMLElementTagNameMap {
|
|
984
|
-
'gs-
|
|
984
|
+
'gs-aggregate': AggregateComponent;
|
|
985
985
|
}
|
|
986
986
|
}
|
|
987
987
|
|
|
@@ -989,7 +989,7 @@ declare global {
|
|
|
989
989
|
declare global {
|
|
990
990
|
namespace JSX {
|
|
991
991
|
interface IntrinsicElements {
|
|
992
|
-
'gs-
|
|
992
|
+
'gs-aggregate': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
993
993
|
}
|
|
994
994
|
}
|
|
995
995
|
}
|
|
@@ -997,7 +997,7 @@ declare global {
|
|
|
997
997
|
|
|
998
998
|
declare global {
|
|
999
999
|
interface HTMLElementTagNameMap {
|
|
1000
|
-
'gs-
|
|
1000
|
+
'gs-prevalence-over-time': PrevalenceOverTimeComponent;
|
|
1001
1001
|
}
|
|
1002
1002
|
}
|
|
1003
1003
|
|
|
@@ -1005,7 +1005,7 @@ declare global {
|
|
|
1005
1005
|
declare global {
|
|
1006
1006
|
namespace JSX {
|
|
1007
1007
|
interface IntrinsicElements {
|
|
1008
|
-
'gs-
|
|
1008
|
+
'gs-prevalence-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1009
1009
|
}
|
|
1010
1010
|
}
|
|
1011
1011
|
}
|
|
@@ -1013,7 +1013,7 @@ declare global {
|
|
|
1013
1013
|
|
|
1014
1014
|
declare global {
|
|
1015
1015
|
interface HTMLElementTagNameMap {
|
|
1016
|
-
'gs-
|
|
1016
|
+
'gs-mutations-over-time': MutationsOverTimeComponent;
|
|
1017
1017
|
}
|
|
1018
1018
|
}
|
|
1019
1019
|
|
|
@@ -1021,7 +1021,7 @@ declare global {
|
|
|
1021
1021
|
declare global {
|
|
1022
1022
|
namespace JSX {
|
|
1023
1023
|
interface IntrinsicElements {
|
|
1024
|
-
'gs-
|
|
1024
|
+
'gs-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1025
1025
|
}
|
|
1026
1026
|
}
|
|
1027
1027
|
}
|
|
@@ -1029,7 +1029,7 @@ declare global {
|
|
|
1029
1029
|
|
|
1030
1030
|
declare global {
|
|
1031
1031
|
interface HTMLElementTagNameMap {
|
|
1032
|
-
'gs-
|
|
1032
|
+
'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
|
|
1033
1033
|
}
|
|
1034
1034
|
}
|
|
1035
1035
|
|
|
@@ -1037,7 +1037,7 @@ declare global {
|
|
|
1037
1037
|
declare global {
|
|
1038
1038
|
namespace JSX {
|
|
1039
1039
|
interface IntrinsicElements {
|
|
1040
|
-
'gs-
|
|
1040
|
+
'gs-number-sequences-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1041
1041
|
}
|
|
1042
1042
|
}
|
|
1043
1043
|
}
|
|
@@ -1061,7 +1061,7 @@ declare global {
|
|
|
1061
1061
|
|
|
1062
1062
|
declare global {
|
|
1063
1063
|
interface HTMLElementTagNameMap {
|
|
1064
|
-
'gs-
|
|
1064
|
+
'gs-wastewater-mutations-over-time': WastewaterMutationsOverTimeComponent;
|
|
1065
1065
|
}
|
|
1066
1066
|
}
|
|
1067
1067
|
|
|
@@ -1069,7 +1069,7 @@ declare global {
|
|
|
1069
1069
|
declare global {
|
|
1070
1070
|
namespace JSX {
|
|
1071
1071
|
interface IntrinsicElements {
|
|
1072
|
-
'gs-
|
|
1072
|
+
'gs-wastewater-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1073
1073
|
}
|
|
1074
1074
|
}
|
|
1075
1075
|
}
|
|
@@ -1077,7 +1077,7 @@ declare global {
|
|
|
1077
1077
|
|
|
1078
1078
|
declare global {
|
|
1079
1079
|
interface HTMLElementTagNameMap {
|
|
1080
|
-
'gs-
|
|
1080
|
+
'gs-statistics': StatisticsComponent;
|
|
1081
1081
|
}
|
|
1082
1082
|
}
|
|
1083
1083
|
|
|
@@ -1085,7 +1085,7 @@ declare global {
|
|
|
1085
1085
|
declare global {
|
|
1086
1086
|
namespace JSX {
|
|
1087
1087
|
interface IntrinsicElements {
|
|
1088
|
-
'gs-
|
|
1088
|
+
'gs-statistics': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1089
1089
|
}
|
|
1090
1090
|
}
|
|
1091
1091
|
}
|
|
@@ -1093,10 +1093,11 @@ declare global {
|
|
|
1093
1093
|
|
|
1094
1094
|
declare global {
|
|
1095
1095
|
interface HTMLElementTagNameMap {
|
|
1096
|
-
'gs-
|
|
1096
|
+
'gs-date-range-filter': DateRangeFilterComponent;
|
|
1097
1097
|
}
|
|
1098
1098
|
interface HTMLElementEventMap {
|
|
1099
|
-
[gsEventNames.
|
|
1099
|
+
[gsEventNames.dateRangeFilterChanged]: CustomEvent<Record<string, string>>;
|
|
1100
|
+
[gsEventNames.dateRangeOptionChanged]: DateRangeOptionChangedEvent;
|
|
1100
1101
|
}
|
|
1101
1102
|
}
|
|
1102
1103
|
|
|
@@ -1104,7 +1105,7 @@ declare global {
|
|
|
1104
1105
|
declare global {
|
|
1105
1106
|
namespace JSX {
|
|
1106
1107
|
interface IntrinsicElements {
|
|
1107
|
-
'gs-
|
|
1108
|
+
'gs-date-range-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1108
1109
|
}
|
|
1109
1110
|
}
|
|
1110
1111
|
}
|
|
@@ -1112,10 +1113,10 @@ declare global {
|
|
|
1112
1113
|
|
|
1113
1114
|
declare global {
|
|
1114
1115
|
interface HTMLElementTagNameMap {
|
|
1115
|
-
'gs-
|
|
1116
|
+
'gs-location-filter': LocationFilterComponent;
|
|
1116
1117
|
}
|
|
1117
1118
|
interface HTMLElementEventMap {
|
|
1118
|
-
[gsEventNames.
|
|
1119
|
+
[gsEventNames.locationChanged]: LocationChangedEvent;
|
|
1119
1120
|
}
|
|
1120
1121
|
}
|
|
1121
1122
|
|
|
@@ -1123,7 +1124,7 @@ declare global {
|
|
|
1123
1124
|
declare global {
|
|
1124
1125
|
namespace JSX {
|
|
1125
1126
|
interface IntrinsicElements {
|
|
1126
|
-
'gs-
|
|
1127
|
+
'gs-location-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1127
1128
|
}
|
|
1128
1129
|
}
|
|
1129
1130
|
}
|
|
@@ -1131,11 +1132,10 @@ declare global {
|
|
|
1131
1132
|
|
|
1132
1133
|
declare global {
|
|
1133
1134
|
interface HTMLElementTagNameMap {
|
|
1134
|
-
'gs-
|
|
1135
|
+
'gs-text-filter': TextFilterComponent;
|
|
1135
1136
|
}
|
|
1136
1137
|
interface HTMLElementEventMap {
|
|
1137
|
-
[gsEventNames.
|
|
1138
|
-
[gsEventNames.dateRangeOptionChanged]: DateRangeOptionChangedEvent;
|
|
1138
|
+
[gsEventNames.textFilterChanged]: TextFilterChangedEvent;
|
|
1139
1139
|
}
|
|
1140
1140
|
}
|
|
1141
1141
|
|
|
@@ -1143,7 +1143,7 @@ declare global {
|
|
|
1143
1143
|
declare global {
|
|
1144
1144
|
namespace JSX {
|
|
1145
1145
|
interface IntrinsicElements {
|
|
1146
|
-
'gs-
|
|
1146
|
+
'gs-text-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1147
1147
|
}
|
|
1148
1148
|
}
|
|
1149
1149
|
}
|
package/dist/util.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genspectrum/dashboard-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "GenSpectrum web components for building dashboards",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -99,6 +99,7 @@
|
|
|
99
99
|
},
|
|
100
100
|
"devDependencies": {
|
|
101
101
|
"@custom-elements-manifest/analyzer": "^0.10.2",
|
|
102
|
+
"@eslint/js": "^9.31.0",
|
|
102
103
|
"@iconify-json/mdi": "^1.1.67",
|
|
103
104
|
"@iconify-json/mdi-light": "^1.1.10",
|
|
104
105
|
"@iconify/tailwind4": "^1.0.6",
|
|
@@ -127,11 +128,13 @@
|
|
|
127
128
|
"autoprefixer": "^10.4.19",
|
|
128
129
|
"daisyui": "^5.0.0",
|
|
129
130
|
"depcheck": "^1.4.7",
|
|
130
|
-
"eslint": "^
|
|
131
|
-
"eslint-config-preact": "^1.3.0",
|
|
131
|
+
"eslint": "^9.31.0",
|
|
132
132
|
"eslint-plugin-import": "^2.29.1",
|
|
133
133
|
"eslint-plugin-jest": "^28.2.0",
|
|
134
|
+
"eslint-plugin-react": "^7.37.5",
|
|
135
|
+
"eslint-plugin-react-hooks": "^5.2.0",
|
|
134
136
|
"eslint-plugin-storybook": "^0.12.0",
|
|
137
|
+
"globals": "^16.3.0",
|
|
135
138
|
"happy-dom": "^17.1.1",
|
|
136
139
|
"http-server": "^14.1.1",
|
|
137
140
|
"lit-analyzer": "^2.0.3",
|
|
@@ -143,6 +146,7 @@
|
|
|
143
146
|
"storybook-addon-fetch-mock": "^2.0.0",
|
|
144
147
|
"tailwindcss": "^4.0.9",
|
|
145
148
|
"typescript": "^5.8.2",
|
|
149
|
+
"typescript-eslint": "^8.36.0",
|
|
146
150
|
"vite": "^6.0.3",
|
|
147
151
|
"vite-plugin-dts": "4.5.0",
|
|
148
152
|
"vitest": "^3.0.2"
|
package/src/lapisApi/lapisApi.ts
CHANGED
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
mutationsResponse,
|
|
10
10
|
problemDetail,
|
|
11
11
|
type ProblemDetail,
|
|
12
|
+
type MutationsOverTimeRequest,
|
|
13
|
+
mutationsOverTimeResponse,
|
|
12
14
|
} from './lapisTypes';
|
|
13
15
|
import { type SequenceType } from '../types';
|
|
14
16
|
import { lineageDefinitionResponseSchema } from './LineageDefinition';
|
|
@@ -112,6 +114,28 @@ export async function fetchSubstitutionsOrDeletions(
|
|
|
112
114
|
return mutationsResponse.parse(await response.json());
|
|
113
115
|
}
|
|
114
116
|
|
|
117
|
+
export async function fetchMutationsOverTime(
|
|
118
|
+
lapisUrl: string,
|
|
119
|
+
body: MutationsOverTimeRequest,
|
|
120
|
+
sequenceType: SequenceType,
|
|
121
|
+
signal?: AbortSignal,
|
|
122
|
+
) {
|
|
123
|
+
const response = await callLapis(
|
|
124
|
+
mutationsOverTimeEndpoint(lapisUrl, sequenceType),
|
|
125
|
+
{
|
|
126
|
+
method: 'POST',
|
|
127
|
+
headers: {
|
|
128
|
+
'Content-Type': 'application/json',
|
|
129
|
+
},
|
|
130
|
+
body: JSON.stringify(body),
|
|
131
|
+
signal,
|
|
132
|
+
},
|
|
133
|
+
`${sequenceType} mutations over time`,
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
return mutationsOverTimeResponse.parse(await response.json());
|
|
137
|
+
}
|
|
138
|
+
|
|
115
139
|
export async function fetchReferenceGenome(lapisUrl: string, signal?: AbortSignal) {
|
|
116
140
|
const response = await callLapis(
|
|
117
141
|
referenceGenomeEndpoint(lapisUrl),
|
|
@@ -176,7 +200,7 @@ const handleErrors = async (response: Response, requestedData: string) => {
|
|
|
176
200
|
const lapisErrorResult = lapisError.safeParse(json);
|
|
177
201
|
if (lapisErrorResult.success) {
|
|
178
202
|
throw new LapisError(
|
|
179
|
-
response.statusText + lapisErrorResult.data.error.detail,
|
|
203
|
+
response.statusText + (lapisErrorResult.data.error.detail ?? ''),
|
|
180
204
|
response.status,
|
|
181
205
|
lapisErrorResult.data.error,
|
|
182
206
|
requestedData,
|
|
@@ -186,7 +210,7 @@ const handleErrors = async (response: Response, requestedData: string) => {
|
|
|
186
210
|
const problemDetailResult = problemDetail.safeParse(json);
|
|
187
211
|
if (problemDetailResult.success) {
|
|
188
212
|
throw new LapisError(
|
|
189
|
-
response.statusText + problemDetailResult.data.detail,
|
|
213
|
+
response.statusText + (problemDetailResult.data.detail ?? ''),
|
|
190
214
|
response.status,
|
|
191
215
|
problemDetailResult.data,
|
|
192
216
|
requestedData,
|
|
@@ -215,6 +239,11 @@ export const substitutionsOrDeletionsEndpoint = (lapisUrl: string, sequenceType:
|
|
|
215
239
|
? `${lapisUrl}/sample/aminoAcidMutations`
|
|
216
240
|
: `${lapisUrl}/sample/nucleotideMutations`;
|
|
217
241
|
};
|
|
242
|
+
export const mutationsOverTimeEndpoint = (lapisUrl: string, sequenceType: SequenceType) => {
|
|
243
|
+
return sequenceType === 'amino acid'
|
|
244
|
+
? `${lapisUrl}/component/aminoAcidMutationsOverTime`
|
|
245
|
+
: `${lapisUrl}/component/nucleotideMutationsOverTime`;
|
|
246
|
+
};
|
|
218
247
|
export const referenceGenomeEndpoint = (lapisUrl: string) => `${lapisUrl}/sample/referenceGenome`;
|
|
219
248
|
export const lineageDefinitionEndpoint = (lapisUrl: string, lapisField: string) =>
|
|
220
249
|
`${lapisUrl}/sample/lineageDefinition/${lapisField}`;
|
|
@@ -7,6 +7,13 @@ export const orderBy = z.object({
|
|
|
7
7
|
type: orderByType,
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
+
const filterValue = z.union([z.string(), z.number(), z.boolean(), z.null(), z.undefined(), z.array(z.string())]);
|
|
11
|
+
|
|
12
|
+
const dateRange = z.object({
|
|
13
|
+
dateFrom: z.string(),
|
|
14
|
+
dateTo: z.string(),
|
|
15
|
+
});
|
|
16
|
+
|
|
10
17
|
export const lapisBaseRequest = z
|
|
11
18
|
.object({
|
|
12
19
|
limit: z.number().optional(),
|
|
@@ -14,7 +21,7 @@ export const lapisBaseRequest = z
|
|
|
14
21
|
fields: z.array(z.string()).optional(),
|
|
15
22
|
orderBy: z.array(orderBy).optional(),
|
|
16
23
|
})
|
|
17
|
-
.catchall(
|
|
24
|
+
.catchall(filterValue);
|
|
18
25
|
export type LapisBaseRequest = z.infer<typeof lapisBaseRequest>;
|
|
19
26
|
|
|
20
27
|
export const mutationsRequest = lapisBaseRequest.extend({ minProportion: z.number().optional() });
|
|
@@ -32,6 +39,33 @@ const mutationProportionCount = z.object({
|
|
|
32
39
|
export const mutationsResponse = makeLapisResponse(z.array(mutationProportionCount));
|
|
33
40
|
export type MutationsResponse = z.infer<typeof mutationsResponse>;
|
|
34
41
|
|
|
42
|
+
export const mutationsOverTimeRequest = z.object({
|
|
43
|
+
filters: z.record(filterValue),
|
|
44
|
+
downloadAsFile: z.boolean().optional(),
|
|
45
|
+
downloadFileBasename: z.string().optional(),
|
|
46
|
+
compression: z.enum(['gzip', 'none']).optional(),
|
|
47
|
+
includeMutations: z.array(z.string()).optional(),
|
|
48
|
+
dateRanges: z.array(dateRange).optional(),
|
|
49
|
+
dateField: z.string().optional(),
|
|
50
|
+
});
|
|
51
|
+
export type MutationsOverTimeRequest = z.infer<typeof mutationsOverTimeRequest>;
|
|
52
|
+
|
|
53
|
+
export const mutationsOverTimeResponse = makeLapisResponse(
|
|
54
|
+
z.object({
|
|
55
|
+
mutations: z.array(z.string()),
|
|
56
|
+
dateRanges: z.array(dateRange),
|
|
57
|
+
data: z.array(
|
|
58
|
+
z.array(
|
|
59
|
+
z.object({
|
|
60
|
+
count: z.number(),
|
|
61
|
+
coverage: z.number(),
|
|
62
|
+
}),
|
|
63
|
+
),
|
|
64
|
+
),
|
|
65
|
+
}),
|
|
66
|
+
);
|
|
67
|
+
export type MutationsOverTimeResponse = z.infer<typeof mutationsOverTimeResponse>;
|
|
68
|
+
|
|
35
69
|
const insertionCount = z.object({
|
|
36
70
|
insertion: z.string(),
|
|
37
71
|
count: z.number(),
|
|
@@ -8,7 +8,8 @@ export type DivisionOperatorResult<
|
|
|
8
8
|
ResultField extends string,
|
|
9
9
|
NumeratorField extends string,
|
|
10
10
|
DenominatorField extends string,
|
|
11
|
-
> =
|
|
11
|
+
> = Record<KeyField, ValueObject[KeyField]> &
|
|
12
|
+
MappedNumber<ResultField> &
|
|
12
13
|
MappedNumber<NumeratorField> &
|
|
13
14
|
MappedNumber<DenominatorField>;
|
|
14
15
|
|
|
@@ -50,7 +51,8 @@ export class DivisionOperator<
|
|
|
50
51
|
[this.numeratorField]: numeratorValue as number,
|
|
51
52
|
[this.denominatorField]: row[this.valueField] as number,
|
|
52
53
|
[this.resultField]: (numeratorValue as number) / (row[this.valueField] as number),
|
|
53
|
-
} as
|
|
54
|
+
} as Record<KeyField, ValueObject[KeyField]> &
|
|
55
|
+
MappedNumber<ResultField> &
|
|
54
56
|
MappedNumber<NumeratorField> &
|
|
55
57
|
MappedNumber<DenominatorField>;
|
|
56
58
|
});
|
|
@@ -3,7 +3,7 @@ import { type Operator } from './Operator';
|
|
|
3
3
|
import { fetchDetails } from '../lapisApi/lapisApi';
|
|
4
4
|
import { type LapisFilter } from '../types';
|
|
5
5
|
|
|
6
|
-
type Details<Fields extends string> =
|
|
6
|
+
type Details<Fields extends string> = Record<Fields, string | number | boolean | null>;
|
|
7
7
|
|
|
8
8
|
export class FetchDetailsOperator<Fields extends string> implements Operator<Details<Fields>> {
|
|
9
9
|
constructor(
|
|
@@ -4,8 +4,8 @@ import type { Operator } from './Operator';
|
|
|
4
4
|
export class RenameFieldOperator<
|
|
5
5
|
OldFieldName extends string,
|
|
6
6
|
NewFieldName extends string,
|
|
7
|
-
Data extends
|
|
8
|
-
> extends MapOperator<Data, Data &
|
|
7
|
+
Data extends Record<OldFieldName, unknown>,
|
|
8
|
+
> extends MapOperator<Data, Data & Record<NewFieldName, Data[OldFieldName]>> {
|
|
9
9
|
constructor(child: Operator<Data>, oldFieldName: OldFieldName, newFieldName: NewFieldName) {
|
|
10
10
|
super(
|
|
11
11
|
child,
|
|
@@ -13,7 +13,7 @@ export class RenameFieldOperator<
|
|
|
13
13
|
({
|
|
14
14
|
...value,
|
|
15
15
|
[newFieldName]: value[oldFieldName],
|
|
16
|
-
}) as Data &
|
|
16
|
+
}) as Data & Record<NewFieldName, Data[OldFieldName]>,
|
|
17
17
|
);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -11,7 +11,6 @@ import { ErrorBoundary } from '../components/error-boundary';
|
|
|
11
11
|
import { Fullscreen } from '../components/fullscreen';
|
|
12
12
|
import Info, { InfoComponentCode, InfoHeadline1, InfoParagraph } from '../components/info';
|
|
13
13
|
import { LoadingDisplay } from '../components/loading-display';
|
|
14
|
-
import { NoDataDisplay } from '../components/no-data-display';
|
|
15
14
|
import { ResizeContainer } from '../components/resize-container';
|
|
16
15
|
import Tabs from '../components/tabs';
|
|
17
16
|
import { useQuery } from '../useQuery';
|
|
@@ -63,10 +62,6 @@ export const AggregateInner: FunctionComponent<AggregateProps> = (componentProps
|
|
|
63
62
|
throw error;
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
if (data === null) {
|
|
67
|
-
return <NoDataDisplay />;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
65
|
return <AggregatedDataTabs data={data} originalComponentProps={componentProps} />;
|
|
71
66
|
};
|
|
72
67
|
|
|
@@ -58,7 +58,6 @@ const AnnotatedMutationWithoutContext: FunctionComponent<AnnotatedMutationWithou
|
|
|
58
58
|
<Fragment key={annotation.name}>
|
|
59
59
|
<InfoHeadline2>{annotation.name}</InfoHeadline2>
|
|
60
60
|
<InfoParagraph>
|
|
61
|
-
{/* eslint-disable-next-line react/no-danger */}
|
|
62
61
|
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(annotation.description) }} />
|
|
63
62
|
</InfoParagraph>
|
|
64
63
|
</Fragment>
|
|
@@ -33,7 +33,7 @@ export const ConfidenceIntervalSelector: FunctionComponent<ConfidenceIntervalSel
|
|
|
33
33
|
return (
|
|
34
34
|
<Select
|
|
35
35
|
items={items}
|
|
36
|
-
selected={confidenceIntervalMethod
|
|
36
|
+
selected={confidenceIntervalMethod}
|
|
37
37
|
onChange={(event: Event) => {
|
|
38
38
|
const select = event.target as HTMLSelectElement;
|
|
39
39
|
const value = select.value as ConfidenceIntervalMethod;
|
|
@@ -19,7 +19,7 @@ export const ErrorBoundary = <T extends Record<string, unknown>>({
|
|
|
19
19
|
schema,
|
|
20
20
|
children,
|
|
21
21
|
}: RenderableProps<ErrorBoundaryProps<T>>) => {
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- useErrorBoundary unfortunately
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- useErrorBoundary unfortunately returns `[any, ...]`
|
|
23
23
|
const [internalError, resetError] = useErrorBoundary();
|
|
24
24
|
const componentPropsParseError = useCheckComponentProps(schema, componentProps);
|
|
25
25
|
|
|
@@ -54,10 +54,6 @@ export const ErrorBoundary = <T extends Record<string, unknown>>({
|
|
|
54
54
|
|
|
55
55
|
function useCheckComponentProps<T extends Record<string, unknown>>(schema: ZodSchema<T>, componentProps: T) {
|
|
56
56
|
return useMemo(() => {
|
|
57
|
-
if (schema === undefined || componentProps === undefined) {
|
|
58
|
-
return undefined;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
57
|
const parseResult = schema.safeParse(componentProps);
|
|
62
58
|
if (parseResult.success) {
|
|
63
59
|
return undefined;
|
|
@@ -151,7 +151,7 @@ function ZodErrorDetails({ error }: { error: InvalidPropsError }) {
|
|
|
151
151
|
</p>
|
|
152
152
|
)}
|
|
153
153
|
<p>This is a summary of the unexpected attribute values:</p>
|
|
154
|
-
<ul
|
|
154
|
+
<ul className='m-4 list-outside list-disc '>
|
|
155
155
|
{error.zodError.issues.map((issue, index) => {
|
|
156
156
|
const actual =
|
|
157
157
|
issue.path[0] in error.componentProps
|
|
@@ -33,14 +33,11 @@ function findComponentRoot(element: HTMLElement) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
function findShadowRoot(element: HTMLElement) {
|
|
36
|
-
let current: Node = element;
|
|
37
|
-
while (current) {
|
|
36
|
+
let current: Node | null = element;
|
|
37
|
+
while (current !== null) {
|
|
38
38
|
if (current instanceof ShadowRoot) {
|
|
39
39
|
return current;
|
|
40
40
|
}
|
|
41
|
-
if (current.parentNode === null) {
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
41
|
current = current.parentNode;
|
|
45
42
|
}
|
|
46
43
|
return null;
|
|
@@ -15,7 +15,7 @@ const tooltipText = 'This is a tooltip which shows some information.';
|
|
|
15
15
|
|
|
16
16
|
export const InfoStory: StoryObj = {
|
|
17
17
|
render: (args) => (
|
|
18
|
-
<div
|
|
18
|
+
<div className='flex justify-center px-4 py-16'>
|
|
19
19
|
<Info {...args}>{tooltipText}</Info>
|
|
20
20
|
</div>
|
|
21
21
|
),
|
|
@@ -60,21 +60,21 @@ export const ProportionSelector: FunctionComponent<ProportionSelectorProps> = ({
|
|
|
60
60
|
const indicateError = internalMinProportion > internalMaxProportion;
|
|
61
61
|
|
|
62
62
|
return (
|
|
63
|
-
<div
|
|
64
|
-
<div
|
|
63
|
+
<div className='flex flex-col w-64 mb-2'>
|
|
64
|
+
<div className='flex items-center '>
|
|
65
65
|
<PercentInput
|
|
66
66
|
percentage={internalMinProportion * 100}
|
|
67
67
|
setPercentage={updateMinPercentage}
|
|
68
68
|
indicateError={indicateError}
|
|
69
69
|
/>
|
|
70
|
-
<div
|
|
70
|
+
<div className='m-2'>-</div>
|
|
71
71
|
<PercentInput
|
|
72
72
|
percentage={internalMaxProportion * 100}
|
|
73
73
|
setPercentage={updateMaxPercentage}
|
|
74
74
|
indicateError={indicateError}
|
|
75
75
|
/>
|
|
76
76
|
</div>
|
|
77
|
-
<div
|
|
77
|
+
<div className='my-1'>
|
|
78
78
|
<MinMaxRangeSlider
|
|
79
79
|
min={internalMinProportion * 100}
|
|
80
80
|
max={internalMaxProportion * 100}
|
|
@@ -10,7 +10,7 @@ export interface SelectProps {
|
|
|
10
10
|
|
|
11
11
|
export const Select: FunctionComponent<SelectProps> = ({ items, selected, onChange, selectStyle }) => {
|
|
12
12
|
return (
|
|
13
|
-
<select
|
|
13
|
+
<select className={`select ${selectStyle} w-fit`} value={selected} onChange={onChange}>
|
|
14
14
|
{items.map((item) => (
|
|
15
15
|
<option key={item.value} value={item.value} disabled={item.disabled}>
|
|
16
16
|
{item.label}
|
|
@@ -29,7 +29,7 @@ export interface TableProps {
|
|
|
29
29
|
export const Table = ({ data, columns, pageSize }: TableProps) => {
|
|
30
30
|
const pagination = typeof pageSize === 'number' ? { limit: pageSize } : pageSize;
|
|
31
31
|
|
|
32
|
-
const wrapper = useRef(null);
|
|
32
|
+
const wrapper = useRef<HTMLDivElement>(null);
|
|
33
33
|
|
|
34
34
|
useEffect(() => {
|
|
35
35
|
if (wrapper.current === null) {
|
|
@@ -40,7 +40,7 @@ const Tabs = forwardRef<HTMLDivElement, ComponentTabsProps>(({ tabs, toolbar },
|
|
|
40
40
|
const toolbarElement = typeof toolbar === 'function' ? toolbar(activeTab) : toolbar;
|
|
41
41
|
|
|
42
42
|
return (
|
|
43
|
-
<div ref={ref} className='h-full w-full flex flex-col'>
|
|
43
|
+
<div ref={ref} className='h-full w-full flex flex-col bg-white'>
|
|
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>}
|
|
@@ -24,7 +24,7 @@ const tooltipContent = 'This is some content.';
|
|
|
24
24
|
|
|
25
25
|
export const TooltipStory: StoryObj<TooltipProps> = {
|
|
26
26
|
render: (args) => (
|
|
27
|
-
<div
|
|
27
|
+
<div className='flex justify-center px-4 py-16'>
|
|
28
28
|
<Tooltip {...args}>
|
|
29
29
|
<div className='bg-red-200'>Hover me</div>
|
|
30
30
|
</Tooltip>
|
|
@@ -47,7 +47,7 @@ const Tooltip: FunctionComponent<TooltipProps> = ({ children, content, position
|
|
|
47
47
|
<div>{children}</div>
|
|
48
48
|
<div
|
|
49
49
|
className={`absolute z-10 w-max bg-white p-4 border border-gray-200 rounded-md invisible group-hover:visible ${getPositionCss(position)}`}
|
|
50
|
-
style={
|
|
50
|
+
style={tooltipStyle}
|
|
51
51
|
>
|
|
52
52
|
{content}
|
|
53
53
|
</div>
|
|
@@ -72,7 +72,7 @@ const XAxis: FunctionComponent<XAxisProps> = (componentProps) => {
|
|
|
72
72
|
return (
|
|
73
73
|
<div
|
|
74
74
|
key={idx}
|
|
75
|
-
|
|
75
|
+
className='absolute text-xs text-black px-1 hover:opacity-80 border-l border-r border-gray-400 border-t'
|
|
76
76
|
style={{
|
|
77
77
|
left: `calc(${leftPercent}% - 1px)`,
|
|
78
78
|
width: `calc(${widthPercent}% - 1px)`,
|
|
@@ -200,10 +200,10 @@ const CDSPlot: FunctionComponent<CDSProps> = (componentProps) => {
|
|
|
200
200
|
};
|
|
201
201
|
|
|
202
202
|
return (
|
|
203
|
-
<div ref={ref}
|
|
203
|
+
<div ref={ref} className='p-4'>
|
|
204
204
|
<CDSBars gffData={gffData} zoomStart={zoomStart} zoomEnd={zoomEnd} />
|
|
205
205
|
<XAxis zoomStart={zoomStart} zoomEnd={zoomEnd} fullWidth={width} />
|
|
206
|
-
<div
|
|
206
|
+
<div className='relative w-full h-5'>
|
|
207
207
|
<MinMaxRangeSlider
|
|
208
208
|
min={zoomStart}
|
|
209
209
|
max={zoomEnd}
|