@genspectrum/dashboard-components 0.12.1 → 0.13.1
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 +292 -25
- package/dist/{LocationChangedEvent-CORvQvXv.js → LineageFilterChangedEvent-GedKNGFI.js} +25 -3
- package/dist/LineageFilterChangedEvent-GedKNGFI.js.map +1 -0
- package/dist/assets/mutationOverTimeWorker-B1-WrM4b.js.map +1 -0
- package/dist/components.d.ts +124 -25
- package/dist/components.js +765 -572
- package/dist/components.js.map +1 -1
- package/dist/style.css +3 -0
- package/dist/util.d.ts +48 -18
- package/dist/util.js +3 -1
- package/package.json +2 -2
- package/src/constants.ts +6 -0
- package/src/lapisApi/__mockData__/wiseReferenceGenome.json +9 -0
- package/src/lapisApi/lapisApi.ts +17 -0
- package/src/lapisApi/lapisTypes.ts +7 -1
- package/src/operator/FetchDetailsOperator.ts +28 -0
- package/src/preact/components/downshift-combobox.tsx +145 -0
- package/src/preact/components/tabs.tsx +1 -1
- package/src/preact/lineageFilter/LineageFilterChangedEvent.ts +11 -0
- package/src/preact/lineageFilter/fetchLineageAutocompleteList.spec.ts +16 -2
- package/src/preact/lineageFilter/fetchLineageAutocompleteList.ts +13 -2
- package/src/preact/lineageFilter/lineage-filter.stories.tsx +110 -9
- package/src/preact/lineageFilter/lineage-filter.tsx +40 -50
- package/src/preact/locationFilter/LocationChangedEvent.ts +1 -1
- package/src/preact/locationFilter/fetchAutocompletionList.spec.ts +6 -2
- package/src/preact/locationFilter/fetchAutocompletionList.ts +16 -6
- package/src/preact/locationFilter/location-filter.stories.tsx +33 -30
- package/src/preact/locationFilter/location-filter.tsx +47 -144
- package/src/preact/mutationsOverTime/MutationOverTimeData.ts +9 -5
- package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +5 -3
- package/src/preact/shared/sort/sortSubstitutionsAndDeletions.ts +4 -7
- package/src/preact/textInput/TextInputChangedEvent.ts +1 -1
- package/src/preact/textInput/fetchStringAutocompleteList.ts +20 -0
- package/src/preact/textInput/text-input.stories.tsx +14 -11
- package/src/preact/textInput/text-input.tsx +39 -140
- package/src/preact/wastewater/mutationsOverTime/__mockData__/details.json +88 -0
- package/src/preact/wastewater/mutationsOverTime/computeWastewaterMutationsOverTimeDataPerLocation.spec.ts +159 -0
- package/src/preact/wastewater/mutationsOverTime/computeWastewaterMutationsOverTimeDataPerLocation.ts +51 -0
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.stories.tsx +71 -0
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.tsx +151 -0
- package/src/query/queryMutationsOverTime.ts +6 -14
- package/src/query/queryWastewaterMutationsOverTime.spec.ts +94 -0
- package/src/query/queryWastewaterMutationsOverTime.ts +55 -0
- package/src/types.ts +3 -0
- package/src/utilEntrypoint.ts +2 -0
- package/src/utils/map2d.ts +39 -0
- package/src/web-components/index.ts +1 -0
- package/src/web-components/input/gs-lineage-filter.stories.ts +120 -31
- package/src/web-components/input/gs-lineage-filter.tsx +24 -8
- package/src/web-components/input/gs-location-filter.stories.ts +9 -0
- package/src/web-components/input/gs-location-filter.tsx +21 -3
- package/src/web-components/input/gs-text-input.stories.ts +14 -5
- package/src/web-components/input/gs-text-input.tsx +23 -7
- package/src/web-components/wastewaterVisualization/gs-wastewater-mutations-over-time.stories.ts +82 -0
- package/src/web-components/wastewaterVisualization/gs-wastewater-mutations-over-time.tsx +112 -0
- package/src/web-components/wastewaterVisualization/index.ts +1 -0
- package/standalone-bundle/assets/{mutationOverTimeWorker-DEybsZ5r.js.map → mutationOverTimeWorker-Cls1J0cl.js.map} +1 -1
- package/standalone-bundle/dashboard-components.js +6972 -6796
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/standalone-bundle/style.css +1 -1
- package/dist/LocationChangedEvent-CORvQvXv.js.map +0 -1
- package/dist/assets/mutationOverTimeWorker-DTv93Ere.js.map +0 -1
- package/src/preact/textInput/fetchAutocompleteList.ts +0 -9
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { type Meta, type StoryObj } from '@storybook/preact';
|
|
1
|
+
import { type Meta, type PreactRenderer, type StoryObj } from '@storybook/preact';
|
|
2
|
+
import { expect, fn, userEvent, waitFor, within } from '@storybook/test';
|
|
3
|
+
import type { StepFunction } from '@storybook/types';
|
|
2
4
|
|
|
3
5
|
import { LineageFilter, type LineageFilterProps } from './lineage-filter';
|
|
4
6
|
import { previewHandles } from '../../../.storybook/preview';
|
|
@@ -22,6 +24,7 @@ const meta: Meta = {
|
|
|
22
24
|
url: AGGREGATED_ENDPOINT,
|
|
23
25
|
body: {
|
|
24
26
|
fields: ['pangoLineage'],
|
|
27
|
+
country: 'Germany',
|
|
25
28
|
},
|
|
26
29
|
},
|
|
27
30
|
response: {
|
|
@@ -32,10 +35,41 @@ const meta: Meta = {
|
|
|
32
35
|
],
|
|
33
36
|
},
|
|
34
37
|
},
|
|
38
|
+
argTypes: {
|
|
39
|
+
lapisField: {
|
|
40
|
+
control: {
|
|
41
|
+
type: 'text',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
placeholderText: {
|
|
45
|
+
control: {
|
|
46
|
+
type: 'text',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
value: {
|
|
50
|
+
control: {
|
|
51
|
+
type: 'text',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
width: {
|
|
55
|
+
control: {
|
|
56
|
+
type: 'text',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
lapisFilter: {
|
|
60
|
+
control: {
|
|
61
|
+
type: 'object',
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
|
|
35
66
|
args: {
|
|
36
67
|
lapisField: 'pangoLineage',
|
|
37
|
-
|
|
38
|
-
|
|
68
|
+
lapisFilter: {
|
|
69
|
+
country: 'Germany',
|
|
70
|
+
},
|
|
71
|
+
placeholderText: 'Enter a lineage',
|
|
72
|
+
value: 'A.1',
|
|
39
73
|
width: '100%',
|
|
40
74
|
},
|
|
41
75
|
};
|
|
@@ -45,14 +79,62 @@ export default meta;
|
|
|
45
79
|
export const Default: StoryObj<LineageFilterProps> = {
|
|
46
80
|
render: (args) => (
|
|
47
81
|
<LapisUrlContext.Provider value={LAPIS_URL}>
|
|
48
|
-
<LineageFilter
|
|
49
|
-
lapisField={args.lapisField}
|
|
50
|
-
placeholderText={args.placeholderText}
|
|
51
|
-
initialValue={args.initialValue}
|
|
52
|
-
width={args.width}
|
|
53
|
-
/>
|
|
82
|
+
<LineageFilter {...args} />
|
|
54
83
|
</LapisUrlContext.Provider>
|
|
55
84
|
),
|
|
85
|
+
play: async ({ canvasElement, step }) => {
|
|
86
|
+
const { canvas, lineageChangedListenerMock } = await prepare(canvasElement, step);
|
|
87
|
+
|
|
88
|
+
step('change lineage filter value fires event', async () => {
|
|
89
|
+
const input = await inputField(canvas);
|
|
90
|
+
await userEvent.clear(input);
|
|
91
|
+
await userEvent.type(input, 'B.1');
|
|
92
|
+
await userEvent.click(canvas.getByRole('option', { name: 'B.1' }));
|
|
93
|
+
|
|
94
|
+
await waitFor(() => {
|
|
95
|
+
return expect(lineageChangedListenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({
|
|
96
|
+
pangoLineage: 'B.1',
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const ClearSelection: StoryObj<LineageFilterProps> = {
|
|
104
|
+
...Default,
|
|
105
|
+
play: async ({ canvasElement, step }) => {
|
|
106
|
+
const { canvas, lineageChangedListenerMock } = await prepare(canvasElement, step);
|
|
107
|
+
|
|
108
|
+
step('clear selection fires event with empty filter', async () => {
|
|
109
|
+
const clearSelectionButton = await canvas.findByLabelText('clear selection');
|
|
110
|
+
await userEvent.click(clearSelectionButton);
|
|
111
|
+
|
|
112
|
+
await waitFor(() => {
|
|
113
|
+
return expect(lineageChangedListenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({
|
|
114
|
+
pangoLineage: undefined,
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const OnBlurInput: StoryObj<LineageFilterProps> = {
|
|
122
|
+
...Default,
|
|
123
|
+
play: async ({ canvasElement, step }) => {
|
|
124
|
+
const { canvas, lineageChangedListenerMock } = await prepare(canvasElement, step);
|
|
125
|
+
|
|
126
|
+
step('after cleared selection by hand and then blur fires event with empty filter', async () => {
|
|
127
|
+
const input = await inputField(canvas);
|
|
128
|
+
await userEvent.clear(input);
|
|
129
|
+
await userEvent.click(canvas.getByLabelText('toggle menu'));
|
|
130
|
+
|
|
131
|
+
await waitFor(() => {
|
|
132
|
+
return expect(lineageChangedListenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({
|
|
133
|
+
pangoLineage: undefined,
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
},
|
|
56
138
|
};
|
|
57
139
|
|
|
58
140
|
export const WithNoLapisField: StoryObj<LineageFilterProps> = {
|
|
@@ -67,3 +149,22 @@ export const WithNoLapisField: StoryObj<LineageFilterProps> = {
|
|
|
67
149
|
});
|
|
68
150
|
},
|
|
69
151
|
};
|
|
152
|
+
|
|
153
|
+
async function prepare(canvasElement: HTMLElement, step: StepFunction<PreactRenderer, unknown>) {
|
|
154
|
+
const canvas = within(canvasElement);
|
|
155
|
+
|
|
156
|
+
const lineageChangedListenerMock = fn();
|
|
157
|
+
step('Setup event listener mock', () => {
|
|
158
|
+
canvasElement.addEventListener('gs-lineage-filter-changed', lineageChangedListenerMock);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
step('location filter is rendered with value', async () => {
|
|
162
|
+
await waitFor(async () => {
|
|
163
|
+
return expect(await inputField(canvas)).toHaveValue('A.1');
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
return { canvas, lineageChangedListenerMock };
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const inputField = (canvas: ReturnType<typeof within>) => canvas.findByPlaceholderText('Enter a lineage');
|
|
@@ -1,27 +1,32 @@
|
|
|
1
1
|
import { type FunctionComponent } from 'preact';
|
|
2
|
-
import { useContext
|
|
2
|
+
import { useContext } from 'preact/hooks';
|
|
3
3
|
import z from 'zod';
|
|
4
4
|
|
|
5
5
|
import { fetchLineageAutocompleteList } from './fetchLineageAutocompleteList';
|
|
6
6
|
import { LapisUrlContext } from '../LapisUrlContext';
|
|
7
|
+
import { LineageFilterChangedEvent } from './LineageFilterChangedEvent';
|
|
8
|
+
import { lapisFilterSchema } from '../../types';
|
|
9
|
+
import { DownshiftCombobox } from '../components/downshift-combobox';
|
|
7
10
|
import { ErrorBoundary } from '../components/error-boundary';
|
|
8
11
|
import { LoadingDisplay } from '../components/loading-display';
|
|
9
|
-
import { NoDataDisplay } from '../components/no-data-display';
|
|
10
12
|
import { ResizeContainer } from '../components/resize-container';
|
|
11
13
|
import { useQuery } from '../useQuery';
|
|
12
14
|
|
|
13
|
-
const
|
|
15
|
+
const lineageSelectorPropsSchema = z.object({
|
|
14
16
|
lapisField: z.string().min(1),
|
|
15
17
|
placeholderText: z.string().optional(),
|
|
16
|
-
|
|
18
|
+
value: z.string(),
|
|
19
|
+
});
|
|
20
|
+
const lineageFilterInnerPropsSchema = lineageSelectorPropsSchema.extend({
|
|
21
|
+
lapisFilter: lapisFilterSchema,
|
|
17
22
|
});
|
|
18
|
-
|
|
19
23
|
const lineageFilterPropsSchema = lineageFilterInnerPropsSchema.extend({
|
|
20
24
|
width: z.string(),
|
|
21
25
|
});
|
|
22
26
|
|
|
23
27
|
export type LineageFilterInnerProps = z.infer<typeof lineageFilterInnerPropsSchema>;
|
|
24
28
|
export type LineageFilterProps = z.infer<typeof lineageFilterPropsSchema>;
|
|
29
|
+
type LineageSelectorProps = z.infer<typeof lineageSelectorPropsSchema>;
|
|
25
30
|
|
|
26
31
|
export const LineageFilter: FunctionComponent<LineageFilterProps> = (props) => {
|
|
27
32
|
const { width, ...innerProps } = props;
|
|
@@ -39,15 +44,14 @@ export const LineageFilter: FunctionComponent<LineageFilterProps> = (props) => {
|
|
|
39
44
|
const LineageFilterInner: FunctionComponent<LineageFilterInnerProps> = ({
|
|
40
45
|
lapisField,
|
|
41
46
|
placeholderText,
|
|
42
|
-
|
|
47
|
+
value,
|
|
48
|
+
lapisFilter,
|
|
43
49
|
}) => {
|
|
44
50
|
const lapis = useContext(LapisUrlContext);
|
|
45
51
|
|
|
46
|
-
const inputRef = useRef<HTMLInputElement>(null);
|
|
47
|
-
|
|
48
52
|
const { data, error, isLoading } = useQuery(
|
|
49
|
-
() => fetchLineageAutocompleteList(lapis, lapisField),
|
|
50
|
-
[lapisField, lapis],
|
|
53
|
+
() => fetchLineageAutocompleteList({ lapis, field: lapisField, lapisFilter }),
|
|
54
|
+
[lapisField, lapis, lapisFilter],
|
|
51
55
|
);
|
|
52
56
|
|
|
53
57
|
if (isLoading) {
|
|
@@ -58,47 +62,33 @@ const LineageFilterInner: FunctionComponent<LineageFilterInnerProps> = ({
|
|
|
58
62
|
throw error;
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const onInput = () => {
|
|
66
|
-
const value = inputRef.current?.value === '' ? undefined : inputRef.current?.value;
|
|
67
|
-
|
|
68
|
-
if (isValidValue(value)) {
|
|
69
|
-
inputRef.current?.dispatchEvent(
|
|
70
|
-
new CustomEvent('gs-lineage-filter-changed', {
|
|
71
|
-
detail: { [lapisField]: value },
|
|
72
|
-
bubbles: true,
|
|
73
|
-
composed: true,
|
|
74
|
-
}),
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const isValidValue = (value: string | undefined) => {
|
|
80
|
-
if (value === undefined) {
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
return data.includes(value);
|
|
84
|
-
};
|
|
65
|
+
return <LineageSelector lapisField={lapisField} value={value} placeholderText={placeholderText} data={data} />;
|
|
66
|
+
};
|
|
85
67
|
|
|
68
|
+
const LineageSelector = ({
|
|
69
|
+
lapisField,
|
|
70
|
+
value,
|
|
71
|
+
placeholderText,
|
|
72
|
+
data,
|
|
73
|
+
}: LineageSelectorProps & {
|
|
74
|
+
data: string[];
|
|
75
|
+
}) => {
|
|
86
76
|
return (
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
/>
|
|
97
|
-
<datalist id={lapisField}>
|
|
98
|
-
{data.map((item) => (
|
|
99
|
-
<option value={item} key={item} />
|
|
100
|
-
))}
|
|
101
|
-
</datalist>
|
|
102
|
-
</>
|
|
77
|
+
<DownshiftCombobox
|
|
78
|
+
allItems={data}
|
|
79
|
+
value={value}
|
|
80
|
+
filterItemsByInputValue={filterByInputValue}
|
|
81
|
+
createEvent={(item: string | null) => new LineageFilterChangedEvent({ [lapisField]: item ?? undefined })}
|
|
82
|
+
itemToString={(item: string | undefined | null) => item ?? ''}
|
|
83
|
+
placeholderText={placeholderText}
|
|
84
|
+
formatItemInList={(item: string) => item}
|
|
85
|
+
/>
|
|
103
86
|
);
|
|
104
87
|
};
|
|
88
|
+
|
|
89
|
+
function filterByInputValue(item: string, inputValue: string | undefined | null) {
|
|
90
|
+
if (inputValue === undefined || inputValue === null || inputValue === '') {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
return item?.toLowerCase().includes(inputValue?.toLowerCase() || '');
|
|
94
|
+
}
|
|
@@ -8,7 +8,7 @@ describe('fetchAutocompletionList', () => {
|
|
|
8
8
|
const fields = ['region', 'country', 'division'];
|
|
9
9
|
|
|
10
10
|
lapisRequestMocks.aggregated(
|
|
11
|
-
{ fields },
|
|
11
|
+
{ fields, country: 'Germany' },
|
|
12
12
|
{
|
|
13
13
|
data: [
|
|
14
14
|
{ count: 0, region: 'region1', country: 'country1_1', division: 'division1_1_1' },
|
|
@@ -20,7 +20,11 @@ describe('fetchAutocompletionList', () => {
|
|
|
20
20
|
},
|
|
21
21
|
);
|
|
22
22
|
|
|
23
|
-
const result = await fetchAutocompletionList(
|
|
23
|
+
const result = await fetchAutocompletionList({
|
|
24
|
+
fields,
|
|
25
|
+
lapis: DUMMY_LAPIS_URL,
|
|
26
|
+
lapisFilter: { country: 'Germany' },
|
|
27
|
+
});
|
|
24
28
|
|
|
25
29
|
expect(result).to.deep.equal([
|
|
26
30
|
{ region: 'region1', country: undefined, division: undefined },
|
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
import { FetchAggregatedOperator } from '../../operator/FetchAggregatedOperator';
|
|
2
|
+
import type { LapisFilter } from '../../types';
|
|
2
3
|
|
|
3
|
-
export async function fetchAutocompletionList(
|
|
4
|
-
fields
|
|
5
|
-
lapis
|
|
6
|
-
signal
|
|
7
|
-
|
|
4
|
+
export async function fetchAutocompletionList({
|
|
5
|
+
fields,
|
|
6
|
+
lapis,
|
|
7
|
+
signal,
|
|
8
|
+
lapisFilter,
|
|
9
|
+
}: {
|
|
10
|
+
fields: string[];
|
|
11
|
+
lapis: string;
|
|
12
|
+
lapisFilter?: LapisFilter;
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
}): Promise<Record<string, string | undefined>[]> {
|
|
8
15
|
const toAncestorInHierarchyOverwriteValues = Array(fields.length - 1)
|
|
9
16
|
.fill(0)
|
|
10
17
|
.map((_, i) => i + 1)
|
|
11
18
|
.map((i) => fields.slice(i).reduce((acc, field) => ({ ...acc, [field]: null }), {}));
|
|
12
19
|
|
|
13
|
-
const fetchAggregatedOperator = new FetchAggregatedOperator<Record<string, string | null>>(
|
|
20
|
+
const fetchAggregatedOperator = new FetchAggregatedOperator<Record<string, string | null>>(
|
|
21
|
+
lapisFilter ?? {},
|
|
22
|
+
fields,
|
|
23
|
+
);
|
|
14
24
|
|
|
15
25
|
const data = (await fetchAggregatedOperator.evaluate(lapis, signal)).content;
|
|
16
26
|
|
|
@@ -21,6 +21,7 @@ const meta: Meta<LocationFilterProps> = {
|
|
|
21
21
|
url: AGGREGATED_ENDPOINT,
|
|
22
22
|
body: {
|
|
23
23
|
fields: ['region', 'country', 'division', 'location'],
|
|
24
|
+
age: 18,
|
|
24
25
|
},
|
|
25
26
|
},
|
|
26
27
|
response: {
|
|
@@ -39,6 +40,9 @@ const meta: Meta<LocationFilterProps> = {
|
|
|
39
40
|
fields: ['region', 'country', 'division', 'location'],
|
|
40
41
|
value: { region: 'Europe', country: undefined, division: undefined, location: undefined },
|
|
41
42
|
placeholderText: 'Enter a location',
|
|
43
|
+
lapisFilter: {
|
|
44
|
+
age: 18,
|
|
45
|
+
},
|
|
42
46
|
},
|
|
43
47
|
argTypes: {
|
|
44
48
|
fields: {
|
|
@@ -61,6 +65,11 @@ const meta: Meta<LocationFilterProps> = {
|
|
|
61
65
|
type: 'text',
|
|
62
66
|
},
|
|
63
67
|
},
|
|
68
|
+
lapisFilter: {
|
|
69
|
+
control: {
|
|
70
|
+
type: 'object',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
64
73
|
},
|
|
65
74
|
};
|
|
66
75
|
|
|
@@ -81,16 +90,14 @@ export const Primary: StoryObj<LocationFilterProps> = {
|
|
|
81
90
|
await userEvent.type(input, 'Germany');
|
|
82
91
|
await userEvent.click(canvas.getByRole('option', { name: 'Germany Europe / Germany' }));
|
|
83
92
|
|
|
84
|
-
await
|
|
85
|
-
expect.
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}),
|
|
93
|
-
);
|
|
93
|
+
await waitFor(() => {
|
|
94
|
+
return expect(locationChangedListenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({
|
|
95
|
+
country: 'Germany',
|
|
96
|
+
region: 'Europe',
|
|
97
|
+
division: undefined,
|
|
98
|
+
location: undefined,
|
|
99
|
+
});
|
|
100
|
+
});
|
|
94
101
|
});
|
|
95
102
|
},
|
|
96
103
|
};
|
|
@@ -104,16 +111,14 @@ export const ClearSelection: StoryObj<LocationFilterProps> = {
|
|
|
104
111
|
const clearSelectionButton = await canvas.findByLabelText('clear selection');
|
|
105
112
|
await userEvent.click(clearSelectionButton);
|
|
106
113
|
|
|
107
|
-
await
|
|
108
|
-
expect.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}),
|
|
116
|
-
);
|
|
114
|
+
await waitFor(() => {
|
|
115
|
+
return expect(locationChangedListenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({
|
|
116
|
+
country: undefined,
|
|
117
|
+
region: undefined,
|
|
118
|
+
division: undefined,
|
|
119
|
+
location: undefined,
|
|
120
|
+
});
|
|
121
|
+
});
|
|
117
122
|
});
|
|
118
123
|
},
|
|
119
124
|
};
|
|
@@ -128,16 +133,14 @@ export const OnBlurInput: StoryObj<LocationFilterProps> = {
|
|
|
128
133
|
await userEvent.clear(input);
|
|
129
134
|
await userEvent.click(canvas.getByLabelText('toggle menu'));
|
|
130
135
|
|
|
131
|
-
await
|
|
132
|
-
expect.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}),
|
|
140
|
-
);
|
|
136
|
+
await waitFor(() => {
|
|
137
|
+
return expect(locationChangedListenerMock.mock.calls.at(-1)![0].detail).toStrictEqual({
|
|
138
|
+
country: undefined,
|
|
139
|
+
region: undefined,
|
|
140
|
+
division: undefined,
|
|
141
|
+
location: undefined,
|
|
142
|
+
});
|
|
143
|
+
});
|
|
141
144
|
});
|
|
142
145
|
},
|
|
143
146
|
};
|