@genspectrum/dashboard-components 0.16.3 → 0.17.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 +86 -61
- package/dist/{LineageFilterChangedEvent-COWV-Y0k.js → LineageFilterChangedEvent-DkvWdq_G.js} +2 -2
- package/dist/LineageFilterChangedEvent-DkvWdq_G.js.map +1 -0
- package/dist/assets/{mutationOverTimeWorker-DJcZmEH9.js.map → mutationOverTimeWorker-CPfQDLe6.js.map} +1 -1
- package/dist/components.d.ts +64 -51
- package/dist/components.js +1134 -937
- package/dist/components.js.map +1 -1
- package/dist/style.css +81 -9
- package/dist/util.d.ts +76 -34
- package/dist/util.js +1 -1
- package/package.json +2 -1
- package/src/preact/components/annotated-mutation.stories.tsx +2 -1
- package/src/preact/components/annotated-mutation.tsx +6 -2
- package/src/preact/components/clearable-select.stories.tsx +75 -0
- package/src/preact/components/clearable-select.tsx +76 -0
- package/src/preact/components/downshift-combobox.tsx +9 -7
- package/src/preact/dateRangeFilter/computeInitialValues.spec.ts +31 -33
- package/src/preact/dateRangeFilter/computeInitialValues.ts +2 -15
- package/src/preact/dateRangeFilter/date-picker.tsx +66 -0
- package/src/preact/dateRangeFilter/date-range-filter.stories.tsx +69 -31
- package/src/preact/dateRangeFilter/date-range-filter.tsx +136 -139
- package/src/preact/dateRangeFilter/dateRangeOption.ts +11 -11
- package/src/preact/mutationComparison/mutation-comparison-table.tsx +14 -1
- package/src/preact/mutationComparison/mutation-comparison-venn.tsx +39 -8
- package/src/preact/mutationComparison/mutation-comparison.stories.tsx +36 -12
- package/src/preact/mutationComparison/mutation-comparison.tsx +2 -0
- package/src/preact/mutations/mutations.stories.tsx +3 -9
- package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +3 -8
- package/src/preact/shared/WithClassName/WithClassName.ts +1 -0
- package/src/preact/shared/icons/DeleteIcon.tsx +3 -0
- package/src/preact/shared/stories/expectMutationAnnotation.ts +13 -0
- package/src/preact/shared/stories/expectOptionSelected.tsx +7 -0
- package/src/utilEntrypoint.ts +3 -1
- package/src/web-components/MutationAnnotations.mdx +33 -0
- package/src/web-components/ResizeContainer.mdx +1 -1
- package/src/web-components/errorHandling.mdx +1 -1
- package/src/web-components/gs-app.ts +2 -2
- package/src/web-components/input/gs-date-range-filter.stories.ts +38 -32
- package/src/web-components/input/gs-date-range-filter.tsx +8 -2
- package/src/web-components/input/gs-lineage-filter.tsx +1 -1
- package/src/web-components/input/gs-location-filter.tsx +1 -1
- package/src/web-components/input/gs-mutation-filter.tsx +1 -1
- package/src/web-components/input/gs-text-filter.tsx +1 -1
- package/src/web-components/visualization/gs-aggregate.tsx +2 -2
- package/src/web-components/visualization/gs-mutation-comparison.stories.ts +18 -1
- package/src/web-components/visualization/gs-mutation-comparison.tsx +24 -10
- package/src/web-components/visualization/gs-mutations-over-time.stories.ts +2 -1
- package/src/web-components/visualization/gs-mutations-over-time.tsx +5 -2
- package/src/web-components/visualization/gs-mutations.stories.ts +2 -1
- package/src/web-components/visualization/gs-mutations.tsx +5 -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/src/web-components/wastewaterVisualization/gs-wastewater-mutations-over-time.tsx +2 -2
- package/standalone-bundle/assets/mutationOverTimeWorker-CERZSdcA.js.map +1 -1
- package/standalone-bundle/dashboard-components.js +13293 -12635
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/standalone-bundle/style.css +1 -1
- package/dist/LineageFilterChangedEvent-COWV-Y0k.js.map +0 -1
|
@@ -2,6 +2,8 @@ import { useCombobox } from 'downshift/preact';
|
|
|
2
2
|
import { type ComponentChild } from 'preact';
|
|
3
3
|
import { useMemo, useRef, useState } from 'preact/hooks';
|
|
4
4
|
|
|
5
|
+
import { DeleteIcon } from '../shared/icons/DeleteIcon';
|
|
6
|
+
|
|
5
7
|
export function DownshiftCombobox<Item>({
|
|
6
8
|
allItems,
|
|
7
9
|
value,
|
|
@@ -10,18 +12,18 @@ export function DownshiftCombobox<Item>({
|
|
|
10
12
|
itemToString,
|
|
11
13
|
placeholderText,
|
|
12
14
|
formatItemInList,
|
|
15
|
+
inputClassName = '',
|
|
13
16
|
}: {
|
|
14
17
|
allItems: Item[];
|
|
15
|
-
value?: Item;
|
|
18
|
+
value?: Item | null;
|
|
16
19
|
filterItemsByInputValue: (item: Item, value: string) => boolean;
|
|
17
20
|
createEvent: (item: Item | null) => CustomEvent;
|
|
18
21
|
itemToString: (item: Item | undefined | null) => string;
|
|
19
22
|
placeholderText?: string;
|
|
20
23
|
formatItemInList: (item: Item) => ComponentChild;
|
|
24
|
+
inputClassName?: string;
|
|
21
25
|
}) {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
const [itemsFilter, setItemsFilter] = useState(itemToString(initialSelectedItem));
|
|
26
|
+
const [itemsFilter, setItemsFilter] = useState(itemToString(value));
|
|
25
27
|
const items = useMemo(
|
|
26
28
|
() => allItems.filter((item) => filterItemsByInputValue(item, itemsFilter)),
|
|
27
29
|
[allItems, filterItemsByInputValue, itemsFilter],
|
|
@@ -65,7 +67,7 @@ export function DownshiftCombobox<Item>({
|
|
|
65
67
|
itemToString(item) {
|
|
66
68
|
return itemToString(item);
|
|
67
69
|
},
|
|
68
|
-
|
|
70
|
+
selectedItem: value,
|
|
69
71
|
environment,
|
|
70
72
|
});
|
|
71
73
|
|
|
@@ -89,7 +91,7 @@ export function DownshiftCombobox<Item>({
|
|
|
89
91
|
<div ref={divRef} className={'relative w-full'}>
|
|
90
92
|
<div className='w-full flex flex-col gap-1'>
|
|
91
93
|
<div
|
|
92
|
-
className=
|
|
94
|
+
className={`flex gap-0.5 input input-bordered min-w-32 ${inputClassName}`}
|
|
93
95
|
onBlur={(event) => {
|
|
94
96
|
if (event.relatedTarget != buttonRef.current) {
|
|
95
97
|
closeMenu();
|
|
@@ -109,7 +111,7 @@ export function DownshiftCombobox<Item>({
|
|
|
109
111
|
onClick={clearInput}
|
|
110
112
|
tabIndex={-1}
|
|
111
113
|
>
|
|
112
|
-
|
|
114
|
+
<DeleteIcon />
|
|
113
115
|
</button>
|
|
114
116
|
<button
|
|
115
117
|
aria-label='toggle menu'
|
|
@@ -18,36 +18,34 @@ const dateRangeOptions = [
|
|
|
18
18
|
];
|
|
19
19
|
|
|
20
20
|
describe('computeInitialValues', () => {
|
|
21
|
+
it('should return undefined for unedfined value', () => {
|
|
22
|
+
const result = computeInitialValues(undefined, earliestDate, dateRangeOptions);
|
|
23
|
+
|
|
24
|
+
expect(result).toBeUndefined();
|
|
25
|
+
});
|
|
26
|
+
|
|
21
27
|
it('should compute initial value if value is dateRangeOption label', () => {
|
|
22
28
|
const result = computeInitialValues(fromToOption, earliestDate, dateRangeOptions);
|
|
23
29
|
|
|
24
|
-
expect(result
|
|
25
|
-
expectDateMatches(result
|
|
26
|
-
expectDateMatches(result
|
|
30
|
+
expect(result?.initialSelectedDateRange).toEqual(fromToOption);
|
|
31
|
+
expectDateMatches(result?.initialSelectedDateFrom, new Date(dateFromOptionValue));
|
|
32
|
+
expectDateMatches(result?.initialSelectedDateTo, new Date(dateToOptionValue));
|
|
27
33
|
});
|
|
28
34
|
|
|
29
35
|
it('should use today as "dateTo" if it is unset in selected option', () => {
|
|
30
36
|
const result = computeInitialValues(fromOption, earliestDate, dateRangeOptions);
|
|
31
37
|
|
|
32
|
-
expect(result
|
|
33
|
-
expectDateMatches(result
|
|
34
|
-
expectDateMatches(result
|
|
38
|
+
expect(result?.initialSelectedDateRange).toEqual(fromOption);
|
|
39
|
+
expectDateMatches(result?.initialSelectedDateFrom, new Date(dateFromOptionValue));
|
|
40
|
+
expectDateMatches(result?.initialSelectedDateTo, today);
|
|
35
41
|
});
|
|
36
42
|
|
|
37
43
|
it('should use earliest date as "dateFrom" if it is unset in selected option', () => {
|
|
38
44
|
const result = computeInitialValues(toOption, earliestDate, dateRangeOptions);
|
|
39
45
|
|
|
40
|
-
expect(result
|
|
41
|
-
expectDateMatches(result
|
|
42
|
-
expectDateMatches(result
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('should fall back to full range if initial value is not set', () => {
|
|
46
|
-
const result = computeInitialValues(undefined, earliestDate, dateRangeOptions);
|
|
47
|
-
|
|
48
|
-
expect(result.initialSelectedDateRange).toBeUndefined();
|
|
49
|
-
expectDateMatches(result.initialSelectedDateFrom, new Date(earliestDate));
|
|
50
|
-
expectDateMatches(result.initialSelectedDateTo, today);
|
|
46
|
+
expect(result?.initialSelectedDateRange).toEqual(toOption);
|
|
47
|
+
expectDateMatches(result?.initialSelectedDateFrom, new Date(earliestDate));
|
|
48
|
+
expectDateMatches(result?.initialSelectedDateTo, new Date(dateToOptionValue));
|
|
51
49
|
});
|
|
52
50
|
|
|
53
51
|
it('should throw when initial value is unknown', () => {
|
|
@@ -66,18 +64,18 @@ describe('computeInitialValues', () => {
|
|
|
66
64
|
const initialDateFrom = '2020-01-01';
|
|
67
65
|
const result = computeInitialValues({ dateFrom: initialDateFrom }, earliestDate, dateRangeOptions);
|
|
68
66
|
|
|
69
|
-
expect(result
|
|
70
|
-
expectDateMatches(result
|
|
71
|
-
expectDateMatches(result
|
|
67
|
+
expect(result?.initialSelectedDateRange).toBeUndefined();
|
|
68
|
+
expectDateMatches(result?.initialSelectedDateFrom, new Date(initialDateFrom));
|
|
69
|
+
expectDateMatches(result?.initialSelectedDateTo, today);
|
|
72
70
|
});
|
|
73
71
|
|
|
74
72
|
it('should select from earliest date until date if only dateTo is given', () => {
|
|
75
73
|
const initialDateTo = '2020-01-01';
|
|
76
74
|
const result = computeInitialValues({ dateTo: initialDateTo }, earliestDate, dateRangeOptions);
|
|
77
75
|
|
|
78
|
-
expect(result
|
|
79
|
-
expectDateMatches(result
|
|
80
|
-
expectDateMatches(result
|
|
76
|
+
expect(result?.initialSelectedDateRange).toBeUndefined();
|
|
77
|
+
expectDateMatches(result?.initialSelectedDateFrom, new Date(earliestDate));
|
|
78
|
+
expectDateMatches(result?.initialSelectedDateTo, new Date(initialDateTo));
|
|
81
79
|
});
|
|
82
80
|
|
|
83
81
|
it('should select date range is dateFrom and dateTo are given', () => {
|
|
@@ -92,9 +90,9 @@ describe('computeInitialValues', () => {
|
|
|
92
90
|
dateRangeOptions,
|
|
93
91
|
);
|
|
94
92
|
|
|
95
|
-
expect(result
|
|
96
|
-
expectDateMatches(result
|
|
97
|
-
expectDateMatches(result
|
|
93
|
+
expect(result?.initialSelectedDateRange).toBeUndefined();
|
|
94
|
+
expectDateMatches(result?.initialSelectedDateFrom, new Date(initialDateFrom));
|
|
95
|
+
expectDateMatches(result?.initialSelectedDateTo, new Date(initialDateTo));
|
|
98
96
|
});
|
|
99
97
|
|
|
100
98
|
it('should set initial "to" to "from" if "from" is after "to"', () => {
|
|
@@ -109,9 +107,9 @@ describe('computeInitialValues', () => {
|
|
|
109
107
|
dateRangeOptions,
|
|
110
108
|
);
|
|
111
109
|
|
|
112
|
-
expect(result
|
|
113
|
-
expectDateMatches(result
|
|
114
|
-
expectDateMatches(result
|
|
110
|
+
expect(result?.initialSelectedDateRange).toBeUndefined();
|
|
111
|
+
expectDateMatches(result?.initialSelectedDateFrom, new Date(initialDateFrom));
|
|
112
|
+
expectDateMatches(result?.initialSelectedDateTo, new Date(initialDateFrom));
|
|
115
113
|
});
|
|
116
114
|
|
|
117
115
|
it('should throw if initial "from" is not a valid date', () => {
|
|
@@ -126,9 +124,9 @@ describe('computeInitialValues', () => {
|
|
|
126
124
|
);
|
|
127
125
|
});
|
|
128
126
|
|
|
129
|
-
function expectDateMatches(actual: Date, expected: Date) {
|
|
130
|
-
expect(actual
|
|
131
|
-
expect(actual
|
|
132
|
-
expect(actual
|
|
127
|
+
function expectDateMatches(actual: Date | undefined, expected: Date | undefined) {
|
|
128
|
+
expect(actual?.getFullYear()).toEqual(expected?.getFullYear());
|
|
129
|
+
expect(actual?.getMonth()).toEqual(expected?.getMonth());
|
|
130
|
+
expect(actual?.getDate()).toEqual(expected?.getDate());
|
|
133
131
|
}
|
|
134
132
|
});
|
|
@@ -2,22 +2,9 @@ import { type DateRangeOption, type DateRangeValue } from './dateRangeOption';
|
|
|
2
2
|
import { getDatesForSelectorValue, getSelectableOptions } from './selectableOptions';
|
|
3
3
|
import { UserFacingError } from '../components/error-display';
|
|
4
4
|
|
|
5
|
-
export function computeInitialValues(
|
|
6
|
-
value: DateRangeValue | undefined,
|
|
7
|
-
earliestDate: string,
|
|
8
|
-
dateRangeOptions: DateRangeOption[],
|
|
9
|
-
): {
|
|
10
|
-
initialSelectedDateRange: string | undefined;
|
|
11
|
-
initialSelectedDateFrom: Date;
|
|
12
|
-
initialSelectedDateTo: Date;
|
|
13
|
-
} {
|
|
5
|
+
export function computeInitialValues(value: DateRangeValue, earliestDate: string, dateRangeOptions: DateRangeOption[]) {
|
|
14
6
|
if (value === undefined) {
|
|
15
|
-
|
|
16
|
-
return {
|
|
17
|
-
initialSelectedDateRange: undefined,
|
|
18
|
-
initialSelectedDateFrom: dateFrom,
|
|
19
|
-
initialSelectedDateTo: dateTo,
|
|
20
|
-
};
|
|
7
|
+
return undefined;
|
|
21
8
|
}
|
|
22
9
|
|
|
23
10
|
if (typeof value === 'string') {
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import 'flatpickr/dist/flatpickr.min.css';
|
|
2
|
+
import flatpickr from 'flatpickr';
|
|
3
|
+
import { useEffect, useRef, useState } from 'preact/hooks';
|
|
4
|
+
|
|
5
|
+
import { type WithClassName } from '../shared/WithClassName/WithClassName';
|
|
6
|
+
|
|
7
|
+
export function DatePicker({
|
|
8
|
+
onChange,
|
|
9
|
+
value,
|
|
10
|
+
minDate,
|
|
11
|
+
maxDate,
|
|
12
|
+
placeholderText,
|
|
13
|
+
className,
|
|
14
|
+
}: WithClassName<{
|
|
15
|
+
onChange?: (date: Date | undefined) => void;
|
|
16
|
+
value?: Date;
|
|
17
|
+
minDate?: Date;
|
|
18
|
+
maxDate?: Date;
|
|
19
|
+
placeholderText?: string;
|
|
20
|
+
}>) {
|
|
21
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
22
|
+
|
|
23
|
+
const [datePicker, setDatePicker] = useState<flatpickr.Instance | null>(null);
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!inputRef.current) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const instance = flatpickr(inputRef.current, {
|
|
31
|
+
allowInput: true,
|
|
32
|
+
dateFormat: 'Y-m-d',
|
|
33
|
+
defaultDate: value,
|
|
34
|
+
minDate,
|
|
35
|
+
maxDate,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
setDatePicker(instance);
|
|
39
|
+
|
|
40
|
+
return () => {
|
|
41
|
+
instance.destroy();
|
|
42
|
+
};
|
|
43
|
+
}, [maxDate, minDate, onChange, value]);
|
|
44
|
+
|
|
45
|
+
if (value === undefined && inputRef.current) {
|
|
46
|
+
inputRef.current.value = '';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const handleChange = () => {
|
|
50
|
+
const newValue = datePicker?.selectedDates[0];
|
|
51
|
+
if (onChange) {
|
|
52
|
+
onChange(newValue);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<input
|
|
58
|
+
className={`input input-bordered w-full ${className}`}
|
|
59
|
+
type='text'
|
|
60
|
+
placeholder={placeholderText}
|
|
61
|
+
ref={inputRef}
|
|
62
|
+
onChange={handleChange}
|
|
63
|
+
onBlur={handleChange}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
@@ -8,8 +8,9 @@ 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';
|
|
11
|
-
import { dateRangeOptionPresets } from './dateRangeOption';
|
|
11
|
+
import { dateRangeOptionPresets, type DateRangeValue } from './dateRangeOption';
|
|
12
12
|
import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
13
|
+
import { expectOptionSelected } from '../shared/stories/expectOptionSelected';
|
|
13
14
|
|
|
14
15
|
const earliestDate = '1970-01-01';
|
|
15
16
|
|
|
@@ -19,6 +20,8 @@ const customDateRange = {
|
|
|
19
20
|
dateTo: '2021-12-31',
|
|
20
21
|
};
|
|
21
22
|
|
|
23
|
+
const placeholder = 'Date range';
|
|
24
|
+
|
|
22
25
|
const meta: Meta<DateRangeFilterProps> = {
|
|
23
26
|
title: 'Input/DateRangeFilter',
|
|
24
27
|
component: DateRangeFilter,
|
|
@@ -56,6 +59,7 @@ const meta: Meta<DateRangeFilterProps> = {
|
|
|
56
59
|
value: undefined,
|
|
57
60
|
lapisDateField: 'aDateColumn',
|
|
58
61
|
width: '100%',
|
|
62
|
+
placeholder,
|
|
59
63
|
},
|
|
60
64
|
};
|
|
61
65
|
|
|
@@ -69,6 +73,22 @@ const Primary: StoryObj<DateRangeFilterProps> = {
|
|
|
69
73
|
),
|
|
70
74
|
};
|
|
71
75
|
|
|
76
|
+
export const WithUndefinedValue: StoryObj<DateRangeFilterProps> = {
|
|
77
|
+
...Primary,
|
|
78
|
+
args: {
|
|
79
|
+
...Primary.args,
|
|
80
|
+
},
|
|
81
|
+
play: async ({ canvasElement }) => {
|
|
82
|
+
const canvas = within(canvasElement);
|
|
83
|
+
|
|
84
|
+
await waitFor(async () => {
|
|
85
|
+
await expectOptionSelected(canvasElement, placeholder);
|
|
86
|
+
await expect(dateFromPicker(canvas)).toHaveValue('');
|
|
87
|
+
await expect(dateToPicker(canvas)).toHaveValue('');
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
72
92
|
export const SetCorrectInitialValues: StoryObj<DateRangeFilterProps> = {
|
|
73
93
|
...Primary,
|
|
74
94
|
args: {
|
|
@@ -79,6 +99,7 @@ export const SetCorrectInitialValues: StoryObj<DateRangeFilterProps> = {
|
|
|
79
99
|
const canvas = within(canvasElement);
|
|
80
100
|
|
|
81
101
|
await waitFor(async () => {
|
|
102
|
+
await expectOptionSelected(canvasElement, 'CustomDateRange');
|
|
82
103
|
await expect(selectField(canvas)).toHaveValue('CustomDateRange');
|
|
83
104
|
await expect(dateFromPicker(canvas)).toHaveValue('2021-01-01');
|
|
84
105
|
await expect(dateToPicker(canvas)).toHaveValue('2021-12-31');
|
|
@@ -98,7 +119,7 @@ export const SetCorrectInitialDateFrom: StoryObj<DateRangeFilterProps> = {
|
|
|
98
119
|
const canvas = within(canvasElement);
|
|
99
120
|
|
|
100
121
|
await waitFor(async () => {
|
|
101
|
-
await
|
|
122
|
+
await expectOptionSelected(canvasElement, 'Custom');
|
|
102
123
|
await expect(dateFromPicker(canvas)).toHaveValue(initialDateFrom);
|
|
103
124
|
await expect(dateToPicker(canvas)).toHaveValue(dayjs().format('YYYY-MM-DD'));
|
|
104
125
|
});
|
|
@@ -117,14 +138,14 @@ export const SetCorrectInitialDateTo: StoryObj<DateRangeFilterProps> = {
|
|
|
117
138
|
const canvas = within(canvasElement);
|
|
118
139
|
|
|
119
140
|
await waitFor(async () => {
|
|
120
|
-
await
|
|
141
|
+
await expectOptionSelected(canvasElement, 'Custom');
|
|
121
142
|
await expect(dateFromPicker(canvas)).toHaveValue(earliestDate);
|
|
122
143
|
await expect(dateToPicker(canvas)).toHaveValue(initialDateTo);
|
|
123
144
|
});
|
|
124
145
|
},
|
|
125
146
|
};
|
|
126
147
|
|
|
127
|
-
export const
|
|
148
|
+
export const SetsValueOnBlur: StoryObj<DateRangeFilterProps> = {
|
|
128
149
|
...Primary,
|
|
129
150
|
args: {
|
|
130
151
|
...Primary.args,
|
|
@@ -143,26 +164,28 @@ export const ChangingDateSetsOptionToCustom: StoryObj<DateRangeFilterProps> = {
|
|
|
143
164
|
await userEvent.click(dateToPicker(canvas));
|
|
144
165
|
|
|
145
166
|
await waitFor(async () => {
|
|
146
|
-
await
|
|
167
|
+
await expectOptionSelected(canvasElement, 'Custom');
|
|
147
168
|
});
|
|
148
169
|
|
|
149
|
-
await
|
|
150
|
-
expect.
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
expect.
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
170
|
+
await waitFor(async () => {
|
|
171
|
+
await expect(filterChangedListenerMock).toHaveBeenCalledWith(
|
|
172
|
+
expect.objectContaining({
|
|
173
|
+
detail: {
|
|
174
|
+
aDateColumnFrom: '2000-01-01',
|
|
175
|
+
aDateColumnTo: dayjs().format('YYYY-MM-DD'),
|
|
176
|
+
},
|
|
177
|
+
}),
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
await expect(optionChangedListenerMock).toHaveBeenCalledWith(
|
|
181
|
+
expect.objectContaining({
|
|
182
|
+
detail: {
|
|
183
|
+
dateFrom: '2000-01-01',
|
|
184
|
+
dateTo: dayjs().format('YYYY-MM-DD'),
|
|
185
|
+
},
|
|
186
|
+
}),
|
|
187
|
+
);
|
|
188
|
+
});
|
|
166
189
|
});
|
|
167
190
|
},
|
|
168
191
|
};
|
|
@@ -171,12 +194,13 @@ export const ChangingTheValueProgrammatically: StoryObj<DateRangeFilterProps> =
|
|
|
171
194
|
...Primary,
|
|
172
195
|
render: (args) => {
|
|
173
196
|
const StatefulWrapper = () => {
|
|
174
|
-
const [value, setValue] = useState('Last month');
|
|
197
|
+
const [value, setValue] = useState<DateRangeValue | undefined>('Last month');
|
|
175
198
|
const ref = useRef<HTMLDivElement>(null);
|
|
176
199
|
|
|
177
200
|
useEffect(() => {
|
|
178
201
|
ref.current?.addEventListener('gs-date-range-option-changed', (event) => {
|
|
179
|
-
|
|
202
|
+
const newValue = (event as CustomEvent).detail;
|
|
203
|
+
setValue(newValue ?? undefined);
|
|
180
204
|
});
|
|
181
205
|
}, []);
|
|
182
206
|
|
|
@@ -207,12 +231,13 @@ export const ChangingTheValueProgrammatically: StoryObj<DateRangeFilterProps> =
|
|
|
207
231
|
await step('Change the value of the component programmatically', async () => {
|
|
208
232
|
await userEvent.click(canvas.getByRole('button', { name: 'Set to Custom' }));
|
|
209
233
|
await waitFor(async () => {
|
|
234
|
+
await expectOptionSelected(canvasElement, customDateRange.label);
|
|
210
235
|
await expect(selectField(canvas)).toHaveValue(customDateRange.label);
|
|
211
236
|
});
|
|
212
237
|
|
|
213
238
|
await userEvent.click(canvas.getByRole('button', { name: 'Set to Last month' }));
|
|
214
239
|
await waitFor(async () => {
|
|
215
|
-
await
|
|
240
|
+
await expectOptionSelected(canvasElement, 'Last month');
|
|
216
241
|
});
|
|
217
242
|
|
|
218
243
|
await expect(filterChangedListenerMock).toHaveBeenCalledTimes(0);
|
|
@@ -220,12 +245,25 @@ export const ChangingTheValueProgrammatically: StoryObj<DateRangeFilterProps> =
|
|
|
220
245
|
});
|
|
221
246
|
|
|
222
247
|
await step('Changing the value from within the component is still possible', async () => {
|
|
223
|
-
await userEvent.selectOptions(selectField(canvas), 'All times');
|
|
224
248
|
await waitFor(async () => {
|
|
225
|
-
await
|
|
249
|
+
await userEvent.selectOptions(selectField(canvas), 'All times');
|
|
250
|
+
await expectOptionSelected(canvasElement, 'All times');
|
|
251
|
+
});
|
|
252
|
+
await waitFor(async () => {
|
|
253
|
+
await expect(filterChangedListenerMock).toHaveBeenCalledTimes(1);
|
|
254
|
+
await expect(optionChangedListenerMock).toHaveBeenCalledTimes(1);
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
await step('Clearing the value from within the component is still possible', async () => {
|
|
259
|
+
await waitFor(async () => {
|
|
260
|
+
await userEvent.click(canvas.getByRole('button', { name: '×' }));
|
|
261
|
+
await expectOptionSelected(canvasElement, placeholder);
|
|
262
|
+
});
|
|
263
|
+
await waitFor(async () => {
|
|
264
|
+
await expect(filterChangedListenerMock).toHaveBeenCalledTimes(2);
|
|
265
|
+
await expect(optionChangedListenerMock).toHaveBeenCalledTimes(2);
|
|
226
266
|
});
|
|
227
|
-
await expect(filterChangedListenerMock).toHaveBeenCalledTimes(1);
|
|
228
|
-
await expect(optionChangedListenerMock).toHaveBeenCalledTimes(1);
|
|
229
267
|
});
|
|
230
268
|
},
|
|
231
269
|
};
|
|
@@ -236,13 +274,13 @@ export const ChangingDateOption: StoryObj<DateRangeFilterProps> = {
|
|
|
236
274
|
const { canvas, filterChangedListenerMock, optionChangedListenerMock } = await prepare(canvasElement, step);
|
|
237
275
|
|
|
238
276
|
await waitFor(async () => {
|
|
239
|
-
await
|
|
277
|
+
await expectOptionSelected(canvasElement, placeholder);
|
|
240
278
|
});
|
|
241
279
|
|
|
242
280
|
await step('Change date to custom', async () => {
|
|
243
281
|
await waitFor(async () => {
|
|
244
282
|
await userEvent.selectOptions(selectField(canvas), 'CustomDateRange');
|
|
245
|
-
await
|
|
283
|
+
await expectOptionSelected(canvasElement, 'CustomDateRange');
|
|
246
284
|
});
|
|
247
285
|
|
|
248
286
|
await expect(filterChangedListenerMock).toHaveBeenCalledWith(
|