@genspectrum/dashboard-components 0.19.9 → 0.21.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 +8 -27
- package/dist/{NumberRangeFilterChangedEvent-RZ8haPHq.js → NumberRangeFilterChangedEvent-B64OQZjX.js} +47 -43
- package/dist/NumberRangeFilterChangedEvent-B64OQZjX.js.map +1 -0
- package/dist/components.d.ts +28 -32
- package/dist/components.js +39 -80
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +36 -57
- package/dist/util.js +1 -1
- package/package.json +2 -2
- package/src/preact/dateRangeFilter/computeInitialValues.spec.ts +18 -29
- package/src/preact/dateRangeFilter/computeInitialValues.ts +29 -27
- package/src/preact/dateRangeFilter/date-range-filter.stories.tsx +8 -15
- package/src/preact/dateRangeFilter/date-range-filter.tsx +16 -35
- package/src/preact/dateRangeFilter/dateRangeOption.ts +67 -47
- package/src/preact/dateRangeFilter/selectableOptions.ts +0 -23
- package/src/preact/statistic/statistics.stories.tsx +67 -0
- package/src/preact/statistic/statistics.tsx +3 -1
- package/src/web-components/input/gs-date-range-filter.stories.ts +4 -13
- package/src/web-components/input/gs-date-range-filter.tsx +2 -12
- package/standalone-bundle/dashboard-components.js +7398 -7372
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/dist/NumberRangeFilterChangedEvent-RZ8haPHq.js.map +0 -1
package/dist/util.d.ts
CHANGED
|
@@ -77,38 +77,19 @@ export declare class DateRangeOptionChangedEvent extends CustomEvent<DateRangeVa
|
|
|
77
77
|
constructor(detail: DateRangeValue);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
declare type DateRangeOptionPresets = {
|
|
81
|
+
last2Weeks: DateRangeOption;
|
|
82
|
+
lastMonth: DateRangeOption;
|
|
83
|
+
last2Months: DateRangeOption;
|
|
84
|
+
last3Months: DateRangeOption;
|
|
85
|
+
last6Months: DateRangeOption;
|
|
86
|
+
lastYear: DateRangeOption;
|
|
87
|
+
};
|
|
88
|
+
|
|
80
89
|
/**
|
|
81
90
|
* Presets for the `gs-date-range-filter` component that can be used as `dateRangeOptions`.
|
|
82
91
|
*/
|
|
83
|
-
export declare const dateRangeOptionPresets:
|
|
84
|
-
last2Weeks: {
|
|
85
|
-
label: string;
|
|
86
|
-
dateFrom: string;
|
|
87
|
-
};
|
|
88
|
-
lastMonth: {
|
|
89
|
-
label: string;
|
|
90
|
-
dateFrom: string;
|
|
91
|
-
};
|
|
92
|
-
last2Months: {
|
|
93
|
-
label: string;
|
|
94
|
-
dateFrom: string;
|
|
95
|
-
};
|
|
96
|
-
last3Months: {
|
|
97
|
-
label: string;
|
|
98
|
-
dateFrom: string;
|
|
99
|
-
};
|
|
100
|
-
last6Months: {
|
|
101
|
-
label: string;
|
|
102
|
-
dateFrom: string;
|
|
103
|
-
};
|
|
104
|
-
lastYear: {
|
|
105
|
-
label: string;
|
|
106
|
-
dateFrom: string;
|
|
107
|
-
};
|
|
108
|
-
allTimes: {
|
|
109
|
-
label: string;
|
|
110
|
-
};
|
|
111
|
-
};
|
|
92
|
+
export declare const dateRangeOptionPresets: () => DateRangeOptionPresets;
|
|
112
93
|
|
|
113
94
|
/**
|
|
114
95
|
* A date range option that can be used in the `gs-date-range-filter` component.
|
|
@@ -118,12 +99,10 @@ declare const dateRangeOptionSchema: default_2.ZodObject<{
|
|
|
118
99
|
label: default_2.ZodString;
|
|
119
100
|
/**
|
|
120
101
|
* The start date of the date range in the format `YYYY-MM-DD`.
|
|
121
|
-
* If not set, the date range selector will default to the `earliestDate` property.
|
|
122
102
|
*/
|
|
123
103
|
dateFrom: default_2.ZodOptional<default_2.ZodString>;
|
|
124
104
|
/**
|
|
125
105
|
* The end date of the date range in the format `YYYY-MM-DD`.
|
|
126
|
-
* If not set, the date range selector will default to the current date.
|
|
127
106
|
*/
|
|
128
107
|
dateTo: default_2.ZodOptional<default_2.ZodString>;
|
|
129
108
|
}, "strip", default_2.ZodTypeAny, {
|
|
@@ -938,7 +917,7 @@ declare global {
|
|
|
938
917
|
|
|
939
918
|
declare global {
|
|
940
919
|
interface HTMLElementTagNameMap {
|
|
941
|
-
'gs-
|
|
920
|
+
'gs-genome-data-viewer': GenomeDataViewerComponent;
|
|
942
921
|
}
|
|
943
922
|
}
|
|
944
923
|
|
|
@@ -946,7 +925,7 @@ declare global {
|
|
|
946
925
|
declare global {
|
|
947
926
|
namespace JSX {
|
|
948
927
|
interface IntrinsicElements {
|
|
949
|
-
'gs-
|
|
928
|
+
'gs-genome-data-viewer': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
950
929
|
}
|
|
951
930
|
}
|
|
952
931
|
}
|
|
@@ -954,7 +933,7 @@ declare global {
|
|
|
954
933
|
|
|
955
934
|
declare global {
|
|
956
935
|
interface HTMLElementTagNameMap {
|
|
957
|
-
'gs-
|
|
936
|
+
'gs-mutations': MutationsComponent;
|
|
958
937
|
}
|
|
959
938
|
}
|
|
960
939
|
|
|
@@ -962,7 +941,7 @@ declare global {
|
|
|
962
941
|
declare global {
|
|
963
942
|
namespace JSX {
|
|
964
943
|
interface IntrinsicElements {
|
|
965
|
-
'gs-
|
|
944
|
+
'gs-mutations': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
966
945
|
}
|
|
967
946
|
}
|
|
968
947
|
}
|
|
@@ -986,7 +965,7 @@ declare global {
|
|
|
986
965
|
|
|
987
966
|
declare global {
|
|
988
967
|
interface HTMLElementTagNameMap {
|
|
989
|
-
'gs-
|
|
968
|
+
'gs-relative-growth-advantage': RelativeGrowthAdvantageComponent;
|
|
990
969
|
}
|
|
991
970
|
}
|
|
992
971
|
|
|
@@ -994,7 +973,7 @@ declare global {
|
|
|
994
973
|
declare global {
|
|
995
974
|
namespace JSX {
|
|
996
975
|
interface IntrinsicElements {
|
|
997
|
-
'gs-
|
|
976
|
+
'gs-relative-growth-advantage': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
998
977
|
}
|
|
999
978
|
}
|
|
1000
979
|
}
|
|
@@ -1002,7 +981,7 @@ declare global {
|
|
|
1002
981
|
|
|
1003
982
|
declare global {
|
|
1004
983
|
interface HTMLElementTagNameMap {
|
|
1005
|
-
'gs-
|
|
984
|
+
'gs-prevalence-over-time': PrevalenceOverTimeComponent;
|
|
1006
985
|
}
|
|
1007
986
|
}
|
|
1008
987
|
|
|
@@ -1010,7 +989,7 @@ declare global {
|
|
|
1010
989
|
declare global {
|
|
1011
990
|
namespace JSX {
|
|
1012
991
|
interface IntrinsicElements {
|
|
1013
|
-
'gs-
|
|
992
|
+
'gs-prevalence-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1014
993
|
}
|
|
1015
994
|
}
|
|
1016
995
|
}
|
|
@@ -1018,7 +997,7 @@ declare global {
|
|
|
1018
997
|
|
|
1019
998
|
declare global {
|
|
1020
999
|
interface HTMLElementTagNameMap {
|
|
1021
|
-
'gs-
|
|
1000
|
+
'gs-aggregate': AggregateComponent;
|
|
1022
1001
|
}
|
|
1023
1002
|
}
|
|
1024
1003
|
|
|
@@ -1026,7 +1005,7 @@ declare global {
|
|
|
1026
1005
|
declare global {
|
|
1027
1006
|
namespace JSX {
|
|
1028
1007
|
interface IntrinsicElements {
|
|
1029
|
-
'gs-
|
|
1008
|
+
'gs-aggregate': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1030
1009
|
}
|
|
1031
1010
|
}
|
|
1032
1011
|
}
|
|
@@ -1034,7 +1013,7 @@ declare global {
|
|
|
1034
1013
|
|
|
1035
1014
|
declare global {
|
|
1036
1015
|
interface HTMLElementTagNameMap {
|
|
1037
|
-
'gs-
|
|
1016
|
+
'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
|
|
1038
1017
|
}
|
|
1039
1018
|
}
|
|
1040
1019
|
|
|
@@ -1042,7 +1021,7 @@ declare global {
|
|
|
1042
1021
|
declare global {
|
|
1043
1022
|
namespace JSX {
|
|
1044
1023
|
interface IntrinsicElements {
|
|
1045
|
-
'gs-
|
|
1024
|
+
'gs-number-sequences-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1046
1025
|
}
|
|
1047
1026
|
}
|
|
1048
1027
|
}
|
|
@@ -1050,7 +1029,7 @@ declare global {
|
|
|
1050
1029
|
|
|
1051
1030
|
declare global {
|
|
1052
1031
|
interface HTMLElementTagNameMap {
|
|
1053
|
-
'gs-
|
|
1032
|
+
'gs-mutations-over-time': MutationsOverTimeComponent;
|
|
1054
1033
|
}
|
|
1055
1034
|
}
|
|
1056
1035
|
|
|
@@ -1058,7 +1037,7 @@ declare global {
|
|
|
1058
1037
|
declare global {
|
|
1059
1038
|
namespace JSX {
|
|
1060
1039
|
interface IntrinsicElements {
|
|
1061
|
-
'gs-
|
|
1040
|
+
'gs-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1062
1041
|
}
|
|
1063
1042
|
}
|
|
1064
1043
|
}
|
|
@@ -1066,7 +1045,7 @@ declare global {
|
|
|
1066
1045
|
|
|
1067
1046
|
declare global {
|
|
1068
1047
|
interface HTMLElementTagNameMap {
|
|
1069
|
-
'gs-
|
|
1048
|
+
'gs-sequences-by-location': SequencesByLocationComponent;
|
|
1070
1049
|
}
|
|
1071
1050
|
}
|
|
1072
1051
|
|
|
@@ -1074,7 +1053,7 @@ declare global {
|
|
|
1074
1053
|
declare global {
|
|
1075
1054
|
namespace JSX {
|
|
1076
1055
|
interface IntrinsicElements {
|
|
1077
|
-
'gs-
|
|
1056
|
+
'gs-sequences-by-location': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1078
1057
|
}
|
|
1079
1058
|
}
|
|
1080
1059
|
}
|
|
@@ -1082,7 +1061,7 @@ declare global {
|
|
|
1082
1061
|
|
|
1083
1062
|
declare global {
|
|
1084
1063
|
interface HTMLElementTagNameMap {
|
|
1085
|
-
'gs-
|
|
1064
|
+
'gs-statistics': StatisticsComponent;
|
|
1086
1065
|
}
|
|
1087
1066
|
}
|
|
1088
1067
|
|
|
@@ -1090,7 +1069,7 @@ declare global {
|
|
|
1090
1069
|
declare global {
|
|
1091
1070
|
namespace JSX {
|
|
1092
1071
|
interface IntrinsicElements {
|
|
1093
|
-
'gs-
|
|
1072
|
+
'gs-statistics': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1094
1073
|
}
|
|
1095
1074
|
}
|
|
1096
1075
|
}
|
|
@@ -1098,11 +1077,7 @@ declare global {
|
|
|
1098
1077
|
|
|
1099
1078
|
declare global {
|
|
1100
1079
|
interface HTMLElementTagNameMap {
|
|
1101
|
-
'gs-
|
|
1102
|
-
}
|
|
1103
|
-
interface HTMLElementEventMap {
|
|
1104
|
-
[gsEventNames.dateRangeFilterChanged]: CustomEvent<Record<string, string>>;
|
|
1105
|
-
[gsEventNames.dateRangeOptionChanged]: DateRangeOptionChangedEvent;
|
|
1080
|
+
'gs-wastewater-mutations-over-time': WastewaterMutationsOverTimeComponent;
|
|
1106
1081
|
}
|
|
1107
1082
|
}
|
|
1108
1083
|
|
|
@@ -1110,7 +1085,7 @@ declare global {
|
|
|
1110
1085
|
declare global {
|
|
1111
1086
|
namespace JSX {
|
|
1112
1087
|
interface IntrinsicElements {
|
|
1113
|
-
'gs-
|
|
1088
|
+
'gs-wastewater-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1114
1089
|
}
|
|
1115
1090
|
}
|
|
1116
1091
|
}
|
|
@@ -1118,7 +1093,11 @@ declare global {
|
|
|
1118
1093
|
|
|
1119
1094
|
declare global {
|
|
1120
1095
|
interface HTMLElementTagNameMap {
|
|
1121
|
-
'gs-
|
|
1096
|
+
'gs-date-range-filter': DateRangeFilterComponent;
|
|
1097
|
+
}
|
|
1098
|
+
interface HTMLElementEventMap {
|
|
1099
|
+
[gsEventNames.dateRangeFilterChanged]: CustomEvent<Record<string, string>>;
|
|
1100
|
+
[gsEventNames.dateRangeOptionChanged]: DateRangeOptionChangedEvent;
|
|
1122
1101
|
}
|
|
1123
1102
|
}
|
|
1124
1103
|
|
|
@@ -1126,7 +1105,7 @@ declare global {
|
|
|
1126
1105
|
declare global {
|
|
1127
1106
|
namespace JSX {
|
|
1128
1107
|
interface IntrinsicElements {
|
|
1129
|
-
'gs-
|
|
1108
|
+
'gs-date-range-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1130
1109
|
}
|
|
1131
1110
|
}
|
|
1132
1111
|
}
|
package/dist/util.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genspectrum/dashboard-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "GenSpectrum web components for building dashboards",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
"@storybook/preact": "^8.0.9",
|
|
112
112
|
"@storybook/preact-vite": "^8.0.9",
|
|
113
113
|
"@storybook/test": "^8.0.0",
|
|
114
|
-
"@storybook/test-runner": "^0.
|
|
114
|
+
"@storybook/test-runner": "^0.23.0",
|
|
115
115
|
"@storybook/types": "^8.0.9",
|
|
116
116
|
"@storybook/web-components": "^8.0.9",
|
|
117
117
|
"@storybook/web-components-vite": "^8.0.9",
|
|
@@ -2,9 +2,6 @@ import { describe, expect, it } from 'vitest';
|
|
|
2
2
|
|
|
3
3
|
import { computeInitialValues } from './computeInitialValues';
|
|
4
4
|
|
|
5
|
-
const today = new Date();
|
|
6
|
-
const earliestDate = '1900-01-01';
|
|
7
|
-
|
|
8
5
|
const fromOption = 'fromOption';
|
|
9
6
|
const toOption = 'toOption';
|
|
10
7
|
const fromToOption = 'fromToOption';
|
|
@@ -19,62 +16,60 @@ const dateRangeOptions = [
|
|
|
19
16
|
|
|
20
17
|
describe('computeInitialValues', () => {
|
|
21
18
|
it('should return undefined for null value', () => {
|
|
22
|
-
const result = computeInitialValues(null,
|
|
19
|
+
const result = computeInitialValues(null, dateRangeOptions);
|
|
23
20
|
|
|
24
21
|
expect(result).toBeUndefined();
|
|
25
22
|
});
|
|
26
23
|
|
|
27
24
|
it('should compute initial value if value is dateRangeOption label', () => {
|
|
28
|
-
const result = computeInitialValues(fromToOption,
|
|
25
|
+
const result = computeInitialValues(fromToOption, dateRangeOptions);
|
|
29
26
|
|
|
30
27
|
expect(result?.initialSelectedDateRange).toEqual(fromToOption);
|
|
31
28
|
expectDateMatches(result?.initialSelectedDateFrom, new Date(dateFromOptionValue));
|
|
32
29
|
expectDateMatches(result?.initialSelectedDateTo, new Date(dateToOptionValue));
|
|
33
30
|
});
|
|
34
31
|
|
|
35
|
-
it('should
|
|
36
|
-
const result = computeInitialValues(fromOption,
|
|
32
|
+
it('should compute initial value if value is dateRangeOption label with missing date to', () => {
|
|
33
|
+
const result = computeInitialValues(fromOption, dateRangeOptions);
|
|
37
34
|
|
|
38
35
|
expect(result?.initialSelectedDateRange).toEqual(fromOption);
|
|
39
36
|
expectDateMatches(result?.initialSelectedDateFrom, new Date(dateFromOptionValue));
|
|
40
|
-
expectDateMatches(result?.initialSelectedDateTo,
|
|
37
|
+
expectDateMatches(result?.initialSelectedDateTo, undefined);
|
|
41
38
|
});
|
|
42
39
|
|
|
43
|
-
it('should
|
|
44
|
-
const result = computeInitialValues(toOption,
|
|
40
|
+
it('should compute initial value if value is dateRangeOption label with missing date from', () => {
|
|
41
|
+
const result = computeInitialValues(toOption, dateRangeOptions);
|
|
45
42
|
|
|
46
43
|
expect(result?.initialSelectedDateRange).toEqual(toOption);
|
|
47
|
-
expectDateMatches(result?.initialSelectedDateFrom,
|
|
44
|
+
expectDateMatches(result?.initialSelectedDateFrom, undefined);
|
|
48
45
|
expectDateMatches(result?.initialSelectedDateTo, new Date(dateToOptionValue));
|
|
49
46
|
});
|
|
50
47
|
|
|
51
48
|
it('should throw when initial value is unknown', () => {
|
|
52
|
-
expect(() => computeInitialValues('not a known value',
|
|
49
|
+
expect(() => computeInitialValues('not a known value', dateRangeOptions)).toThrowError(
|
|
53
50
|
/Invalid value "not a known value", It must be one of/,
|
|
54
51
|
);
|
|
55
52
|
});
|
|
56
53
|
|
|
57
54
|
it('should throw when initial value is set but no options are provided', () => {
|
|
58
|
-
expect(() => computeInitialValues('not a known value',
|
|
59
|
-
/There are no selectable options/,
|
|
60
|
-
);
|
|
55
|
+
expect(() => computeInitialValues('not a known value', [])).toThrowError(/There are no selectable options/);
|
|
61
56
|
});
|
|
62
57
|
|
|
63
|
-
it('should
|
|
58
|
+
it('should compute initial date if only dateFrom is given', () => {
|
|
64
59
|
const initialDateFrom = '2020-01-01';
|
|
65
|
-
const result = computeInitialValues({ dateFrom: initialDateFrom },
|
|
60
|
+
const result = computeInitialValues({ dateFrom: initialDateFrom }, dateRangeOptions);
|
|
66
61
|
|
|
67
62
|
expect(result?.initialSelectedDateRange).toBeUndefined();
|
|
68
63
|
expectDateMatches(result?.initialSelectedDateFrom, new Date(initialDateFrom));
|
|
69
|
-
expectDateMatches(result?.initialSelectedDateTo,
|
|
64
|
+
expectDateMatches(result?.initialSelectedDateTo, undefined);
|
|
70
65
|
});
|
|
71
66
|
|
|
72
|
-
it('should
|
|
67
|
+
it('should compute initial date if only dateTo is given', () => {
|
|
73
68
|
const initialDateTo = '2020-01-01';
|
|
74
|
-
const result = computeInitialValues({ dateTo: initialDateTo },
|
|
69
|
+
const result = computeInitialValues({ dateTo: initialDateTo }, dateRangeOptions);
|
|
75
70
|
|
|
76
71
|
expect(result?.initialSelectedDateRange).toBeUndefined();
|
|
77
|
-
expectDateMatches(result?.initialSelectedDateFrom,
|
|
72
|
+
expectDateMatches(result?.initialSelectedDateFrom, undefined);
|
|
78
73
|
expectDateMatches(result?.initialSelectedDateTo, new Date(initialDateTo));
|
|
79
74
|
});
|
|
80
75
|
|
|
@@ -86,7 +81,6 @@ describe('computeInitialValues', () => {
|
|
|
86
81
|
dateFrom: initialDateFrom,
|
|
87
82
|
dateTo: initialDateTo,
|
|
88
83
|
},
|
|
89
|
-
earliestDate,
|
|
90
84
|
dateRangeOptions,
|
|
91
85
|
);
|
|
92
86
|
|
|
@@ -103,7 +97,6 @@ describe('computeInitialValues', () => {
|
|
|
103
97
|
dateFrom: initialDateFrom,
|
|
104
98
|
dateTo: initialDateTo,
|
|
105
99
|
},
|
|
106
|
-
earliestDate,
|
|
107
100
|
dateRangeOptions,
|
|
108
101
|
);
|
|
109
102
|
|
|
@@ -113,15 +106,11 @@ describe('computeInitialValues', () => {
|
|
|
113
106
|
});
|
|
114
107
|
|
|
115
108
|
it('should throw if initial "from" is not a valid date', () => {
|
|
116
|
-
expect(() => computeInitialValues({ dateFrom: 'not a date' },
|
|
117
|
-
'Invalid value.dateFrom',
|
|
118
|
-
);
|
|
109
|
+
expect(() => computeInitialValues({ dateFrom: 'not a date' }, [])).toThrowError('Invalid value.dateFrom');
|
|
119
110
|
});
|
|
120
111
|
|
|
121
112
|
it('should throw if initial "to" is not a valid date', () => {
|
|
122
|
-
expect(() => computeInitialValues({ dateTo: 'not a date' },
|
|
123
|
-
'Invalid value.dateTo',
|
|
124
|
-
);
|
|
113
|
+
expect(() => computeInitialValues({ dateTo: 'not a date' }, [])).toThrowError('Invalid value.dateTo');
|
|
125
114
|
});
|
|
126
115
|
|
|
127
116
|
function expectDateMatches(actual: Date | undefined, expected: Date | undefined) {
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { type DateRangeOption, type DateRangeValue } from './dateRangeOption';
|
|
2
|
-
import {
|
|
2
|
+
import { getSelectableOptions } from './selectableOptions';
|
|
3
3
|
import { UserFacingError } from '../components/error-display';
|
|
4
4
|
|
|
5
|
-
export function computeInitialValues(value: DateRangeValue,
|
|
5
|
+
export function computeInitialValues(value: DateRangeValue, dateRangeOptions: DateRangeOption[]) {
|
|
6
6
|
if (value === null) {
|
|
7
7
|
return undefined;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
if (typeof value === 'string') {
|
|
11
11
|
const selectableOptions = getSelectableOptions(dateRangeOptions);
|
|
12
|
-
const
|
|
12
|
+
const matchingOption = dateRangeOptions.find((option) => option.label === value);
|
|
13
13
|
|
|
14
|
-
if (
|
|
14
|
+
if (matchingOption === undefined) {
|
|
15
15
|
if (selectableOptions.length === 0) {
|
|
16
16
|
throw new UserFacingError('Invalid value', 'There are no selectable options, but value is set.');
|
|
17
17
|
}
|
|
@@ -21,34 +21,24 @@ export function computeInitialValues(value: DateRangeValue, earliestDate: string
|
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
const { dateFrom, dateTo } = getDatesForSelectorValue(initialSelectedDateRange, dateRangeOptions, earliestDate);
|
|
25
|
-
|
|
26
24
|
return {
|
|
27
|
-
initialSelectedDateRange,
|
|
28
|
-
initialSelectedDateFrom:
|
|
29
|
-
|
|
25
|
+
initialSelectedDateRange: matchingOption.label,
|
|
26
|
+
initialSelectedDateFrom:
|
|
27
|
+
matchingOption.dateFrom !== undefined ? new Date(matchingOption.dateFrom) : undefined,
|
|
28
|
+
initialSelectedDateTo: matchingOption.dateTo !== undefined ? new Date(matchingOption.dateTo) : undefined,
|
|
30
29
|
};
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
const { dateFrom, dateTo } = value;
|
|
34
33
|
|
|
35
|
-
const initialSelectedDateFrom =
|
|
36
|
-
let initialSelectedDateTo =
|
|
37
|
-
|
|
38
|
-
if (isNaN(initialSelectedDateFrom.getTime())) {
|
|
39
|
-
throw new UserFacingError(
|
|
40
|
-
'Invalid value.dateFrom',
|
|
41
|
-
`Invalid value.dateFrom "${dateFrom}", It must be of the format YYYY-MM-DD`,
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
if (isNaN(initialSelectedDateTo.getTime())) {
|
|
45
|
-
throw new UserFacingError(
|
|
46
|
-
'Invalid value.dateTo',
|
|
47
|
-
`Invalid value.dateTo "${dateTo}", It must be of the format YYYY-MM-DD`,
|
|
48
|
-
);
|
|
49
|
-
}
|
|
34
|
+
const initialSelectedDateFrom = parseMaybeDate(dateFrom, 'dateFrom');
|
|
35
|
+
let initialSelectedDateTo = parseMaybeDate(dateTo, 'dateTo');
|
|
50
36
|
|
|
51
|
-
if (
|
|
37
|
+
if (
|
|
38
|
+
initialSelectedDateFrom !== undefined &&
|
|
39
|
+
initialSelectedDateTo !== undefined &&
|
|
40
|
+
initialSelectedDateFrom > initialSelectedDateTo
|
|
41
|
+
) {
|
|
52
42
|
initialSelectedDateTo = initialSelectedDateFrom;
|
|
53
43
|
}
|
|
54
44
|
|
|
@@ -59,6 +49,18 @@ export function computeInitialValues(value: DateRangeValue, earliestDate: string
|
|
|
59
49
|
};
|
|
60
50
|
}
|
|
61
51
|
|
|
62
|
-
function
|
|
63
|
-
|
|
52
|
+
function parseMaybeDate(date: string | undefined, name: string): Date | undefined {
|
|
53
|
+
if (date === undefined || date === '') {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const parsedDate = new Date(date);
|
|
58
|
+
if (isNaN(parsedDate.getTime())) {
|
|
59
|
+
throw new UserFacingError(
|
|
60
|
+
`Invalid value.${name}`,
|
|
61
|
+
`Invalid value.${name} "${date}", it must be of the format YYYY-MM-DD`,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return parsedDate;
|
|
64
66
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type Meta, type PreactRenderer, type StoryObj } from '@storybook/preact';
|
|
2
2
|
import { expect, fn, userEvent, waitFor, within } from '@storybook/test';
|
|
3
3
|
import type { StepFunction } from '@storybook/types';
|
|
4
|
-
import dayjs from 'dayjs/esm';
|
|
5
4
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
|
6
5
|
|
|
7
6
|
import { DateRangeFilter, type DateRangeFilterProps } from './date-range-filter';
|
|
@@ -13,7 +12,9 @@ import { dateRangeOptionPresets, type DateRangeValue } from './dateRangeOption';
|
|
|
13
12
|
import { expectInvalidAttributesErrorMessage } from '../shared/stories/expectErrorMessage';
|
|
14
13
|
import { expectOptionSelected } from '../shared/stories/expectOptionSelected';
|
|
15
14
|
|
|
16
|
-
const
|
|
15
|
+
const allTimes = {
|
|
16
|
+
label: 'All times',
|
|
17
|
+
};
|
|
17
18
|
|
|
18
19
|
const customDateRange = {
|
|
19
20
|
label: 'CustomDateRange',
|
|
@@ -43,11 +44,6 @@ const meta: Meta<DateRangeFilterProps> = {
|
|
|
43
44
|
type: 'object',
|
|
44
45
|
},
|
|
45
46
|
},
|
|
46
|
-
earliestDate: {
|
|
47
|
-
control: {
|
|
48
|
-
type: 'text',
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
47
|
width: {
|
|
52
48
|
control: {
|
|
53
49
|
type: 'text',
|
|
@@ -55,8 +51,7 @@ const meta: Meta<DateRangeFilterProps> = {
|
|
|
55
51
|
},
|
|
56
52
|
},
|
|
57
53
|
args: {
|
|
58
|
-
dateRangeOptions: [dateRangeOptionPresets.lastMonth,
|
|
59
|
-
earliestDate,
|
|
54
|
+
dateRangeOptions: [dateRangeOptionPresets().lastMonth, allTimes, customDateRange],
|
|
60
55
|
value: null,
|
|
61
56
|
lapisDateField: 'aDateColumn',
|
|
62
57
|
width: '100%',
|
|
@@ -122,7 +117,7 @@ export const SetCorrectInitialDateFrom: StoryObj<DateRangeFilterProps> = {
|
|
|
122
117
|
await waitFor(async () => {
|
|
123
118
|
await expectOptionSelected(canvasElement, 'Custom');
|
|
124
119
|
await expect(dateFromPicker(canvas)).toHaveValue(initialDateFrom);
|
|
125
|
-
await expect(dateToPicker(canvas)).toHaveValue(
|
|
120
|
+
await expect(dateToPicker(canvas)).toHaveValue('');
|
|
126
121
|
});
|
|
127
122
|
},
|
|
128
123
|
};
|
|
@@ -140,7 +135,7 @@ export const SetCorrectInitialDateTo: StoryObj<DateRangeFilterProps> = {
|
|
|
140
135
|
|
|
141
136
|
await waitFor(async () => {
|
|
142
137
|
await expectOptionSelected(canvasElement, 'Custom');
|
|
143
|
-
await expect(dateFromPicker(canvas)).toHaveValue(
|
|
138
|
+
await expect(dateFromPicker(canvas)).toHaveValue('');
|
|
144
139
|
await expect(dateToPicker(canvas)).toHaveValue(initialDateTo);
|
|
145
140
|
});
|
|
146
141
|
},
|
|
@@ -150,7 +145,7 @@ export const SetsValueOnBlur: StoryObj<DateRangeFilterProps> = {
|
|
|
150
145
|
...Primary,
|
|
151
146
|
args: {
|
|
152
147
|
...Primary.args,
|
|
153
|
-
value: dateRangeOptionPresets.lastMonth.label,
|
|
148
|
+
value: dateRangeOptionPresets().lastMonth.label,
|
|
154
149
|
},
|
|
155
150
|
play: async ({ canvasElement, step }) => {
|
|
156
151
|
const { canvas, filterChangedListenerMock, optionChangedListenerMock } = await prepare(canvasElement, step);
|
|
@@ -173,7 +168,6 @@ export const SetsValueOnBlur: StoryObj<DateRangeFilterProps> = {
|
|
|
173
168
|
expect.objectContaining({
|
|
174
169
|
detail: {
|
|
175
170
|
aDateColumnFrom: '2000-01-01',
|
|
176
|
-
aDateColumnTo: dayjs().format('YYYY-MM-DD'),
|
|
177
171
|
},
|
|
178
172
|
}),
|
|
179
173
|
);
|
|
@@ -182,7 +176,6 @@ export const SetsValueOnBlur: StoryObj<DateRangeFilterProps> = {
|
|
|
182
176
|
expect.objectContaining({
|
|
183
177
|
detail: {
|
|
184
178
|
dateFrom: '2000-01-01',
|
|
185
|
-
dateTo: dayjs().format('YYYY-MM-DD'),
|
|
186
179
|
},
|
|
187
180
|
}),
|
|
188
181
|
);
|
|
@@ -211,7 +204,7 @@ export const ChangingTheValueProgrammatically: StoryObj<DateRangeFilterProps> =
|
|
|
211
204
|
<button className='btn' onClick={() => setValue(customDateRange.label)}>
|
|
212
205
|
Set to Custom
|
|
213
206
|
</button>
|
|
214
|
-
<button className='btn' onClick={() => setValue(dateRangeOptionPresets.lastMonth.label)}>
|
|
207
|
+
<button className='btn' onClick={() => setValue(dateRangeOptionPresets().lastMonth.label)}>
|
|
215
208
|
Set to Last month
|
|
216
209
|
</button>
|
|
217
210
|
</div>
|