@genspectrum/dashboard-components 0.13.7 → 0.14.2

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.
Files changed (82) hide show
  1. package/custom-elements.json +24 -62
  2. package/dist/{LineageFilterChangedEvent-GedKNGFI.js → LineageFilterChangedEvent-C9dXOxt6.js} +11 -3
  3. package/dist/LineageFilterChangedEvent-C9dXOxt6.js.map +1 -0
  4. package/dist/assets/mutationOverTimeWorker-Dxnxrfe0.js.map +1 -1
  5. package/dist/components.d.ts +40 -50
  6. package/dist/components.js +112 -91
  7. package/dist/components.js.map +1 -1
  8. package/dist/util.d.ts +38 -28
  9. package/dist/util.js +1 -1
  10. package/package.json +2 -2
  11. package/src/lapisApi/lapisApi.ts +1 -1
  12. package/src/operator/FillMissingOperator.spec.ts +1 -1
  13. package/src/operator/GroupByAndSumOperator.spec.ts +1 -1
  14. package/src/operator/GroupByOperator.spec.ts +2 -2
  15. package/src/operator/MapOperator.spec.ts +1 -1
  16. package/src/operator/MockOperator.spec.ts +1 -1
  17. package/src/operator/MockOperator.ts +6 -4
  18. package/src/operator/SortOperator.spec.ts +1 -1
  19. package/src/preact/LapisUrlContext.ts +14 -1
  20. package/src/preact/aggregatedData/aggregate.stories.tsx +4 -4
  21. package/src/preact/aggregatedData/aggregate.tsx +3 -4
  22. package/src/preact/components/csv-download-button.stories.tsx +2 -2
  23. package/src/preact/components/csv-download-button.tsx +1 -1
  24. package/src/preact/components/error-boundary.stories.tsx +5 -5
  25. package/src/preact/components/error-boundary.tsx +14 -3
  26. package/src/preact/components/error-display.stories.tsx +9 -9
  27. package/src/preact/components/fullscreen.tsx +3 -3
  28. package/src/preact/components/info.tsx +1 -1
  29. package/src/preact/components/mutation-type-selector.stories.tsx +1 -1
  30. package/src/preact/components/table.stories.tsx +3 -3
  31. package/src/preact/components/table.tsx +1 -1
  32. package/src/preact/dateRangeSelector/computeInitialValues.spec.ts +34 -20
  33. package/src/preact/dateRangeSelector/computeInitialValues.ts +25 -21
  34. package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +107 -46
  35. package/src/preact/dateRangeSelector/date-range-selector.tsx +31 -22
  36. package/src/preact/dateRangeSelector/dateRangeOption.ts +11 -1
  37. package/src/preact/lineageFilter/lineage-filter.stories.tsx +9 -9
  38. package/src/preact/lineageFilter/lineage-filter.tsx +3 -4
  39. package/src/preact/locationFilter/fetchAutocompletionList.ts +1 -1
  40. package/src/preact/locationFilter/location-filter.stories.tsx +9 -9
  41. package/src/preact/locationFilter/location-filter.tsx +4 -4
  42. package/src/preact/map/sequences-by-location.stories.tsx +4 -4
  43. package/src/preact/map/sequences-by-location.tsx +3 -4
  44. package/src/preact/mutationComparison/mutation-comparison.stories.tsx +3 -3
  45. package/src/preact/mutationComparison/mutation-comparison.tsx +4 -4
  46. package/src/preact/mutationFilter/mutation-filter-info.tsx +3 -3
  47. package/src/preact/mutationFilter/mutation-filter.stories.tsx +7 -7
  48. package/src/preact/mutations/getMutationsGridData.ts +1 -1
  49. package/src/preact/mutations/mutations.stories.tsx +3 -3
  50. package/src/preact/mutations/mutations.tsx +4 -4
  51. package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +3 -3
  52. package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +4 -4
  53. package/src/preact/mutationsOverTime/mutations-over-time.tsx +5 -4
  54. package/src/preact/numberSequencesOverTime/number-sequences-over-time.stories.tsx +4 -4
  55. package/src/preact/numberSequencesOverTime/number-sequences-over-time.tsx +4 -4
  56. package/src/preact/prevalenceOverTime/prevalence-over-time-bubble-chart.tsx +4 -4
  57. package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +4 -4
  58. package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +4 -4
  59. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +4 -4
  60. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +4 -4
  61. package/src/preact/shared/floating-ui/hooks.ts +1 -1
  62. package/src/preact/statistic/statistics.stories.tsx +3 -3
  63. package/src/preact/statistic/statistics.tsx +2 -3
  64. package/src/preact/textInput/text-input.stories.tsx +7 -7
  65. package/src/preact/textInput/text-input.tsx +3 -4
  66. package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.stories.tsx +3 -3
  67. package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +4 -4
  68. package/src/utils/map2d.ts +1 -0
  69. package/src/web-components/PreactLitAdapter.tsx +3 -3
  70. package/src/web-components/gs-app.stories.ts +7 -7
  71. package/src/web-components/gs-app.ts +3 -1
  72. package/src/web-components/input/gs-date-range-selector.stories.ts +10 -17
  73. package/src/web-components/input/gs-date-range-selector.tsx +15 -38
  74. package/src/web-components/input/gs-lineage-filter.stories.ts +1 -1
  75. package/src/web-components/input/gs-location-filter.stories.ts +1 -1
  76. package/src/web-components/input/gs-mutation-filter.stories.ts +7 -7
  77. package/src/web-components/input/gs-text-input.stories.ts +3 -3
  78. package/src/web-components/visualization/gs-aggregate.tsx +2 -2
  79. package/standalone-bundle/assets/mutationOverTimeWorker-CmSrq4SZ.js.map +1 -1
  80. package/standalone-bundle/dashboard-components.js +6068 -6055
  81. package/standalone-bundle/dashboard-components.js.map +1 -1
  82. package/dist/LineageFilterChangedEvent-GedKNGFI.js.map +0 -1
package/dist/util.d.ts CHANGED
@@ -136,10 +136,20 @@ declare const dateRangeOptionSchema: default_2.ZodObject<{
136
136
  dateTo?: string | undefined;
137
137
  }>;
138
138
 
139
- export declare type DateRangeSelectOption = string | {
140
- dateFrom: string;
141
- dateTo: string;
142
- };
139
+ export declare type DateRangeSelectOption = Required<DateRangeValue>;
140
+
141
+ declare type DateRangeValue = default_2.infer<typeof dateRangeValueSchema>;
142
+
143
+ declare const dateRangeValueSchema: default_2.ZodUnion<[default_2.ZodString, default_2.ZodObject<{
144
+ dateFrom: default_2.ZodOptional<default_2.ZodString>;
145
+ dateTo: default_2.ZodOptional<default_2.ZodString>;
146
+ }, "strip", default_2.ZodTypeAny, {
147
+ dateFrom?: string | undefined;
148
+ dateTo?: string | undefined;
149
+ }, {
150
+ dateFrom?: string | undefined;
151
+ dateTo?: string | undefined;
152
+ }>]>;
143
153
 
144
154
  export declare type LapisFilter = default_2.infer<typeof lapisFilterSchema>;
145
155
 
@@ -838,7 +848,7 @@ declare global {
838
848
 
839
849
  declare global {
840
850
  interface HTMLElementTagNameMap {
841
- 'gs-mutation-comparison-component': MutationComparisonComponent;
851
+ 'gs-mutations-component': MutationsComponent;
842
852
  }
843
853
  }
844
854
 
@@ -846,7 +856,7 @@ declare global {
846
856
  declare global {
847
857
  namespace JSX {
848
858
  interface IntrinsicElements {
849
- 'gs-mutation-comparison-component': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
859
+ 'gs-mutations-component': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
850
860
  }
851
861
  }
852
862
  }
@@ -854,7 +864,7 @@ declare global {
854
864
 
855
865
  declare global {
856
866
  interface HTMLElementTagNameMap {
857
- 'gs-mutations-component': MutationsComponent;
867
+ 'gs-mutation-comparison-component': MutationComparisonComponent;
858
868
  }
859
869
  }
860
870
 
@@ -862,7 +872,7 @@ declare global {
862
872
  declare global {
863
873
  namespace JSX {
864
874
  interface IntrinsicElements {
865
- 'gs-mutations-component': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
875
+ 'gs-mutation-comparison-component': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
866
876
  }
867
877
  }
868
878
  }
@@ -902,7 +912,7 @@ declare global {
902
912
 
903
913
  declare global {
904
914
  interface HTMLElementTagNameMap {
905
- 'gs-aggregate': AggregateComponent;
915
+ 'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
906
916
  }
907
917
  }
908
918
 
@@ -910,7 +920,7 @@ declare global {
910
920
  declare global {
911
921
  namespace JSX {
912
922
  interface IntrinsicElements {
913
- 'gs-aggregate': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
923
+ 'gs-number-sequences-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
914
924
  }
915
925
  }
916
926
  }
@@ -918,7 +928,7 @@ declare global {
918
928
 
919
929
  declare global {
920
930
  interface HTMLElementTagNameMap {
921
- 'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
931
+ 'gs-aggregate': AggregateComponent;
922
932
  }
923
933
  }
924
934
 
@@ -926,7 +936,7 @@ declare global {
926
936
  declare global {
927
937
  namespace JSX {
928
938
  interface IntrinsicElements {
929
- 'gs-number-sequences-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
939
+ 'gs-aggregate': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
930
940
  }
931
941
  }
932
942
  }
@@ -950,7 +960,7 @@ declare global {
950
960
 
951
961
  declare global {
952
962
  interface HTMLElementTagNameMap {
953
- 'gs-statistics': StatisticsComponent;
963
+ 'gs-sequences-by-location': SequencesByLocationComponent;
954
964
  }
955
965
  }
956
966
 
@@ -958,7 +968,7 @@ declare global {
958
968
  declare global {
959
969
  namespace JSX {
960
970
  interface IntrinsicElements {
961
- 'gs-statistics': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
971
+ 'gs-sequences-by-location': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
962
972
  }
963
973
  }
964
974
  }
@@ -966,7 +976,7 @@ declare global {
966
976
 
967
977
  declare global {
968
978
  interface HTMLElementTagNameMap {
969
- 'gs-sequences-by-location': SequencesByLocationComponent;
979
+ 'gs-statistics': StatisticsComponent;
970
980
  }
971
981
  }
972
982
 
@@ -974,7 +984,7 @@ declare global {
974
984
  declare global {
975
985
  namespace JSX {
976
986
  interface IntrinsicElements {
977
- 'gs-sequences-by-location': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
987
+ 'gs-statistics': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
978
988
  }
979
989
  }
980
990
  }
@@ -1018,10 +1028,10 @@ declare global {
1018
1028
 
1019
1029
  declare global {
1020
1030
  interface HTMLElementTagNameMap {
1021
- 'gs-location-filter': LocationFilterComponent;
1031
+ 'gs-text-input': TextInputComponent;
1022
1032
  }
1023
1033
  interface HTMLElementEventMap {
1024
- 'gs-location-changed': LocationChangedEvent;
1034
+ 'gs-text-input-changed': TextInputChangedEvent;
1025
1035
  }
1026
1036
  }
1027
1037
 
@@ -1029,7 +1039,7 @@ declare global {
1029
1039
  declare global {
1030
1040
  namespace JSX {
1031
1041
  interface IntrinsicElements {
1032
- 'gs-location-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1042
+ 'gs-text-input': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1033
1043
  }
1034
1044
  }
1035
1045
  }
@@ -1037,10 +1047,10 @@ declare global {
1037
1047
 
1038
1048
  declare global {
1039
1049
  interface HTMLElementTagNameMap {
1040
- 'gs-mutation-filter': MutationFilterComponent;
1050
+ 'gs-location-filter': LocationFilterComponent;
1041
1051
  }
1042
1052
  interface HTMLElementEventMap {
1043
- 'gs-mutation-filter-changed': CustomEvent<MutationsFilter>;
1053
+ 'gs-location-changed': LocationChangedEvent;
1044
1054
  }
1045
1055
  }
1046
1056
 
@@ -1048,7 +1058,7 @@ declare global {
1048
1058
  declare global {
1049
1059
  namespace JSX {
1050
1060
  interface IntrinsicElements {
1051
- 'gs-mutation-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1061
+ 'gs-location-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1052
1062
  }
1053
1063
  }
1054
1064
  }
@@ -1056,10 +1066,10 @@ declare global {
1056
1066
 
1057
1067
  declare global {
1058
1068
  interface HTMLElementTagNameMap {
1059
- 'gs-text-input': TextInputComponent;
1069
+ 'gs-lineage-filter': LineageFilterComponent;
1060
1070
  }
1061
1071
  interface HTMLElementEventMap {
1062
- 'gs-text-input-changed': TextInputChangedEvent;
1072
+ 'gs-lineage-filter-changed': LineageFilterChangedEvent;
1063
1073
  }
1064
1074
  }
1065
1075
 
@@ -1067,7 +1077,7 @@ declare global {
1067
1077
  declare global {
1068
1078
  namespace JSX {
1069
1079
  interface IntrinsicElements {
1070
- 'gs-text-input': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1080
+ 'gs-lineage-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1071
1081
  }
1072
1082
  }
1073
1083
  }
@@ -1075,10 +1085,10 @@ declare global {
1075
1085
 
1076
1086
  declare global {
1077
1087
  interface HTMLElementTagNameMap {
1078
- 'gs-lineage-filter': LineageFilterComponent;
1088
+ 'gs-mutation-filter': MutationFilterComponent;
1079
1089
  }
1080
1090
  interface HTMLElementEventMap {
1081
- 'gs-lineage-filter-changed': LineageFilterChangedEvent;
1091
+ 'gs-mutation-filter-changed': CustomEvent<MutationsFilter>;
1082
1092
  }
1083
1093
  }
1084
1094
 
@@ -1086,7 +1096,7 @@ declare global {
1086
1096
  declare global {
1087
1097
  namespace JSX {
1088
1098
  interface IntrinsicElements {
1089
- 'gs-lineage-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1099
+ 'gs-mutation-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
1090
1100
  }
1091
1101
  }
1092
1102
  }
package/dist/util.js CHANGED
@@ -1,4 +1,4 @@
1
- import { D, a, L, T, d, v } from "./LineageFilterChangedEvent-GedKNGFI.js";
1
+ import { D, a, L, T, d, v } from "./LineageFilterChangedEvent-C9dXOxt6.js";
2
2
  export {
3
3
  D as DateRangeOptionChangedEvent,
4
4
  a as LineageFilterChangedEvent,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genspectrum/dashboard-components",
3
- "version": "0.13.7",
3
+ "version": "0.14.2",
4
4
  "description": "GenSpectrum web components for building dashboards",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-only",
@@ -9,7 +9,7 @@
9
9
  "types": "dist/genspectrum-components.d.ts",
10
10
  "repository": {
11
11
  "type": "git",
12
- "url": "https://github.com/GenSpectrum/dashboard-components.git",
12
+ "url": "git+https://github.com/GenSpectrum/dashboard-components.git",
13
13
  "directory": "components"
14
14
  },
15
15
  "publishConfig": {
@@ -146,7 +146,7 @@ async function callLapis(
146
146
  const handleErrors = async (response: Response, requestedData: string) => {
147
147
  if (!response.ok) {
148
148
  if (response.status >= 400 && response.status < 500) {
149
- const json = await response.json();
149
+ const json = (await response.json()) as unknown;
150
150
 
151
151
  const lapisErrorResult = lapisError.safeParse(json);
152
152
  if (lapisErrorResult.success) {
@@ -23,6 +23,6 @@ describe('FillMissingOperator', () => {
23
23
  (id) => ({ id }),
24
24
  );
25
25
  const result = await query.evaluate('lapis');
26
- await expectEqualAfterSorting(result.content, [{ id: 1 }, { id: 2 }, { id: 3 }], (a, b) => a.id - b.id);
26
+ expectEqualAfterSorting(result.content, [{ id: 1 }, { id: 2 }, { id: 3 }], (a, b) => a.id - b.id);
27
27
  });
28
28
  });
@@ -14,7 +14,7 @@ describe('GroupByAndSumOperator', () => {
14
14
 
15
15
  const query = new GroupByAndSumOperator(child, 'lineage', 'n');
16
16
  const result = await query.evaluate('lapis');
17
- await expectEqualAfterSorting(
17
+ expectEqualAfterSorting(
18
18
  result.content,
19
19
  [
20
20
  { lineage: 'A', n: 3 },
@@ -17,7 +17,7 @@ describe('GroupByOperator', () => {
17
17
  n: values.length,
18
18
  }));
19
19
  const resultCount = await queryCount.evaluate('lapis');
20
- await expectEqualAfterSorting(
20
+ expectEqualAfterSorting(
21
21
  resultCount.content,
22
22
  [
23
23
  { lineage: 'A', n: 2 },
@@ -31,7 +31,7 @@ describe('GroupByOperator', () => {
31
31
  n: values.reduce((a, b) => a + b.n, 0),
32
32
  }));
33
33
  const resultSum = await querySum.evaluate('lapis');
34
- await expectEqualAfterSorting(
34
+ expectEqualAfterSorting(
35
35
  resultSum.content,
36
36
  [
37
37
  { lineage: 'A', n: 3 },
@@ -8,6 +8,6 @@ describe('MapOperator', () => {
8
8
  const child = new MockOperator([1, 2, 3]);
9
9
  const query = new MapOperator(child, (x) => x * 2);
10
10
  const result = await query.evaluate('lapis');
11
- await expect(result.content).deep.equal([2, 4, 6]);
11
+ expect(result.content).deep.equal([2, 4, 6]);
12
12
  });
13
13
  });
@@ -6,6 +6,6 @@ describe('MockOperator', () => {
6
6
  it('should be a mock', async () => {
7
7
  const query = new MockOperator([1, 2, 3]);
8
8
  const result = await query.evaluate();
9
- await expect(result.content).to.deep.equal([1, 2, 3]);
9
+ expect(result.content).to.deep.equal([1, 2, 3]);
10
10
  });
11
11
  });
@@ -4,9 +4,11 @@ import { type Operator } from './Operator';
4
4
  export class MockOperator<T> implements Operator<T> {
5
5
  constructor(private content: T[]) {}
6
6
 
7
- async evaluate(): Promise<Dataset<T>> {
8
- return {
9
- content: this.content,
10
- };
7
+ evaluate(): Promise<Dataset<T>> {
8
+ return new Promise((resolve) =>
9
+ resolve({
10
+ content: this.content,
11
+ }),
12
+ );
11
13
  }
12
14
  }
@@ -8,6 +8,6 @@ describe('SortOperator', () => {
8
8
  const child = new MockOperator([3, 1, 2]);
9
9
  const query = new SortOperator(child, (a, b) => a - b);
10
10
  const result = await query.evaluate('lapis');
11
- await expect(result.content).deep.equal([1, 2, 3]);
11
+ expect(result.content).deep.equal([1, 2, 3]);
12
12
  });
13
13
  });
@@ -1,3 +1,16 @@
1
1
  import { createContext } from 'preact';
2
+ import { useContext } from 'preact/hooks';
2
3
 
3
- export const LapisUrlContext = createContext('');
4
+ const LapisUrlContext = createContext('');
5
+
6
+ export const LapisUrlContextProvider = LapisUrlContext.Provider;
7
+
8
+ export const useLapisUrl = () => {
9
+ const lapisUrl = useContext(LapisUrlContext);
10
+
11
+ if (lapisUrl.endsWith('/')) {
12
+ return lapisUrl.slice(0, -1);
13
+ }
14
+
15
+ return lapisUrl;
16
+ };
@@ -4,7 +4,7 @@ import { expect, waitFor, within } from '@storybook/test';
4
4
  import aggregatedData from './__mockData__/aggregated.json';
5
5
  import { Aggregate, type AggregateProps } from './aggregate';
6
6
  import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
7
- import { LapisUrlContext } from '../LapisUrlContext';
7
+ import { LapisUrlContextProvider } from '../LapisUrlContext';
8
8
  import { expectInvalidAttributesErrorMessage, playThatExpectsErrorMessage } from '../shared/stories/expectErrorMessage';
9
9
 
10
10
  const meta: Meta<AggregateProps> = {
@@ -44,9 +44,9 @@ export default meta;
44
44
 
45
45
  export const Default: StoryObj<AggregateProps> = {
46
46
  render: (args) => (
47
- <LapisUrlContext.Provider value={LAPIS_URL}>
47
+ <LapisUrlContextProvider value={LAPIS_URL}>
48
48
  <Aggregate {...args} />
49
- </LapisUrlContext.Provider>
49
+ </LapisUrlContextProvider>
50
50
  ),
51
51
  args: {
52
52
  fields: ['division', 'host'],
@@ -104,7 +104,7 @@ export const WithEmptyFieldString: StoryObj<AggregateProps> = {
104
104
  fields: [''],
105
105
  },
106
106
  play: async ({ canvasElement, step }) => {
107
- step('expect error message', async () => {
107
+ await step('expect error message', async () => {
108
108
  await expectInvalidAttributesErrorMessage(canvasElement, 'String must contain at least 1 character(s)');
109
109
  });
110
110
  },
@@ -1,11 +1,10 @@
1
1
  import { type FunctionComponent } from 'preact';
2
- import { useContext } from 'preact/hooks';
3
2
  import z from 'zod';
4
3
 
4
+ import { useLapisUrl } from '../LapisUrlContext';
5
5
  import { AggregateTable } from './aggregate-table';
6
6
  import { type AggregateData, queryAggregateData } from '../../query/queryAggregateData';
7
7
  import { lapisFilterSchema, views } from '../../types';
8
- import { LapisUrlContext } from '../LapisUrlContext';
9
8
  import { CsvDownloadButton } from '../components/csv-download-button';
10
9
  import { ErrorBoundary } from '../components/error-boundary';
11
10
  import { Fullscreen } from '../components/fullscreen';
@@ -48,7 +47,7 @@ export const Aggregate: FunctionComponent<AggregateProps> = (componentProps) =>
48
47
 
49
48
  export const AggregateInner: FunctionComponent<AggregateProps> = (componentProps) => {
50
49
  const { fields, lapisFilter, initialSortField, initialSortDirection } = componentProps;
51
- const lapis = useContext(LapisUrlContext);
50
+ const lapis = useLapisUrl();
52
51
 
53
52
  const { data, error, isLoading } = useQuery(async () => {
54
53
  return queryAggregateData(lapisFilter, fields, lapis);
@@ -129,7 +128,7 @@ type AggregateInfoProps = {
129
128
  };
130
129
 
131
130
  const AggregateInfo: FunctionComponent<AggregateInfoProps> = ({ originalComponentProps }) => {
132
- const lapis = useContext(LapisUrlContext);
131
+ const lapis = useLapisUrl();
133
132
  return (
134
133
  <Info>
135
134
  <InfoHeadline1>Aggregated data</InfoHeadline1>
@@ -1,7 +1,7 @@
1
1
  import { type StoryObj } from '@storybook/preact';
2
2
  import { type Meta } from '@storybook/web-components';
3
3
 
4
- import { CsvDownloadButton, type CsvDownloadButtonProps } from './csv-download-button';
4
+ import { CsvDownloadButton, type CsvDownloadButtonProps, type DataValue } from './csv-download-button';
5
5
 
6
6
  const meta: Meta<CsvDownloadButtonProps> = {
7
7
  title: 'Component/CSV Download Button',
@@ -10,7 +10,7 @@ const meta: Meta<CsvDownloadButtonProps> = {
10
10
 
11
11
  export default meta;
12
12
 
13
- export const DownloadButton: StoryObj = {
13
+ export const DownloadButton: StoryObj<CsvDownloadButtonProps & { data: Record<string, DataValue>[] }> = {
14
14
  render: (args) => {
15
15
  return <CsvDownloadButton label={args.label} filename={args.filename} getData={() => args.data} />;
16
16
  },
@@ -4,7 +4,7 @@ type ToStringable = {
4
4
  toString: () => string;
5
5
  };
6
6
 
7
- type DataValue = string | number | boolean | null | ToStringable;
7
+ export type DataValue = string | number | boolean | null | undefined | ToStringable;
8
8
 
9
9
  export interface CsvDownloadButtonProps {
10
10
  label?: string;
@@ -2,7 +2,7 @@ import { type Meta, type StoryObj } from '@storybook/preact';
2
2
  import { expect, waitFor, within } from '@storybook/test';
3
3
  import z from 'zod';
4
4
 
5
- import { ErrorBoundary } from './error-boundary';
5
+ import { ErrorBoundary, type ErrorBoundaryProps } from './error-boundary';
6
6
  import { UserFacingError } from './error-display';
7
7
 
8
8
  const meta: Meta = {
@@ -28,7 +28,7 @@ const someSchema = z.object({
28
28
  const someValidProps = { test: 'someValue' };
29
29
  const someInvalidProps = { test: '' };
30
30
 
31
- export const ErrorBoundaryWithoutErrorStory: StoryObj = {
31
+ export const ErrorBoundaryWithoutErrorStory: StoryObj<ErrorBoundaryProps<typeof someValidProps>> = {
32
32
  render: (args) => (
33
33
  <ErrorBoundary size={args.size} schema={someSchema} componentProps={someValidProps}>
34
34
  <div>Some content</div>
@@ -41,7 +41,7 @@ export const ErrorBoundaryWithoutErrorStory: StoryObj = {
41
41
  },
42
42
  };
43
43
 
44
- export const ErrorBoundaryWithErrorStory: StoryObj = {
44
+ export const ErrorBoundaryWithErrorStory: StoryObj<ErrorBoundaryProps<typeof someValidProps>> = {
45
45
  render: (args) => (
46
46
  <ErrorBoundary size={args.size} schema={someSchema} componentProps={someValidProps}>
47
47
  <ContentThatThrowsError error={() => new Error('Some error')} />
@@ -55,7 +55,7 @@ export const ErrorBoundaryWithErrorStory: StoryObj = {
55
55
  },
56
56
  };
57
57
 
58
- export const ErrorBoundaryWithParsingErrorStory: StoryObj = {
58
+ export const ErrorBoundaryWithParsingErrorStory: StoryObj<ErrorBoundaryProps<typeof someValidProps>> = {
59
59
  render: (args) => (
60
60
  <ErrorBoundary size={args.size} schema={someSchema} componentProps={someInvalidProps}>
61
61
  <ContentThatThrowsError error={() => new Error('Some error')} />
@@ -69,7 +69,7 @@ export const ErrorBoundaryWithParsingErrorStory: StoryObj = {
69
69
  },
70
70
  };
71
71
 
72
- export const ErrorBoundaryWithUserFacingErrorStory: StoryObj = {
72
+ export const ErrorBoundaryWithUserFacingErrorStory: StoryObj<ErrorBoundaryProps<typeof someValidProps>> = {
73
73
  render: (args) => (
74
74
  <ErrorBoundary size={args.size} schema={someSchema} componentProps={someValidProps}>
75
75
  <ContentThatThrowsError error={() => new UserFacingError('Error Headline', 'Some error')} />
@@ -1,11 +1,11 @@
1
1
  import { type RenderableProps } from 'preact';
2
- import { useErrorBoundary, useMemo } from 'preact/hooks';
2
+ import { useEffect, useErrorBoundary, useMemo } from 'preact/hooks';
3
3
  import { type ZodSchema } from 'zod';
4
4
 
5
5
  import { ErrorDisplay, type ErrorDisplayProps, InvalidPropsError } from './error-display';
6
6
  import { ResizeContainer, type Size } from './resize-container';
7
7
 
8
- type ErrorBoundaryProps<T> = {
8
+ export type ErrorBoundaryProps<T> = {
9
9
  size: Size;
10
10
  componentProps: T;
11
11
  schema: ZodSchema<T>;
@@ -19,13 +19,24 @@ 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 return `[any, ...]`
22
23
  const [internalError, resetError] = useErrorBoundary();
23
24
  const componentPropsParseError = useCheckComponentProps(schema, componentProps);
24
25
 
26
+ useEffect(
27
+ () => {
28
+ if (internalError) {
29
+ resetError();
30
+ }
31
+ },
32
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- this should run if and only if the props of the component change
33
+ [componentProps],
34
+ );
35
+
25
36
  if (internalError) {
26
37
  return (
27
38
  <ResizeContainer size={size}>
28
- <ErrorDisplay error={internalError} resetError={resetError} layout={layout} />
39
+ <ErrorDisplay error={internalError as Error} resetError={resetError} layout={layout} />
29
40
  </ResizeContainer>
30
41
  );
31
42
  }
@@ -39,12 +39,12 @@ export const UserFacingErrorStory: StoryObj = {
39
39
  const error = canvas.getByText('Oops! Something went wrong.', { exact: false });
40
40
  const detailMessage = () => canvas.getByText('some message');
41
41
  await waitFor(() => expect(error).toBeInTheDocument());
42
- await waitFor(() => {
43
- expect(detailMessage()).not.toBeVisible();
42
+ await waitFor(async () => {
43
+ await expect(detailMessage()).not.toBeVisible();
44
44
  });
45
45
  await userEvent.click(canvas.getByText('Show details.'));
46
- await waitFor(() => {
47
- expect(detailMessage()).toBeVisible();
46
+ await waitFor(async () => {
47
+ await expect(detailMessage()).toBeVisible();
48
48
  });
49
49
  },
50
50
  };
@@ -60,9 +60,9 @@ export const FiresEvent: StoryObj = {
60
60
  const listenerMock = fn();
61
61
  canvasElement.addEventListener('gs-error', listenerMock);
62
62
 
63
- await waitFor(() => {
64
- expect(listenerMock.mock.calls.at(-1)![0].error.name).toStrictEqual('UserFacingError');
65
- expect(listenerMock.mock.calls.at(-1)![0].error.message).toStrictEqual('some message');
63
+ await waitFor(async () => {
64
+ await expect(listenerMock.mock.calls.at(-1)![0].error.name).toStrictEqual('UserFacingError');
65
+ await expect(listenerMock.mock.calls.at(-1)![0].error.message).toStrictEqual('some message');
66
66
  });
67
67
  },
68
68
  };
@@ -81,8 +81,8 @@ export const TriggersResetErrorOnReloadButton: StoryObj = {
81
81
 
82
82
  await userEvent.click(canvas.getByText('Try again'));
83
83
 
84
- await waitFor(() => {
85
- expect(resetErrorMock).toHaveBeenCalled();
84
+ await waitFor(async () => {
85
+ await expect(resetErrorMock).toHaveBeenCalled();
86
86
  });
87
87
  },
88
88
  };
@@ -6,14 +6,14 @@ export const Fullscreen = () => {
6
6
  return (
7
7
  <button
8
8
  ref={element}
9
- onClick={async () => {
9
+ onClick={() => {
10
10
  if (element.current) {
11
11
  if (isFullscreen) {
12
- await document.exitFullscreen();
12
+ void document.exitFullscreen();
13
13
  } else {
14
14
  const componentRoot = findComponentRoot(element.current);
15
15
  if (componentRoot) {
16
- await componentRoot.requestFullscreen();
16
+ void componentRoot.requestFullscreen();
17
17
  }
18
18
  }
19
19
  }
@@ -97,7 +97,7 @@ function componentParametersToCode(componentName: string, params: object, lapisU
97
97
 
98
98
  const attributes = indentLines(
99
99
  Object.entries(params)
100
- .map(([key, value]) => `${key}='${stringifyIfNeeded(value)}'`)
100
+ .map(([key, value]) => `${key}='${stringifyIfNeeded(value) as string}'`)
101
101
  .join('\n'),
102
102
  4,
103
103
  );
@@ -108,7 +108,7 @@ export const OneTypesSelected: StoryObj<MutationTypeSelectorProps> = {
108
108
  const canvas = within(canvasElement);
109
109
 
110
110
  await step('Show the selected type as label', async () => {
111
- const substitutionElements = await canvas.getAllByText('Substitution');
111
+ const substitutionElements = canvas.getAllByText('Substitution');
112
112
  await expect(substitutionElements.length).toBe(2);
113
113
  });
114
114
  },
@@ -1,7 +1,7 @@
1
1
  import { type Meta, type StoryObj } from '@storybook/preact';
2
2
  import { expect, userEvent, waitFor, within } from '@storybook/test';
3
3
 
4
- import { Table } from './table';
4
+ import { Table, type TableProps } from './table';
5
5
 
6
6
  const meta: Meta = {
7
7
  title: 'Component/Table',
@@ -16,7 +16,7 @@ const meta: Meta = {
16
16
 
17
17
  export default meta;
18
18
 
19
- export const TableStory: StoryObj = {
19
+ export const TableStory: StoryObj<TableProps> = {
20
20
  render: (args) => {
21
21
  return <Table data={args.data} columns={args.columns} pageSize={args.pageSize} />;
22
22
  },
@@ -49,7 +49,7 @@ export const TableStory: StoryObj = {
49
49
  },
50
50
  };
51
51
 
52
- export const TableStoryNoPagination: StoryObj = {
52
+ export const TableStoryNoPagination: StoryObj<TableProps> = {
53
53
  render: (args) => {
54
54
  return <Table data={args.data} columns={args.columns} pageSize={args.pageSize} />;
55
55
  },
@@ -22,7 +22,7 @@ export const tableStyle = {
22
22
  },
23
23
  };
24
24
 
25
- interface TableProps {
25
+ export interface TableProps {
26
26
  data: TData;
27
27
  columns: OneDArray<TColumn | string | ComponentChild>;
28
28
  pageSize: number | boolean;