@genspectrum/dashboard-components 0.14.1 → 0.15.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.
Files changed (74) hide show
  1. package/custom-elements.json +90 -58
  2. package/dist/{LineageFilterChangedEvent-C9dXOxt6.js → LineageFilterChangedEvent-COWV-Y0k.js} +6 -6
  3. package/dist/LineageFilterChangedEvent-COWV-Y0k.js.map +1 -0
  4. package/dist/assets/mutationOverTimeWorker-BL50C-yi.js.map +1 -0
  5. package/dist/components.d.ts +52 -56
  6. package/dist/components.js +79 -58
  7. package/dist/components.js.map +1 -1
  8. package/dist/util.d.ts +49 -49
  9. package/dist/util.js +2 -2
  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/aggregatedData/aggregate.stories.tsx +1 -1
  20. package/src/preact/components/csv-download-button.stories.tsx +2 -2
  21. package/src/preact/components/csv-download-button.tsx +1 -1
  22. package/src/preact/components/error-boundary.stories.tsx +5 -5
  23. package/src/preact/components/error-boundary.tsx +14 -3
  24. package/src/preact/components/error-display.stories.tsx +9 -9
  25. package/src/preact/components/fullscreen.tsx +3 -3
  26. package/src/preact/components/info.tsx +1 -1
  27. package/src/preact/components/mutation-type-selector.stories.tsx +1 -1
  28. package/src/preact/components/table.stories.tsx +3 -3
  29. package/src/preact/components/table.tsx +1 -1
  30. package/src/preact/{dateRangeSelector/date-range-selector.stories.tsx → dateRangeFilter/date-range-filter.stories.tsx} +18 -21
  31. package/src/preact/{dateRangeSelector/date-range-selector.tsx → dateRangeFilter/date-range-filter.tsx} +11 -11
  32. package/src/preact/{dateRangeSelector → dateRangeFilter}/dateRangeOption.ts +2 -2
  33. package/src/preact/lineageFilter/lineage-filter.stories.tsx +6 -6
  34. package/src/preact/locationFilter/fetchAutocompletionList.ts +1 -1
  35. package/src/preact/locationFilter/location-filter.stories.tsx +6 -6
  36. package/src/preact/map/sequences-by-location.stories.tsx +1 -1
  37. package/src/preact/mutationFilter/mutation-filter.stories.tsx +2 -2
  38. package/src/preact/mutations/getMutationsGridData.ts +1 -1
  39. package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +3 -3
  40. package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +1 -1
  41. package/src/preact/mutationsOverTime/mutations-over-time.tsx +1 -0
  42. package/src/preact/numberSequencesOverTime/number-sequences-over-time.stories.tsx +1 -1
  43. package/src/preact/prevalenceOverTime/prevalence-over-time-bubble-chart.tsx +4 -4
  44. package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +1 -1
  45. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.stories.tsx +1 -1
  46. package/src/preact/shared/floating-ui/hooks.ts +1 -1
  47. package/src/preact/{textInput/TextInputChangedEvent.ts → textFilter/TextFilterChangedEvent.ts} +2 -2
  48. package/src/preact/{textInput/text-input.stories.tsx → textFilter/text-filter.stories.tsx} +14 -14
  49. package/src/preact/{textInput/text-input.tsx → textFilter/text-filter.tsx} +10 -10
  50. package/src/utilEntrypoint.ts +2 -2
  51. package/src/utils/map2d.ts +1 -0
  52. package/src/web-components/gs-app.stories.ts +7 -7
  53. package/src/web-components/input/{gs-date-range-selector.stories.ts → gs-date-range-filter.stories.ts} +65 -20
  54. package/src/web-components/input/{gs-date-range-selector.tsx → gs-date-range-filter.tsx} +28 -13
  55. package/src/web-components/input/gs-lineage-filter.stories.ts +1 -1
  56. package/src/web-components/input/gs-location-filter.stories.ts +1 -1
  57. package/src/web-components/input/gs-mutation-filter.stories.ts +7 -7
  58. package/src/web-components/input/{gs-text-input.stories.ts → gs-text-filter.stories.ts} +18 -18
  59. package/src/web-components/input/{gs-text-input.tsx → gs-text-filter.tsx} +16 -16
  60. package/src/web-components/input/index.ts +2 -2
  61. package/src/web-components/visualization/gs-aggregate.tsx +2 -2
  62. package/standalone-bundle/assets/mutationOverTimeWorker-CFB5-Mdk.js.map +1 -0
  63. package/standalone-bundle/dashboard-components.js +2233 -2220
  64. package/standalone-bundle/dashboard-components.js.map +1 -1
  65. package/dist/LineageFilterChangedEvent-C9dXOxt6.js.map +0 -1
  66. package/dist/assets/mutationOverTimeWorker-Dxnxrfe0.js.map +0 -1
  67. package/standalone-bundle/assets/mutationOverTimeWorker-CmSrq4SZ.js.map +0 -1
  68. /package/src/preact/{dateRangeSelector → dateRangeFilter}/computeInitialValues.spec.ts +0 -0
  69. /package/src/preact/{dateRangeSelector → dateRangeFilter}/computeInitialValues.ts +0 -0
  70. /package/src/preact/{dateRangeSelector → dateRangeFilter}/dateConversion.ts +0 -0
  71. /package/src/preact/{dateRangeSelector → dateRangeFilter}/selectableOptions.ts +0 -0
  72. /package/src/preact/{textInput → textFilter}/__mockData__/aggregated_hosts.json +0 -0
  73. /package/src/preact/{textInput → textFilter}/fetchStringAutocompleteList.spec.ts +0 -0
  74. /package/src/preact/{textInput → textFilter}/fetchStringAutocompleteList.ts +0 -0
@@ -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;
@@ -4,7 +4,7 @@ import type { StepFunction } from '@storybook/types';
4
4
  import dayjs from 'dayjs/esm';
5
5
  import { useEffect, useRef, useState } from 'preact/hooks';
6
6
 
7
- import { DateRangeSelector, type DateRangeSelectorProps } from './date-range-selector';
7
+ import { DateRangeFilter, type DateRangeFilterProps } from './date-range-filter';
8
8
  import { previewHandles } from '../../../.storybook/preview';
9
9
  import { LAPIS_URL } from '../../constants';
10
10
  import { LapisUrlContextProvider } from '../LapisUrlContext';
@@ -19,9 +19,9 @@ const customDateRange = {
19
19
  dateTo: '2021-12-31',
20
20
  };
21
21
 
22
- const meta: Meta<DateRangeSelectorProps> = {
23
- title: 'Input/DateRangeSelector',
24
- component: DateRangeSelector,
22
+ const meta: Meta<DateRangeFilterProps> = {
23
+ title: 'Input/DateRangeFilter',
24
+ component: DateRangeFilter,
25
25
  parameters: {
26
26
  actions: {
27
27
  handles: ['gs-date-range-filter-changed', 'gs-date-range-option-changed', ...previewHandles],
@@ -61,15 +61,15 @@ const meta: Meta<DateRangeSelectorProps> = {
61
61
 
62
62
  export default meta;
63
63
 
64
- const Primary: StoryObj<DateRangeSelectorProps> = {
64
+ const Primary: StoryObj<DateRangeFilterProps> = {
65
65
  render: (args) => (
66
66
  <LapisUrlContextProvider value={LAPIS_URL}>
67
- <DateRangeSelector {...args} />
67
+ <DateRangeFilter {...args} />
68
68
  </LapisUrlContextProvider>
69
69
  ),
70
70
  };
71
71
 
72
- export const SetCorrectInitialValues: StoryObj<DateRangeSelectorProps> = {
72
+ export const SetCorrectInitialValues: StoryObj<DateRangeFilterProps> = {
73
73
  ...Primary,
74
74
  args: {
75
75
  ...Primary.args,
@@ -88,7 +88,7 @@ export const SetCorrectInitialValues: StoryObj<DateRangeSelectorProps> = {
88
88
 
89
89
  const initialDateFrom = '2000-01-01';
90
90
 
91
- export const SetCorrectInitialDateFrom: StoryObj<DateRangeSelectorProps> = {
91
+ export const SetCorrectInitialDateFrom: StoryObj<DateRangeFilterProps> = {
92
92
  ...Primary,
93
93
  args: {
94
94
  ...Primary.args,
@@ -107,7 +107,7 @@ export const SetCorrectInitialDateFrom: StoryObj<DateRangeSelectorProps> = {
107
107
 
108
108
  const initialDateTo = '2000-01-01';
109
109
 
110
- export const SetCorrectInitialDateTo: StoryObj<DateRangeSelectorProps> = {
110
+ export const SetCorrectInitialDateTo: StoryObj<DateRangeFilterProps> = {
111
111
  ...Primary,
112
112
  args: {
113
113
  ...Primary.args,
@@ -124,7 +124,7 @@ export const SetCorrectInitialDateTo: StoryObj<DateRangeSelectorProps> = {
124
124
  },
125
125
  };
126
126
 
127
- export const ChangingDateSetsOptionToCustom: StoryObj<DateRangeSelectorProps> = {
127
+ export const ChangingDateSetsOptionToCustom: StoryObj<DateRangeFilterProps> = {
128
128
  ...Primary,
129
129
  args: {
130
130
  ...Primary.args,
@@ -167,7 +167,7 @@ export const ChangingDateSetsOptionToCustom: StoryObj<DateRangeSelectorProps> =
167
167
  },
168
168
  };
169
169
 
170
- export const ChangingTheValueProgrammatically: StoryObj<DateRangeSelectorProps> = {
170
+ export const ChangingTheValueProgrammatically: StoryObj<DateRangeFilterProps> = {
171
171
  ...Primary,
172
172
  render: (args) => {
173
173
  const StatefulWrapper = () => {
@@ -183,7 +183,7 @@ export const ChangingTheValueProgrammatically: StoryObj<DateRangeSelectorProps>
183
183
  return (
184
184
  <div ref={ref}>
185
185
  <LapisUrlContextProvider value={LAPIS_URL}>
186
- <DateRangeSelector {...args} value={value} />
186
+ <DateRangeFilter {...args} value={value} />
187
187
  </LapisUrlContextProvider>
188
188
  <button className='btn' onClick={() => setValue(customDateRange.label)}>
189
189
  Set to Custom
@@ -230,7 +230,7 @@ export const ChangingTheValueProgrammatically: StoryObj<DateRangeSelectorProps>
230
230
  },
231
231
  };
232
232
 
233
- export const ChangingDateOption: StoryObj<DateRangeSelectorProps> = {
233
+ export const ChangingDateOption: StoryObj<DateRangeFilterProps> = {
234
234
  ...Primary,
235
235
  play: async ({ canvasElement, step }) => {
236
236
  const { canvas, filterChangedListenerMock, optionChangedListenerMock } = await prepare(canvasElement, step);
@@ -263,7 +263,7 @@ export const ChangingDateOption: StoryObj<DateRangeSelectorProps> = {
263
263
  },
264
264
  };
265
265
 
266
- export const HandlesInvalidInitialDateFrom: StoryObj<DateRangeSelectorProps> = {
266
+ export const HandlesInvalidInitialDateFrom: StoryObj<DateRangeFilterProps> = {
267
267
  ...Primary,
268
268
  args: {
269
269
  ...Primary.args,
@@ -278,14 +278,14 @@ export const HandlesInvalidInitialDateFrom: StoryObj<DateRangeSelectorProps> = {
278
278
  },
279
279
  };
280
280
 
281
- export const WithNoDateColumn: StoryObj<DateRangeSelectorProps> = {
281
+ export const WithNoDateColumn: StoryObj<DateRangeFilterProps> = {
282
282
  ...Primary,
283
283
  args: {
284
284
  ...Primary.args,
285
285
  lapisDateField: '',
286
286
  },
287
287
  play: async ({ canvasElement, step }) => {
288
- step('expect error message', async () => {
288
+ await step('expect error message', async () => {
289
289
  await expectInvalidAttributesErrorMessage(canvasElement, 'String must contain at least 1 character(s)');
290
290
  });
291
291
  },
@@ -295,12 +295,9 @@ async function prepare(canvasElement: HTMLElement, step: StepFunction<PreactRend
295
295
  const canvas = within(canvasElement);
296
296
 
297
297
  const filterChangedListenerMock = fn();
298
- await step('Setup event listener mock', async () => {
299
- canvasElement.addEventListener('gs-date-range-filter-changed', filterChangedListenerMock);
300
- });
301
-
302
298
  const optionChangedListenerMock = fn();
303
- await step('Setup event listener mock', async () => {
299
+ await step('Setup event listener mock', () => {
300
+ canvasElement.addEventListener('gs-date-range-filter-changed', filterChangedListenerMock);
304
301
  canvasElement.addEventListener('gs-date-range-option-changed', optionChangedListenerMock);
305
302
  });
306
303
 
@@ -18,39 +18,39 @@ import type { ScaleType } from '../shared/charts/getYAxisScale';
18
18
 
19
19
  const customOption = 'Custom';
20
20
 
21
- const dateRangeSelectorInnerPropsSchema = z.object({
21
+ const dateRangeFilterInnerPropsSchema = z.object({
22
22
  dateRangeOptions: z.array(dateRangeOptionSchema),
23
23
  earliestDate: z.string().date(),
24
24
  value: dateRangeValueSchema.optional(),
25
25
  lapisDateField: z.string().min(1),
26
26
  });
27
27
 
28
- const dateRangeSelectorPropsSchema = dateRangeSelectorInnerPropsSchema.extend({
28
+ const dateRangeFilterPropsSchema = dateRangeFilterInnerPropsSchema.extend({
29
29
  width: z.string(),
30
30
  });
31
31
 
32
- export type DateRangeSelectorProps = z.infer<typeof dateRangeSelectorPropsSchema>;
33
- export type DateRangeSelectorInnerProps = z.infer<typeof dateRangeSelectorInnerPropsSchema>;
32
+ export type DateRangeFilterProps = z.infer<typeof dateRangeFilterPropsSchema>;
33
+ export type DateRangeFilterInnerProps = z.infer<typeof dateRangeFilterInnerPropsSchema>;
34
34
 
35
- export const DateRangeSelector = (props: DateRangeSelectorProps) => {
35
+ export const DateRangeFilter = (props: DateRangeFilterProps) => {
36
36
  const { width, ...innerProps } = props;
37
37
  const size = { width, height: '3rem' };
38
38
 
39
39
  return (
40
- <ErrorBoundary size={size} layout='horizontal' componentProps={props} schema={dateRangeSelectorPropsSchema}>
40
+ <ErrorBoundary size={size} layout='horizontal' componentProps={props} schema={dateRangeFilterPropsSchema}>
41
41
  <div style={{ width }}>
42
- <DateRangeSelectorInner {...innerProps} />
42
+ <DateRangeFilterInner {...innerProps} />
43
43
  </div>
44
44
  </ErrorBoundary>
45
45
  );
46
46
  };
47
47
 
48
- export const DateRangeSelectorInner = ({
48
+ export const DateRangeFilterInner = ({
49
49
  dateRangeOptions,
50
50
  earliestDate = '1900-01-01',
51
51
  value,
52
52
  lapisDateField,
53
- }: DateRangeSelectorInnerProps) => {
53
+ }: DateRangeFilterInnerProps) => {
54
54
  const initialValues = useMemo(
55
55
  () => computeInitialValues(value, earliestDate, dateRangeOptions),
56
56
  [value, earliestDate, dateRangeOptions],
@@ -148,7 +148,7 @@ export const DateRangeSelectorInner = ({
148
148
  fireFilterChangedEvent();
149
149
  fireOptionChangedEvent({
150
150
  dateFrom: dateFrom !== undefined ? toYYYYMMDD(dateFrom) : earliestDate,
151
- dateTo: toYYYYMMDD(dateTo || new Date())!,
151
+ dateTo: toYYYYMMDD(dateTo || new Date()),
152
152
  });
153
153
  };
154
154
 
@@ -167,7 +167,7 @@ export const DateRangeSelectorInner = ({
167
167
  fireFilterChangedEvent();
168
168
  fireOptionChangedEvent({
169
169
  dateFrom: dateFrom !== undefined ? toYYYYMMDD(dateFrom) : earliestDate,
170
- dateTo: toYYYYMMDD(dateTo || new Date())!,
170
+ dateTo: toYYYYMMDD(dateTo || new Date()),
171
171
  });
172
172
  };
173
173
 
@@ -3,7 +3,7 @@ import z from 'zod';
3
3
  import { toYYYYMMDD } from './dateConversion';
4
4
 
5
5
  /**
6
- * A date range option that can be used in the `gs-date-range-selector` component.
6
+ * A date range option that can be used in the `gs-date-range-filter` component.
7
7
  */
8
8
  export const dateRangeOptionSchema = z.object({
9
9
  /** The label of the date range option that will be shown to the user */
@@ -65,7 +65,7 @@ const lastYear = new Date(today);
65
65
  lastYear.setFullYear(today.getFullYear() - 1);
66
66
 
67
67
  /**
68
- * Presets for the `gs-date-range-selector` component that can be used as `dateRangeOptions`.
68
+ * Presets for the `gs-date-range-filter` component that can be used as `dateRangeOptions`.
69
69
  */
70
70
  export const dateRangeOptionPresets = {
71
71
  last2Weeks: {
@@ -85,7 +85,7 @@ export const Default: StoryObj<LineageFilterProps> = {
85
85
  play: async ({ canvasElement, step }) => {
86
86
  const { canvas, lineageChangedListenerMock } = await prepare(canvasElement, step);
87
87
 
88
- step('change lineage filter value fires event', async () => {
88
+ await step('change lineage filter value fires event', async () => {
89
89
  const input = await inputField(canvas);
90
90
  await userEvent.clear(input);
91
91
  await userEvent.type(input, 'B.1');
@@ -105,7 +105,7 @@ export const ClearSelection: StoryObj<LineageFilterProps> = {
105
105
  play: async ({ canvasElement, step }) => {
106
106
  const { canvas, lineageChangedListenerMock } = await prepare(canvasElement, step);
107
107
 
108
- step('clear selection fires event with empty filter', async () => {
108
+ await step('clear selection fires event with empty filter', async () => {
109
109
  const clearSelectionButton = await canvas.findByLabelText('clear selection');
110
110
  await userEvent.click(clearSelectionButton);
111
111
 
@@ -123,7 +123,7 @@ export const OnBlurInput: StoryObj<LineageFilterProps> = {
123
123
  play: async ({ canvasElement, step }) => {
124
124
  const { canvas, lineageChangedListenerMock } = await prepare(canvasElement, step);
125
125
 
126
- step('after cleared selection by hand and then blur fires event with empty filter', async () => {
126
+ await step('after cleared selection by hand and then blur fires event with empty filter', async () => {
127
127
  const input = await inputField(canvas);
128
128
  await userEvent.clear(input);
129
129
  await userEvent.click(canvas.getByLabelText('toggle menu'));
@@ -144,7 +144,7 @@ export const WithNoLapisField: StoryObj<LineageFilterProps> = {
144
144
  lapisField: '',
145
145
  },
146
146
  play: async ({ canvasElement, step }) => {
147
- step('expect error message', async () => {
147
+ await step('expect error message', async () => {
148
148
  await expectInvalidAttributesErrorMessage(canvasElement, 'String must contain at least 1 character(s)');
149
149
  });
150
150
  },
@@ -154,11 +154,11 @@ async function prepare(canvasElement: HTMLElement, step: StepFunction<PreactRend
154
154
  const canvas = within(canvasElement);
155
155
 
156
156
  const lineageChangedListenerMock = fn();
157
- step('Setup event listener mock', () => {
157
+ await step('Setup event listener mock', () => {
158
158
  canvasElement.addEventListener('gs-lineage-filter-changed', lineageChangedListenerMock);
159
159
  });
160
160
 
161
- step('location filter is rendered with value', async () => {
161
+ await step('location filter is rendered with value', async () => {
162
162
  await waitFor(async () => {
163
163
  return expect(await inputField(canvas)).toHaveValue('A.1');
164
164
  });
@@ -43,7 +43,7 @@ export async function fetchAutocompletionList({
43
43
 
44
44
  return [...locationValues]
45
45
  .map<EntryWithNullValues>(([json, count]) => ({
46
- value: JSON.parse(json),
46
+ value: JSON.parse(json) as Record<string, string | null>,
47
47
  count,
48
48
  }))
49
49
  .sort(compareLocationEntries(fields))
@@ -84,7 +84,7 @@ export const Primary: StoryObj<LocationFilterProps> = {
84
84
  play: async ({ canvasElement, step }) => {
85
85
  const { canvas, locationChangedListenerMock } = await prepare(canvasElement, step);
86
86
 
87
- step('change location filter value fires event', async () => {
87
+ await step('change location filter value fires event', async () => {
88
88
  const input = await inputField(canvas);
89
89
  await userEvent.clear(input);
90
90
  await userEvent.type(input, 'Germany');
@@ -107,7 +107,7 @@ export const ClearSelection: StoryObj<LocationFilterProps> = {
107
107
  play: async ({ canvasElement, step }) => {
108
108
  const { canvas, locationChangedListenerMock } = await prepare(canvasElement, step);
109
109
 
110
- step('clear selection fires event with empty filter', async () => {
110
+ await step('clear selection fires event with empty filter', async () => {
111
111
  const clearSelectionButton = await canvas.findByLabelText('clear selection');
112
112
  await userEvent.click(clearSelectionButton);
113
113
 
@@ -128,7 +128,7 @@ export const OnBlurInput: StoryObj<LocationFilterProps> = {
128
128
  play: async ({ canvasElement, step }) => {
129
129
  const { canvas, locationChangedListenerMock } = await prepare(canvasElement, step);
130
130
 
131
- step('after cleared selection by hand and then blur fires event with empty filter', async () => {
131
+ await step('after cleared selection by hand and then blur fires event with empty filter', async () => {
132
132
  const input = await inputField(canvas);
133
133
  await userEvent.clear(input);
134
134
  await userEvent.click(canvas.getByLabelText('toggle menu'));
@@ -151,11 +151,11 @@ async function prepare(canvasElement: HTMLElement, step: StepFunction<PreactRend
151
151
  const canvas = within(canvasElement);
152
152
 
153
153
  const locationChangedListenerMock = fn();
154
- step('Setup event listener mock', () => {
154
+ await step('Setup event listener mock', () => {
155
155
  canvasElement.addEventListener('gs-location-changed', locationChangedListenerMock);
156
156
  });
157
157
 
158
- step('location filter is rendered with value', async () => {
158
+ await step('location filter is rendered with value', async () => {
159
159
  await waitFor(async () => {
160
160
  return expect(await inputField(canvas)).toHaveValue('Europe');
161
161
  });
@@ -171,7 +171,7 @@ export const WithNoFields: StoryObj<LocationFilterProps> = {
171
171
  fields: [],
172
172
  },
173
173
  play: async ({ canvasElement, step }) => {
174
- step('expect error message', async () => {
174
+ await step('expect error message', async () => {
175
175
  await expectInvalidAttributesErrorMessage(canvasElement, 'Array must contain at least 1 element(s)');
176
176
  });
177
177
  },
@@ -134,7 +134,7 @@ export const InvalidProps: StoryObj<SequencesByLocationProps> = {
134
134
  lapisLocationField: '',
135
135
  },
136
136
  play: async ({ canvasElement, step }) => {
137
- step('expect error message', async () => {
137
+ await step('expect error message', async () => {
138
138
  await expectInvalidAttributesErrorMessage(
139
139
  canvasElement,
140
140
  '"lapisLocationField": String must contain at least 1 character(s)',
@@ -223,7 +223,7 @@ async function prepare(canvasElement: HTMLElement, step: StepFunction<PreactRend
223
223
  const canvas = within(canvasElement);
224
224
 
225
225
  const changedListenerMock = fn();
226
- await step('Setup event listener mock', async () => {
226
+ await step('Setup event listener mock', () => {
227
227
  canvasElement.addEventListener('gs-mutation-filter-changed', changedListenerMock);
228
228
  });
229
229
 
@@ -265,5 +265,5 @@ const testNoOptionsExist = async (canvas: ReturnType<typeof within>, mutation: s
265
265
  await expect(options).toHaveLength(0);
266
266
  };
267
267
 
268
- const inputField = (canvas: ReturnType<typeof within>) =>
268
+ const inputField = (canvas: ReturnType<typeof within>): HTMLElement =>
269
269
  canvas.getByPlaceholderText('Enter a mutation', { exact: false });
@@ -25,7 +25,7 @@ const accumulateByPosition = (data: SubstitutionOrDeletionEntry[], sequenceType:
25
25
 
26
26
  const initiallyFillPositionsToProportionAtBase = () => {
27
27
  if (!positionsToProportionAtBase.has(position)) {
28
- const empty = new Map();
28
+ const empty = new Map<string | undefined, number>();
29
29
  basesOfView.forEach((base) => empty.set(base, 0));
30
30
  empty.set(mutationEntry.mutation.valueAtReference, 1);
31
31
  positionsToProportionAtBase.set(position, empty);
@@ -62,9 +62,9 @@ const MutationsOverTimeGrid: FunctionComponent<MutationsOverTimeGridProps> = ({
62
62
  ))}
63
63
  {shownMutations.map((mutation, rowIndex) => {
64
64
  return (
65
- <Fragment key={`fragment-${mutation.toString()}`}>
65
+ <Fragment key={`fragment-${mutation.code}`}>
66
66
  <div
67
- key={`mutation-${mutation.toString()}`}
67
+ key={`mutation-${mutation.code}`}
68
68
  style={{ gridRowStart: rowIndex + 2, gridColumnStart: 1 }}
69
69
  >
70
70
  <MutationCell mutation={mutation} />
@@ -80,7 +80,7 @@ const MutationsOverTimeGrid: FunctionComponent<MutationsOverTimeGridProps> = ({
80
80
  return (
81
81
  <div
82
82
  style={{ gridRowStart: rowIndex + 2, gridColumnStart: columnIndex + 2 }}
83
- key={`${mutation.toString()}-${date.toString()}`}
83
+ key={`${mutation.code}-${date.dateString}`}
84
84
  >
85
85
  <ProportionCell
86
86
  value={value}
@@ -164,7 +164,7 @@ export const WithNoLapisDateFieldField: StoryObj<MutationsOverTimeProps> = {
164
164
  lapisDateField: '',
165
165
  },
166
166
  play: async ({ canvasElement, step }) => {
167
- step('expect error message', async () => {
167
+ await step('expect error message', async () => {
168
168
  await expectInvalidAttributesErrorMessage(canvasElement, 'String must contain at least 1 character(s)');
169
169
  });
170
170
  },
@@ -78,6 +78,7 @@ export const MutationsOverTimeInner: FunctionComponent<MutationsOverTimeProps> =
78
78
 
79
79
  const { data, error, isLoading } = useWebWorker<MutationOverTimeQuery, MutationOverTimeWorkerResponse>(
80
80
  messageToWorker,
81
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
81
82
  MutationOverTimeWorker,
82
83
  );
83
84
 
@@ -129,7 +129,7 @@ export const WithNoLapisDateField: StoryObj<NumberSequencesOverTimeProps> = {
129
129
  lapisDateField: '',
130
130
  },
131
131
  play: async ({ canvasElement, step }) => {
132
- step('expect error message', async () => {
132
+ await step('expect error message', async () => {
133
133
  await expectInvalidAttributesErrorMessage(canvasElement, 'String must contain at least 1 character(s)');
134
134
  });
135
135
  },
@@ -87,13 +87,13 @@ const PrevalenceOverTimeBubbleChart = ({
87
87
  intersect: false,
88
88
  callbacks: {
89
89
  title: (context) => {
90
- const dataset = nonNullDateRangeData[context[0].datasetIndex!];
91
- const dataPoint = dataset.content[context[0].dataIndex!];
90
+ const dataset = nonNullDateRangeData[context[0].datasetIndex];
91
+ const dataPoint = dataset.content[context[0].dataIndex];
92
92
  return dataPoint.dateRange?.toString();
93
93
  },
94
94
  label: (context) => {
95
- const dataset = nonNullDateRangeData[context.datasetIndex!];
96
- const dataPoint = dataset.content[context.dataIndex!];
95
+ const dataset = nonNullDateRangeData[context.datasetIndex];
96
+ const dataPoint = dataset.content[context.dataIndex];
97
97
 
98
98
  const percentage = (dataPoint.prevalence * 100).toFixed(2);
99
99
  const count = dataPoint.count.toFixed(0);
@@ -254,7 +254,7 @@ export const WithNoLapisDateField: StoryObj<PrevalenceOverTimeProps> = {
254
254
  lapisDateField: '',
255
255
  },
256
256
  play: async ({ canvasElement, step }) => {
257
- step('expect error message', async () => {
257
+ await step('expect error message', async () => {
258
258
  await expectInvalidAttributesErrorMessage(canvasElement, 'String must contain at least 1 character(s)');
259
259
  });
260
260
  },
@@ -188,7 +188,7 @@ export const WithNoLapisDateField: StoryObj<RelativeGrowthAdvantageProps> = {
188
188
  lapisDateField: '',
189
189
  },
190
190
  play: async ({ canvasElement, step }) => {
191
- step('expect error message', async () => {
191
+ await step('expect error message', async () => {
192
192
  await expectInvalidAttributesErrorMessage(canvasElement, 'String must contain at least 1 character(s)');
193
193
  });
194
194
  },
@@ -20,7 +20,7 @@ export function useFloatingUi(
20
20
  const { current: floating } = floatingRef;
21
21
 
22
22
  const update = () => {
23
- computePosition(reference, floating, {
23
+ void computePosition(reference, floating, {
24
24
  placement,
25
25
  middleware,
26
26
  }).then(({ x, y }) => {
@@ -1,8 +1,8 @@
1
1
  type LapisTextFilter = Record<string, string | undefined>;
2
2
 
3
- export class TextInputChangedEvent extends CustomEvent<LapisTextFilter> {
3
+ export class TextFilterChangedEvent extends CustomEvent<LapisTextFilter> {
4
4
  constructor(detail: LapisTextFilter) {
5
- super('gs-text-input-changed', {
5
+ super('gs-text-filter-changed', {
6
6
  detail,
7
7
  bubbles: true,
8
8
  composed: true,
@@ -2,18 +2,18 @@ import { type Meta, type StoryObj } from '@storybook/preact';
2
2
  import { expect, fireEvent, fn, waitFor, within } from '@storybook/test';
3
3
 
4
4
  import data from './__mockData__/aggregated_hosts.json';
5
- import { TextInput, type TextInputProps } from './text-input';
5
+ import { TextFilter, type TextFilterProps } from './text-filter';
6
6
  import { previewHandles } from '../../../.storybook/preview';
7
7
  import { AGGREGATED_ENDPOINT, LAPIS_URL } from '../../constants';
8
8
  import { LapisUrlContextProvider } from '../LapisUrlContext';
9
9
  import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
10
10
 
11
- const meta: Meta<TextInputProps> = {
12
- title: 'Input/TextInput',
13
- component: TextInput,
11
+ const meta: Meta<TextFilterProps> = {
12
+ title: 'Input/TextFilter',
13
+ component: TextFilter,
14
14
  parameters: {
15
15
  actions: {
16
- handles: ['gs-text-input-changed', ...previewHandles],
16
+ handles: ['gs-text-filter-changed', ...previewHandles],
17
17
  },
18
18
  fetchMock: {
19
19
  mocks: [
@@ -65,10 +65,10 @@ const meta: Meta<TextInputProps> = {
65
65
 
66
66
  export default meta;
67
67
 
68
- export const Default: StoryObj<TextInputProps> = {
68
+ export const Default: StoryObj<TextFilterProps> = {
69
69
  render: (args) => (
70
70
  <LapisUrlContextProvider value={LAPIS_URL}>
71
- <TextInput {...args} />
71
+ <TextFilter {...args} />
72
72
  </LapisUrlContextProvider>
73
73
  ),
74
74
  args: {
@@ -82,7 +82,7 @@ export const Default: StoryObj<TextInputProps> = {
82
82
  },
83
83
  };
84
84
 
85
- export const RemoveInitialValue: StoryObj<TextInputProps> = {
85
+ export const RemoveInitialValue: StoryObj<TextFilterProps> = {
86
86
  ...Default,
87
87
  args: {
88
88
  ...Default.args,
@@ -92,13 +92,13 @@ export const RemoveInitialValue: StoryObj<TextInputProps> = {
92
92
  const canvas = within(canvasElement);
93
93
 
94
94
  const changedListenerMock = fn();
95
- await step('Setup event listener mock', async () => {
96
- canvasElement.addEventListener('gs-text-input-changed', changedListenerMock);
95
+ await step('Setup event listener mock', () => {
96
+ canvasElement.addEventListener('gs-text-filter-changed', changedListenerMock);
97
97
  });
98
98
 
99
- await waitFor(() => {
99
+ await waitFor(async () => {
100
100
  const input = canvas.getByPlaceholderText('Enter a host name', { exact: false });
101
- expect(input).toHaveValue('Homo sapiens');
101
+ await expect(input).toHaveValue('Homo sapiens');
102
102
  });
103
103
 
104
104
  await step('Remove initial value', async () => {
@@ -115,14 +115,14 @@ export const RemoveInitialValue: StoryObj<TextInputProps> = {
115
115
  },
116
116
  };
117
117
 
118
- export const WithNoLapisField: StoryObj<TextInputProps> = {
118
+ export const WithNoLapisField: StoryObj<TextFilterProps> = {
119
119
  ...Default,
120
120
  args: {
121
121
  ...Default.args,
122
122
  lapisField: '',
123
123
  },
124
124
  play: async ({ canvasElement, step }) => {
125
- step('expect error message', async () => {
125
+ await step('expect error message', async () => {
126
126
  await expectInvalidAttributesErrorMessage(canvasElement, 'String must contain at least 1 character(s)');
127
127
  });
128
128
  },