@spaced-out/ui-design-system 0.4.7 → 0.4.9
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/CHANGELOG.md +14 -0
- package/lib/components/DateRangePicker/Calendar.js +3 -2
- package/lib/components/DateRangePicker/Calendar.js.flow +9 -2
- package/lib/components/DateRangePicker/DateRangePicker.js +8 -3
- package/lib/components/DateRangePicker/DateRangePicker.js.flow +7 -0
- package/lib/components/DateRangePicker/DateRangeWrapper.js +34 -18
- package/lib/components/DateRangePicker/DateRangeWrapper.js.flow +42 -15
- package/lib/types/date-range-picker.js +1 -3
- package/lib/types/date-range-picker.js.flow +3 -3
- package/lib/utils/date-range-picker/date-range-picker.js +56 -29
- package/lib/utils/date-range-picker/date-range-picker.js.flow +75 -24
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.4.9](https://github.com/spaced-out/ui-design-system/compare/v0.4.8...v0.4.9) (2025-07-24)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* menu virtualization ([#378](https://github.com/spaced-out/ui-design-system/issues/378)) ([8ba2f75](https://github.com/spaced-out/ui-design-system/commit/8ba2f754f60f1bd9635d37c4320da033d5257037))
|
|
11
|
+
|
|
12
|
+
### [0.4.8](https://github.com/spaced-out/ui-design-system/compare/v0.4.7...v0.4.8) (2025-07-24)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* localization in date range picker ([#377](https://github.com/spaced-out/ui-design-system/issues/377)) ([ae21b25](https://github.com/spaced-out/ui-design-system/commit/ae21b255c5f1a0122408000239eaf5c44abbd2b9))
|
|
18
|
+
|
|
5
19
|
### [0.4.7](https://github.com/spaced-out/ui-design-system/compare/v0.4.6...v0.4.7) (2025-07-24)
|
|
6
20
|
|
|
7
21
|
|
|
@@ -24,7 +24,8 @@ const Calendar = _ref => {
|
|
|
24
24
|
hoverDay,
|
|
25
25
|
dateRange,
|
|
26
26
|
inHoverRange,
|
|
27
|
-
today
|
|
27
|
+
today,
|
|
28
|
+
t
|
|
28
29
|
} = _ref;
|
|
29
30
|
return /*#__PURE__*/React.createElement("div", {
|
|
30
31
|
className: _CalendarModule.default.calendar
|
|
@@ -34,7 +35,7 @@ const Calendar = _ref => {
|
|
|
34
35
|
key: day,
|
|
35
36
|
className: _CalendarModule.default.calendarRowItem,
|
|
36
37
|
color: _Text.TEXT_COLORS.tertiary
|
|
37
|
-
}, day))), (0, _utils.getDaysInMonth)(value).map((week, index) => /*#__PURE__*/React.createElement("div", {
|
|
38
|
+
}, (0, _dateRangePicker.getTranslation)(t, day)))), (0, _utils.getDaysInMonth)(value).map((week, index) => /*#__PURE__*/React.createElement("div", {
|
|
38
39
|
key: week[index],
|
|
39
40
|
className: _CalendarModule.default.calendarRow
|
|
40
41
|
}, week.map(date => {
|
|
@@ -16,7 +16,12 @@ import {
|
|
|
16
16
|
NAVIGATION_ACTION,
|
|
17
17
|
WEEKDAYS,
|
|
18
18
|
} from '../../utils';
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
getTranslation,
|
|
21
|
+
isAfter,
|
|
22
|
+
isBefore,
|
|
23
|
+
isSame,
|
|
24
|
+
} from '../../utils/date-range-picker';
|
|
20
25
|
import {BodySmall, TEXT_COLORS} from '../Text';
|
|
21
26
|
|
|
22
27
|
import {Day} from './Day';
|
|
@@ -41,6 +46,7 @@ type CalendarProps = {
|
|
|
41
46
|
) => void,
|
|
42
47
|
},
|
|
43
48
|
today: string,
|
|
49
|
+
t: ?(key: string, fallback: string) => string,
|
|
44
50
|
};
|
|
45
51
|
|
|
46
52
|
export const Calendar = ({
|
|
@@ -53,6 +59,7 @@ export const Calendar = ({
|
|
|
53
59
|
dateRange,
|
|
54
60
|
inHoverRange,
|
|
55
61
|
today,
|
|
62
|
+
t,
|
|
56
63
|
}: CalendarProps): React.Node => (
|
|
57
64
|
<div className={css.calendar}>
|
|
58
65
|
<div className={css.calendarRow}>
|
|
@@ -62,7 +69,7 @@ export const Calendar = ({
|
|
|
62
69
|
className={css.calendarRowItem}
|
|
63
70
|
color={TEXT_COLORS.tertiary}
|
|
64
71
|
>
|
|
65
|
-
{day}
|
|
72
|
+
{getTranslation(t, day)}
|
|
66
73
|
</BodySmall>
|
|
67
74
|
))}
|
|
68
75
|
</div>
|
|
@@ -26,7 +26,9 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/React.forwardRef(
|
|
|
26
26
|
hideTimezone = false,
|
|
27
27
|
selectedDateRange = {},
|
|
28
28
|
startDateLabel,
|
|
29
|
-
endDateLabel
|
|
29
|
+
endDateLabel,
|
|
30
|
+
t,
|
|
31
|
+
locale
|
|
30
32
|
} = _ref;
|
|
31
33
|
const localTimezone = _momentTimezone.default.tz.guess();
|
|
32
34
|
const {
|
|
@@ -43,7 +45,8 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/React.forwardRef(
|
|
|
43
45
|
minDate,
|
|
44
46
|
maxDate,
|
|
45
47
|
today,
|
|
46
|
-
onError
|
|
48
|
+
onError,
|
|
49
|
+
t
|
|
47
50
|
}), [today]);
|
|
48
51
|
const {
|
|
49
52
|
startDate,
|
|
@@ -132,6 +135,8 @@ const DateRangePicker = exports.DateRangePicker = /*#__PURE__*/React.forwardRef(
|
|
|
132
135
|
cardWrapperClass: (0, _classify.default)(_DateRangePickerModule.default.container, classNames?.wrapper),
|
|
133
136
|
today: today,
|
|
134
137
|
startDateLabel: startDateLabel,
|
|
135
|
-
endDateLabel: endDateLabel
|
|
138
|
+
endDateLabel: endDateLabel,
|
|
139
|
+
t: t,
|
|
140
|
+
locale: locale
|
|
136
141
|
});
|
|
137
142
|
});
|
|
@@ -47,6 +47,8 @@ export type DateRangePickerProps = {
|
|
|
47
47
|
maxDate?: string,
|
|
48
48
|
startDateLabel?: string,
|
|
49
49
|
endDateLabel?: string,
|
|
50
|
+
t?: ?(key: string, fallback: string) => string,
|
|
51
|
+
locale?: string,
|
|
50
52
|
};
|
|
51
53
|
|
|
52
54
|
export const DateRangePicker: React$AbstractComponent<
|
|
@@ -65,6 +67,8 @@ export const DateRangePicker: React$AbstractComponent<
|
|
|
65
67
|
selectedDateRange = {},
|
|
66
68
|
startDateLabel,
|
|
67
69
|
endDateLabel,
|
|
70
|
+
t,
|
|
71
|
+
locale,
|
|
68
72
|
}: DateRangePickerProps,
|
|
69
73
|
ref,
|
|
70
74
|
): React.Node => {
|
|
@@ -87,6 +91,7 @@ export const DateRangePicker: React$AbstractComponent<
|
|
|
87
91
|
maxDate,
|
|
88
92
|
today,
|
|
89
93
|
onError,
|
|
94
|
+
t,
|
|
90
95
|
}),
|
|
91
96
|
[today],
|
|
92
97
|
);
|
|
@@ -201,6 +206,8 @@ export const DateRangePicker: React$AbstractComponent<
|
|
|
201
206
|
today={today}
|
|
202
207
|
startDateLabel={startDateLabel}
|
|
203
208
|
endDateLabel={endDateLabel}
|
|
209
|
+
t={t}
|
|
210
|
+
locale={locale}
|
|
204
211
|
/>
|
|
205
212
|
);
|
|
206
213
|
},
|
|
@@ -22,6 +22,7 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
22
22
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } // $FlowFixMe[untyped-import]
|
|
23
23
|
const CalendarHeader = _ref => {
|
|
24
24
|
let {
|
|
25
|
+
t,
|
|
25
26
|
date,
|
|
26
27
|
marker,
|
|
27
28
|
minDate,
|
|
@@ -46,12 +47,14 @@ const CalendarHeader = _ref => {
|
|
|
46
47
|
minDate,
|
|
47
48
|
maxDate,
|
|
48
49
|
rangeStartMonth,
|
|
49
|
-
rangeEndMonth
|
|
50
|
+
rangeEndMonth,
|
|
51
|
+
t
|
|
50
52
|
});
|
|
53
|
+
const MONTHS = (0, _utils.getMonths)(t);
|
|
51
54
|
return /*#__PURE__*/React.createElement("div", {
|
|
52
55
|
className: _DateRangeWrapperModule.default.calendarHeader
|
|
53
56
|
}, /*#__PURE__*/React.createElement(_Icon.ClickableIcon, {
|
|
54
|
-
ariaLabel:
|
|
57
|
+
ariaLabel: (0, _dateRangePicker.getTranslation)(t, 'Select Previous Month'),
|
|
55
58
|
size: "small",
|
|
56
59
|
name: "chevron-left",
|
|
57
60
|
className: (0, _classify.default)(_DateRangeWrapperModule.default.headerIcon, {
|
|
@@ -69,7 +72,7 @@ const CalendarHeader = _ref => {
|
|
|
69
72
|
onChange: event => {
|
|
70
73
|
setMonth((0, _utils.getMonthEndDate)(_moment.default.utc(date).set('M', event.key)));
|
|
71
74
|
},
|
|
72
|
-
dropdownInputText:
|
|
75
|
+
dropdownInputText: MONTHS[_moment.default.utc(date).month()].label,
|
|
73
76
|
scrollMenuToBottom: true
|
|
74
77
|
}), /*#__PURE__*/React.createElement(_Dropdown.Dropdown, {
|
|
75
78
|
disabled: !availableYears.length || (0, _dateRangePicker.isAfter)(minDate, maxDate),
|
|
@@ -85,7 +88,7 @@ const CalendarHeader = _ref => {
|
|
|
85
88
|
scrollMenuToBottom: true
|
|
86
89
|
}), /*#__PURE__*/React.createElement(_Icon.ClickableIcon, {
|
|
87
90
|
size: "small",
|
|
88
|
-
ariaLabel:
|
|
91
|
+
ariaLabel: (0, _dateRangePicker.getTranslation)(t, 'Select Next Month'),
|
|
89
92
|
name: "chevron-right",
|
|
90
93
|
className: (0, _classify.default)(_DateRangeWrapperModule.default.headerIcon, {
|
|
91
94
|
[_DateRangeWrapperModule.default.disabledIcon]: nextDisabled
|
|
@@ -114,7 +117,9 @@ const DateRangeWrapper = exports.DateRangeWrapper = /*#__PURE__*/React.forwardRe
|
|
|
114
117
|
hideTimezone,
|
|
115
118
|
today,
|
|
116
119
|
startDateLabel,
|
|
117
|
-
endDateLabel
|
|
120
|
+
endDateLabel,
|
|
121
|
+
t,
|
|
122
|
+
locale
|
|
118
123
|
} = _ref2;
|
|
119
124
|
const canNavigateCloser = _moment.default.utc(rangeStartMonth).year() !== _moment.default.utc(rangeEndMonth).year() || Math.abs(_moment.default.utc(rangeStartMonth).month() - _moment.default.utc(rangeEndMonth).month()) > 1;
|
|
120
125
|
const handleApplyClick = () => {
|
|
@@ -142,7 +147,8 @@ const DateRangeWrapper = exports.DateRangeWrapper = /*#__PURE__*/React.forwardRe
|
|
|
142
147
|
dateRange,
|
|
143
148
|
minDate,
|
|
144
149
|
maxDate,
|
|
145
|
-
today
|
|
150
|
+
today,
|
|
151
|
+
t
|
|
146
152
|
};
|
|
147
153
|
return /*#__PURE__*/React.createElement(_FocusManager.FocusManager, null, /*#__PURE__*/React.createElement(_Card.Card, {
|
|
148
154
|
classNames: {
|
|
@@ -154,7 +160,7 @@ const DateRangeWrapper = exports.DateRangeWrapper = /*#__PURE__*/React.forwardRe
|
|
|
154
160
|
}, /*#__PURE__*/React.createElement(_Text.BodySmall, {
|
|
155
161
|
className: _DateRangeWrapperModule.default.selectedDate,
|
|
156
162
|
color: _Text.TEXT_COLORS.secondary
|
|
157
|
-
}, `${startDateLabel || 'Start Date'}: ${(0, _dateRangePicker.getFormattedDate)(_utils.MARKERS.DATE_RANGE_START, dateRange)}`), /*#__PURE__*/React.createElement(_Icon.Icon, {
|
|
163
|
+
}, `${startDateLabel || (0, _dateRangePicker.getTranslation)(t, 'Start Date')}: ${(0, _dateRangePicker.getFormattedDate)(_utils.MARKERS.DATE_RANGE_START, dateRange, locale)}`), /*#__PURE__*/React.createElement(_Icon.Icon, {
|
|
158
164
|
name: "minus",
|
|
159
165
|
size: _Icon.ICON_SIZE.small,
|
|
160
166
|
type: _Icon.ICON_TYPE.regular,
|
|
@@ -162,9 +168,10 @@ const DateRangeWrapper = exports.DateRangeWrapper = /*#__PURE__*/React.forwardRe
|
|
|
162
168
|
}), /*#__PURE__*/React.createElement(_Text.BodySmall, {
|
|
163
169
|
className: _DateRangeWrapperModule.default.selectedDate,
|
|
164
170
|
color: _Text.TEXT_COLORS.secondary
|
|
165
|
-
}, `${endDateLabel || 'End Date'}: ${(0, _dateRangePicker.getFormattedDate)(_utils.MARKERS.DATE_RANGE_END, dateRange)}`)), /*#__PURE__*/React.createElement("div", {
|
|
171
|
+
}, `${endDateLabel || (0, _dateRangePicker.getTranslation)(t, 'End Date')}: ${(0, _dateRangePicker.getFormattedDate)(_utils.MARKERS.DATE_RANGE_END, dateRange, locale)}`)), /*#__PURE__*/React.createElement("div", {
|
|
166
172
|
className: _DateRangeWrapperModule.default.calendarMenuContainer
|
|
167
173
|
}, /*#__PURE__*/React.createElement(CalendarHeader, {
|
|
174
|
+
t: t,
|
|
168
175
|
marker: _utils.MARKERS.DATE_RANGE_START,
|
|
169
176
|
rangeStartMonth: rangeStartMonth,
|
|
170
177
|
rangeEndMonth: rangeEndMonth,
|
|
@@ -177,6 +184,7 @@ const DateRangeWrapper = exports.DateRangeWrapper = /*#__PURE__*/React.forwardRe
|
|
|
177
184
|
onClickNext: () => onMonthNavigate(_utils.MARKERS.DATE_RANGE_START, _utils.NAVIGATION_ACTION.NEXT),
|
|
178
185
|
onClickPrevious: () => onMonthNavigate(_utils.MARKERS.DATE_RANGE_START, _utils.NAVIGATION_ACTION.PREV)
|
|
179
186
|
}), /*#__PURE__*/React.createElement(CalendarHeader, {
|
|
187
|
+
t: t,
|
|
180
188
|
marker: _utils.MARKERS.DATE_RANGE_END,
|
|
181
189
|
rangeStartMonth: rangeStartMonth,
|
|
182
190
|
rangeEndMonth: rangeEndMonth,
|
|
@@ -202,26 +210,34 @@ const DateRangeWrapper = exports.DateRangeWrapper = /*#__PURE__*/React.forwardRe
|
|
|
202
210
|
className: _DateRangeWrapperModule.default.cardFooter
|
|
203
211
|
}, /*#__PURE__*/React.createElement(_Card.CardTitle, {
|
|
204
212
|
className: _DateRangeWrapperModule.default.timezoneDropdownContainer
|
|
205
|
-
}, !hideTimezone && /*#__PURE__*/React.createElement(_Dropdown.
|
|
206
|
-
|
|
213
|
+
}, !hideTimezone && /*#__PURE__*/React.createElement(_Dropdown.Dropdown, {
|
|
214
|
+
menu: {
|
|
215
|
+
selectedKeys: [timezone],
|
|
216
|
+
options: (0, _utils.getTimezones)(t),
|
|
217
|
+
allowSearch: true,
|
|
218
|
+
virtualization: {
|
|
219
|
+
enable: true
|
|
220
|
+
},
|
|
221
|
+
staticLabels: {
|
|
222
|
+
SEARCH_PLACEHOLDER: `${(0, _dateRangePicker.getTranslation)(t, 'Search')}...`,
|
|
223
|
+
RESULT: (0, _dateRangePicker.getTranslation)(t, 'result'),
|
|
224
|
+
RESULTS: (0, _dateRangePicker.getTranslation)(t, 'results')
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
dropdownInputText: (0, _dateRangePicker.getTranslation)(t, _dateRangePicker.TIMEZONES[timezone]),
|
|
207
228
|
disabled: (0, _dateRangePicker.isAfter)(minDate, maxDate),
|
|
208
229
|
classNames: {
|
|
209
230
|
box: _DateRangeWrapperModule.default.timezoneDropdown
|
|
210
231
|
},
|
|
211
|
-
selectedKeys: [timezone],
|
|
212
232
|
onChange: event => setTimezone(event.key),
|
|
213
|
-
size: "small"
|
|
214
|
-
menuVirtualization: {
|
|
215
|
-
enable: true
|
|
216
|
-
},
|
|
217
|
-
allowSearch: true
|
|
233
|
+
size: "small"
|
|
218
234
|
})), /*#__PURE__*/React.createElement(_Card.CardActions, null, /*#__PURE__*/React.createElement(_Button.Button, {
|
|
219
235
|
type: "ghost",
|
|
220
236
|
onClick: onCancel,
|
|
221
237
|
size: "small"
|
|
222
|
-
},
|
|
238
|
+
}, (0, _dateRangePicker.getTranslation)(t, 'Cancel')), /*#__PURE__*/React.createElement(_Button.Button, {
|
|
223
239
|
onClick: handleApplyClick,
|
|
224
240
|
size: "small",
|
|
225
241
|
disabled: !(dateRange.startDate && dateRange.endDate)
|
|
226
|
-
},
|
|
242
|
+
}, (0, _dateRangePicker.getTranslation)(t, 'Apply'))))));
|
|
227
243
|
});
|
|
@@ -9,9 +9,9 @@ import {
|
|
|
9
9
|
generateAvailableYears,
|
|
10
10
|
getAvailableMonths,
|
|
11
11
|
getMonthEndDate,
|
|
12
|
+
getMonths,
|
|
12
13
|
getTimezones,
|
|
13
14
|
MARKERS,
|
|
14
|
-
MONTHS,
|
|
15
15
|
NAVIGATION_ACTION,
|
|
16
16
|
} from '../../utils';
|
|
17
17
|
import classify from '../../utils/classify';
|
|
@@ -19,9 +19,11 @@ import {
|
|
|
19
19
|
addTimezoneEndOfDay,
|
|
20
20
|
addTimezoneStartOfDay,
|
|
21
21
|
getFormattedDate,
|
|
22
|
+
getTranslation,
|
|
22
23
|
isAfter,
|
|
23
24
|
isSameOrAfter,
|
|
24
25
|
isSameOrBefore,
|
|
26
|
+
TIMEZONES,
|
|
25
27
|
} from '../../utils/date-range-picker';
|
|
26
28
|
import {Button} from '../Button';
|
|
27
29
|
import {
|
|
@@ -32,7 +34,7 @@ import {
|
|
|
32
34
|
CardHeader,
|
|
33
35
|
CardTitle,
|
|
34
36
|
} from '../Card';
|
|
35
|
-
import {Dropdown
|
|
37
|
+
import {Dropdown} from '../Dropdown';
|
|
36
38
|
import {FocusManager} from '../FocusManager';
|
|
37
39
|
import {ClickableIcon, Icon, ICON_SIZE, ICON_TYPE} from '../Icon';
|
|
38
40
|
import {BodySmall, TEXT_COLORS} from '../Text';
|
|
@@ -54,6 +56,7 @@ type HeaderProps = {
|
|
|
54
56
|
onClickPrevious: () => void,
|
|
55
57
|
marker: $Values<typeof MARKERS>,
|
|
56
58
|
setMonth: (date: string) => void,
|
|
59
|
+
t: ?(key: string, fallback: string) => string,
|
|
57
60
|
};
|
|
58
61
|
|
|
59
62
|
type DateRangeWrapperProps = {
|
|
@@ -83,9 +86,12 @@ type DateRangeWrapperProps = {
|
|
|
83
86
|
today: string,
|
|
84
87
|
startDateLabel?: string,
|
|
85
88
|
endDateLabel?: string,
|
|
89
|
+
t?: ?(key: string, fallback: string) => string,
|
|
90
|
+
locale?: string,
|
|
86
91
|
};
|
|
87
92
|
|
|
88
93
|
const CalendarHeader = ({
|
|
94
|
+
t,
|
|
89
95
|
date,
|
|
90
96
|
marker,
|
|
91
97
|
minDate,
|
|
@@ -111,12 +117,14 @@ const CalendarHeader = ({
|
|
|
111
117
|
maxDate,
|
|
112
118
|
rangeStartMonth,
|
|
113
119
|
rangeEndMonth,
|
|
120
|
+
t,
|
|
114
121
|
});
|
|
122
|
+
const MONTHS = getMonths(t);
|
|
115
123
|
|
|
116
124
|
return (
|
|
117
125
|
<div className={css.calendarHeader}>
|
|
118
126
|
<ClickableIcon
|
|
119
|
-
ariaLabel=
|
|
127
|
+
ariaLabel={getTranslation(t, 'Select Previous Month')}
|
|
120
128
|
size="small"
|
|
121
129
|
name="chevron-left"
|
|
122
130
|
className={classify(css.headerIcon, {
|
|
@@ -153,7 +161,7 @@ const CalendarHeader = ({
|
|
|
153
161
|
/>
|
|
154
162
|
<ClickableIcon
|
|
155
163
|
size="small"
|
|
156
|
-
ariaLabel=
|
|
164
|
+
ariaLabel={getTranslation(t, 'Select Next Month')}
|
|
157
165
|
name="chevron-right"
|
|
158
166
|
className={classify(css.headerIcon, {
|
|
159
167
|
[css.disabledIcon]: nextDisabled,
|
|
@@ -190,6 +198,8 @@ export const DateRangeWrapper: React$AbstractComponent<
|
|
|
190
198
|
today,
|
|
191
199
|
startDateLabel,
|
|
192
200
|
endDateLabel,
|
|
201
|
+
t,
|
|
202
|
+
locale,
|
|
193
203
|
}: DateRangeWrapperProps,
|
|
194
204
|
ref,
|
|
195
205
|
): React.Node => {
|
|
@@ -223,6 +233,7 @@ export const DateRangeWrapper: React$AbstractComponent<
|
|
|
223
233
|
minDate,
|
|
224
234
|
maxDate,
|
|
225
235
|
today,
|
|
236
|
+
t,
|
|
226
237
|
};
|
|
227
238
|
|
|
228
239
|
return (
|
|
@@ -238,9 +249,12 @@ export const DateRangeWrapper: React$AbstractComponent<
|
|
|
238
249
|
className={css.selectedDate}
|
|
239
250
|
color={TEXT_COLORS.secondary}
|
|
240
251
|
>
|
|
241
|
-
{`${
|
|
252
|
+
{`${
|
|
253
|
+
startDateLabel || getTranslation(t, 'Start Date')
|
|
254
|
+
}: ${getFormattedDate(
|
|
242
255
|
MARKERS.DATE_RANGE_START,
|
|
243
256
|
dateRange,
|
|
257
|
+
locale,
|
|
244
258
|
)}`}
|
|
245
259
|
</BodySmall>
|
|
246
260
|
|
|
@@ -255,15 +269,19 @@ export const DateRangeWrapper: React$AbstractComponent<
|
|
|
255
269
|
className={css.selectedDate}
|
|
256
270
|
color={TEXT_COLORS.secondary}
|
|
257
271
|
>
|
|
258
|
-
{`${
|
|
272
|
+
{`${
|
|
273
|
+
endDateLabel || getTranslation(t, 'End Date')
|
|
274
|
+
}: ${getFormattedDate(
|
|
259
275
|
MARKERS.DATE_RANGE_END,
|
|
260
276
|
dateRange,
|
|
277
|
+
locale,
|
|
261
278
|
)}`}
|
|
262
279
|
</BodySmall>
|
|
263
280
|
</CardHeader>
|
|
264
281
|
|
|
265
282
|
<div className={css.calendarMenuContainer}>
|
|
266
283
|
<CalendarHeader
|
|
284
|
+
t={t}
|
|
267
285
|
marker={MARKERS.DATE_RANGE_START}
|
|
268
286
|
rangeStartMonth={rangeStartMonth}
|
|
269
287
|
rangeEndMonth={rangeEndMonth}
|
|
@@ -287,6 +305,7 @@ export const DateRangeWrapper: React$AbstractComponent<
|
|
|
287
305
|
}
|
|
288
306
|
/>
|
|
289
307
|
<CalendarHeader
|
|
308
|
+
t={t}
|
|
290
309
|
marker={MARKERS.DATE_RANGE_END}
|
|
291
310
|
rangeStartMonth={rangeStartMonth}
|
|
292
311
|
rangeEndMonth={rangeEndMonth}
|
|
@@ -321,32 +340,40 @@ export const DateRangeWrapper: React$AbstractComponent<
|
|
|
321
340
|
<CardFooter className={css.cardFooter}>
|
|
322
341
|
<CardTitle className={css.timezoneDropdownContainer}>
|
|
323
342
|
{!hideTimezone && (
|
|
324
|
-
<
|
|
325
|
-
|
|
343
|
+
<Dropdown
|
|
344
|
+
menu={{
|
|
345
|
+
selectedKeys: [timezone],
|
|
346
|
+
options: getTimezones(t),
|
|
347
|
+
allowSearch: true,
|
|
348
|
+
virtualization: {
|
|
349
|
+
enable: true,
|
|
350
|
+
},
|
|
351
|
+
staticLabels: {
|
|
352
|
+
SEARCH_PLACEHOLDER: `${getTranslation(t, 'Search')}...`,
|
|
353
|
+
RESULT: getTranslation(t, 'result'),
|
|
354
|
+
RESULTS: getTranslation(t, 'results'),
|
|
355
|
+
},
|
|
356
|
+
}}
|
|
357
|
+
dropdownInputText={getTranslation(t, TIMEZONES[timezone])}
|
|
326
358
|
disabled={isAfter(minDate, maxDate)}
|
|
327
359
|
classNames={{
|
|
328
360
|
box: css.timezoneDropdown,
|
|
329
361
|
}}
|
|
330
|
-
selectedKeys={[timezone]}
|
|
331
362
|
onChange={(event) => setTimezone(event.key)}
|
|
332
363
|
size="small"
|
|
333
|
-
menuVirtualization={{
|
|
334
|
-
enable: true,
|
|
335
|
-
}}
|
|
336
|
-
allowSearch
|
|
337
364
|
/>
|
|
338
365
|
)}
|
|
339
366
|
</CardTitle>
|
|
340
367
|
<CardActions>
|
|
341
368
|
<Button type="ghost" onClick={onCancel} size="small">
|
|
342
|
-
Cancel
|
|
369
|
+
{getTranslation(t, 'Cancel')}
|
|
343
370
|
</Button>
|
|
344
371
|
<Button
|
|
345
372
|
onClick={handleApplyClick}
|
|
346
373
|
size="small"
|
|
347
374
|
disabled={!(dateRange.startDate && dateRange.endDate)}
|
|
348
375
|
>
|
|
349
|
-
Apply
|
|
376
|
+
{getTranslation(t, 'Apply')}
|
|
350
377
|
</Button>
|
|
351
378
|
</CardActions>
|
|
352
379
|
</CardFooter>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// @flow strict
|
|
2
|
-
import {DATE_RANGE_PICKER_ERRORS} from '../utils/date-range-picker';
|
|
3
|
-
|
|
4
2
|
|
|
5
3
|
export type TimeUnit = 'years' | 'months' | 'days' | 'd' | 'M' | 'y';
|
|
6
4
|
export type DateRange = {startDate?: ?string, endDate?: ?string};
|
|
7
|
-
export type DateRangePickerErrorTypes =
|
|
5
|
+
export type DateRangePickerErrorTypes = {
|
|
6
|
+
[key: string]: {type: string, description: string},
|
|
7
|
+
};
|
|
8
8
|
export type DateRangePickerError = {
|
|
9
9
|
type: string,
|
|
10
10
|
description: string,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.wrangleMoment = exports.isValid = exports.isStartOfRange = exports.isStartDateEndDateSame = exports.isSameOrBefore = exports.isSameOrAfter = exports.isSame = exports.isEndOfRange = exports.isBetween = exports.isBefore = exports.isAfter = exports.inDateRange = exports.getValidDates = exports.getTimezones = exports.getSubtractedDate = exports.getMonthEndDate = exports.getFormattedDate = exports.getDaysInMonth = exports.getAvailableMonths = exports.getAddedDate = exports.generateAvailableYears = exports.formatIsoDate = exports.checkRangeValidity = exports.WEEKDAYS = exports.NAVIGATION_ACTION = exports.
|
|
6
|
+
exports.wrangleMoment = exports.makeKey = exports.isValid = exports.isStartOfRange = exports.isStartDateEndDateSame = exports.isSameOrBefore = exports.isSameOrAfter = exports.isSame = exports.isEndOfRange = exports.isBetween = exports.isBefore = exports.isAfter = exports.inDateRange = exports.getValidDates = exports.getTranslation = exports.getTimezones = exports.getSubtractedDate = exports.getMonths = exports.getMonthEndDate = exports.getFormattedDate = exports.getDaysInMonth = exports.getDateRangePickerErrors = exports.getAvailableMonths = exports.getAddedDate = exports.generateAvailableYears = exports.formatIsoDate = exports.checkRangeValidity = exports.WEEKDAYS = exports.NAVIGATION_ACTION = exports.MARKERS = void 0;
|
|
7
7
|
var _parseISO = _interopRequireDefault(require("date-fns/parseISO"));
|
|
8
8
|
var _invariant = _interopRequireDefault(require("invariant"));
|
|
9
9
|
var _lodash = require("lodash");
|
|
@@ -12,6 +12,21 @@ var _timezones = require("./timezones");
|
|
|
12
12
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
13
|
// $FlowFixMe - strict types for date-fns
|
|
14
14
|
// $FlowFixMe[untyped-import]
|
|
15
|
+
const makeKey = value => {
|
|
16
|
+
try {
|
|
17
|
+
if (value && typeof value === 'string') {
|
|
18
|
+
return value.replace(/\(s\)/gi, '_s') // Replace (s) with _s (case-insensitive)
|
|
19
|
+
.replace(/[^\w\s']/g, '') // Remove special chars except apostrophes
|
|
20
|
+
.replace(/\s+/g, '_') // Spaces → underscores
|
|
21
|
+
.replace(/_+/g, '_') // Collapse multiple ____ into _
|
|
22
|
+
.replace(/^_|_$/g, ''); // Trim leading/trailing _
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
} catch {
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
exports.makeKey = makeKey;
|
|
15
30
|
const NAVIGATION_ACTION = exports.NAVIGATION_ACTION = Object.freeze({
|
|
16
31
|
NEXT: 'next',
|
|
17
32
|
PREV: 'prev'
|
|
@@ -21,61 +36,63 @@ const MARKERS = exports.MARKERS = Object.freeze({
|
|
|
21
36
|
DATE_RANGE_END: 'SECOND'
|
|
22
37
|
});
|
|
23
38
|
const WEEKDAYS = exports.WEEKDAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
|
|
24
|
-
const
|
|
39
|
+
const getMonths = t => [{
|
|
25
40
|
key: '0',
|
|
26
|
-
label: 'Jan'
|
|
41
|
+
label: getTranslation(t, 'Jan')
|
|
27
42
|
}, {
|
|
28
43
|
key: '1',
|
|
29
|
-
label: 'Feb'
|
|
44
|
+
label: getTranslation(t, 'Feb')
|
|
30
45
|
}, {
|
|
31
46
|
key: '2',
|
|
32
|
-
label: 'Mar'
|
|
47
|
+
label: getTranslation(t, 'Mar')
|
|
33
48
|
}, {
|
|
34
49
|
key: '3',
|
|
35
|
-
label: 'Apr'
|
|
50
|
+
label: getTranslation(t, 'Apr')
|
|
36
51
|
}, {
|
|
37
52
|
key: '4',
|
|
38
|
-
label: 'May'
|
|
53
|
+
label: getTranslation(t, 'May')
|
|
39
54
|
}, {
|
|
40
55
|
key: '5',
|
|
41
|
-
label: 'Jun'
|
|
56
|
+
label: getTranslation(t, 'Jun')
|
|
42
57
|
}, {
|
|
43
58
|
key: '6',
|
|
44
|
-
label: 'Jul'
|
|
59
|
+
label: getTranslation(t, 'Jul')
|
|
45
60
|
}, {
|
|
46
61
|
key: '7',
|
|
47
|
-
label: 'Aug'
|
|
62
|
+
label: getTranslation(t, 'Aug')
|
|
48
63
|
}, {
|
|
49
64
|
key: '8',
|
|
50
|
-
label: 'Sep'
|
|
65
|
+
label: getTranslation(t, 'Sep')
|
|
51
66
|
}, {
|
|
52
67
|
key: '9',
|
|
53
|
-
label: 'Oct'
|
|
68
|
+
label: getTranslation(t, 'Oct')
|
|
54
69
|
}, {
|
|
55
70
|
key: '10',
|
|
56
|
-
label: 'Nov'
|
|
71
|
+
label: getTranslation(t, 'Nov')
|
|
57
72
|
}, {
|
|
58
73
|
key: '11',
|
|
59
|
-
label: 'Dec'
|
|
74
|
+
label: getTranslation(t, 'Dec')
|
|
60
75
|
}];
|
|
61
|
-
|
|
76
|
+
exports.getMonths = getMonths;
|
|
77
|
+
const getDateRangePickerErrors = t => ({
|
|
62
78
|
MIN_MAX_INVALID: {
|
|
63
79
|
type: 'MIN_MAX_INVALID',
|
|
64
|
-
description: 'Given minDate and maxDate are invalid.'
|
|
80
|
+
description: getTranslation(t, 'Given minDate and maxDate are invalid.')
|
|
65
81
|
},
|
|
66
82
|
START_DATE_EARLY: {
|
|
67
83
|
type: 'START_DATE_EARLY',
|
|
68
|
-
description: 'Given startDate can not come before minDate.'
|
|
84
|
+
description: getTranslation(t, 'Given startDate can not come before minDate.')
|
|
69
85
|
},
|
|
70
86
|
START_DATE_LATE: {
|
|
71
87
|
type: 'START_DATE_LATE',
|
|
72
|
-
description: 'Given startDate can not come after endDate.'
|
|
88
|
+
description: getTranslation(t, 'Given startDate can not come after endDate.')
|
|
73
89
|
},
|
|
74
90
|
END_DATE_LATE: {
|
|
75
91
|
type: 'END_DATE_LATE',
|
|
76
|
-
description: 'Given endDate can not come after maxDate.'
|
|
92
|
+
description: getTranslation(t, 'Given endDate can not come after maxDate.')
|
|
77
93
|
}
|
|
78
94
|
});
|
|
95
|
+
exports.getDateRangePickerErrors = getDateRangePickerErrors;
|
|
79
96
|
const checkRangeValidity = (rangeStart, rangeEnd, errorBody, onError) => {
|
|
80
97
|
const isRangeStartValid = isValid(rangeStart);
|
|
81
98
|
const isRangeEndValid = isRangeStartValid && isValid(rangeEnd);
|
|
@@ -174,10 +191,10 @@ const getSubtractedDate = (date, subtractCount, timeUnit) => formatIsoDate(_mome
|
|
|
174
191
|
exports.getSubtractedDate = getSubtractedDate;
|
|
175
192
|
const getMonthEndDate = date => formatIsoDate(_moment.default.utc(date).endOf('M'));
|
|
176
193
|
exports.getMonthEndDate = getMonthEndDate;
|
|
177
|
-
const getTimezones =
|
|
194
|
+
const getTimezones = t => Object.keys(_timezones.TIMEZONES).reduce((menuOptions, key) => {
|
|
178
195
|
menuOptions.push({
|
|
179
196
|
key,
|
|
180
|
-
label: _timezones.TIMEZONES[key]
|
|
197
|
+
label: getTranslation(t, _timezones.TIMEZONES[key])
|
|
181
198
|
});
|
|
182
199
|
return menuOptions;
|
|
183
200
|
}, []);
|
|
@@ -205,12 +222,14 @@ const getAvailableMonths = _ref6 => {
|
|
|
205
222
|
minDate,
|
|
206
223
|
maxDate,
|
|
207
224
|
rangeStartMonth,
|
|
208
|
-
rangeEndMonth
|
|
225
|
+
rangeEndMonth,
|
|
226
|
+
t
|
|
209
227
|
} = _ref6;
|
|
210
228
|
const [rangeStartMonthKey, rangeStartYear] = getMonthAndYear(rangeStartMonth);
|
|
211
229
|
const [rangeEndMonthKey, rangeEndYear] = getMonthAndYear(rangeEndMonth);
|
|
212
230
|
const [minDateMonth, minDateYear] = getMonthAndYear(minDate);
|
|
213
231
|
const [maxDateMonth, maxDateYear] = getMonthAndYear(maxDate);
|
|
232
|
+
const MONTHS = getMonths(t);
|
|
214
233
|
return MONTHS.filter(month => {
|
|
215
234
|
const isSameYear = rangeStartYear === rangeEndYear;
|
|
216
235
|
const isFirstAndMinDateYearSame = rangeStartYear === minDateYear;
|
|
@@ -241,7 +260,8 @@ const getValidDates = _ref7 => {
|
|
|
241
260
|
minDate,
|
|
242
261
|
maxDate,
|
|
243
262
|
today,
|
|
244
|
-
onError
|
|
263
|
+
onError,
|
|
264
|
+
t
|
|
245
265
|
} = _ref7;
|
|
246
266
|
const {
|
|
247
267
|
startDate,
|
|
@@ -252,10 +272,10 @@ const getValidDates = _ref7 => {
|
|
|
252
272
|
const isRangeValid = (min, max, errorMessage) => checkRangeValidity(min, max, errorMessage, onError);
|
|
253
273
|
|
|
254
274
|
// minDate should be after maxDate
|
|
255
|
-
const isMinMaxRangeInvalid = !isRangeValid(validMinDate, validMaxDate,
|
|
275
|
+
const isMinMaxRangeInvalid = !isRangeValid(validMinDate, validMaxDate, getDateRangePickerErrors(t).MIN_MAX_INVALID);
|
|
256
276
|
|
|
257
277
|
// if startDate is defined and then it should be after minDate
|
|
258
|
-
const isStartDateInvalid = isMinMaxRangeInvalid || (0, _lodash.isEmpty)(startDate) || !isRangeValid(validMinDate, startDate,
|
|
278
|
+
const isStartDateInvalid = isMinMaxRangeInvalid || (0, _lodash.isEmpty)(startDate) || !isRangeValid(validMinDate, startDate, getDateRangePickerErrors(t).START_DATE_EARLY);
|
|
259
279
|
if (isMinMaxRangeInvalid || isStartDateInvalid) {
|
|
260
280
|
return {
|
|
261
281
|
validDateRange: {
|
|
@@ -267,10 +287,10 @@ const getValidDates = _ref7 => {
|
|
|
267
287
|
};
|
|
268
288
|
}
|
|
269
289
|
// if endDate is defined then it should be before maxDate
|
|
270
|
-
const isEndDateInvalid = (0, _lodash.isEmpty)(endDate) || !isRangeValid(endDate, validMaxDate,
|
|
290
|
+
const isEndDateInvalid = (0, _lodash.isEmpty)(endDate) || !isRangeValid(endDate, validMaxDate, getDateRangePickerErrors(t).END_DATE_LATE);
|
|
271
291
|
|
|
272
292
|
// startDate should be before endDate
|
|
273
|
-
const isStartEndRangeInvalid = isEndDateInvalid || !isRangeValid(startDate, endDate,
|
|
293
|
+
const isStartEndRangeInvalid = isEndDateInvalid || !isRangeValid(startDate, endDate, getDateRangePickerErrors(t).START_DATE_LATE);
|
|
274
294
|
if (isEndDateInvalid || isStartEndRangeInvalid) {
|
|
275
295
|
return {
|
|
276
296
|
validDateRange: {
|
|
@@ -319,11 +339,16 @@ const isBetween = (date, startRange, endRange) => _moment.default.utc(date).isBe
|
|
|
319
339
|
exports.isBetween = isBetween;
|
|
320
340
|
const isValid = date => _moment.default.utc(date).isValid();
|
|
321
341
|
exports.isValid = isValid;
|
|
322
|
-
const getFormattedDate = (marker, dateRange) => {
|
|
342
|
+
const getFormattedDate = (marker, dateRange, locale) => {
|
|
323
343
|
const {
|
|
324
344
|
startDate,
|
|
325
345
|
endDate
|
|
326
346
|
} = dateRange;
|
|
347
|
+
|
|
348
|
+
// set locale if provided
|
|
349
|
+
if (locale) {
|
|
350
|
+
_moment.default.locale(locale);
|
|
351
|
+
}
|
|
327
352
|
switch (marker) {
|
|
328
353
|
case MARKERS.DATE_RANGE_START:
|
|
329
354
|
return startDate ? _moment.default.utc(startDate).format('MMM DD, YYYY') : 'MMM DD, YYYY';
|
|
@@ -331,4 +356,6 @@ const getFormattedDate = (marker, dateRange) => {
|
|
|
331
356
|
return endDate ? _moment.default.utc(endDate).format('MMM DD, YYYY') : 'MMM DD, YYYY';
|
|
332
357
|
}
|
|
333
358
|
};
|
|
334
|
-
exports.getFormattedDate = getFormattedDate;
|
|
359
|
+
exports.getFormattedDate = getFormattedDate;
|
|
360
|
+
const getTranslation = (t, labelToTranslate) => t ? t(makeKey(labelToTranslate), labelToTranslate) : labelToTranslate;
|
|
361
|
+
exports.getTranslation = getTranslation;
|
|
@@ -9,6 +9,7 @@ import moment from 'moment';
|
|
|
9
9
|
import type {
|
|
10
10
|
DateRange,
|
|
11
11
|
DateRangePickerError,
|
|
12
|
+
DateRangePickerErrorTypes,
|
|
12
13
|
DateRangeWithTimezone,
|
|
13
14
|
TimeUnit,
|
|
14
15
|
} from 'src/types/date-range-picker';
|
|
@@ -18,6 +19,22 @@ import type {MenuOption} from '../../components/Menu';
|
|
|
18
19
|
import {TIMEZONES} from './timezones';
|
|
19
20
|
|
|
20
21
|
|
|
22
|
+
export const makeKey = (value: string): string => {
|
|
23
|
+
try {
|
|
24
|
+
if (value && typeof value === 'string') {
|
|
25
|
+
return value
|
|
26
|
+
.replace(/\(s\)/gi, '_s') // Replace (s) with _s (case-insensitive)
|
|
27
|
+
.replace(/[^\w\s']/g, '') // Remove special chars except apostrophes
|
|
28
|
+
.replace(/\s+/g, '_') // Spaces → underscores
|
|
29
|
+
.replace(/_+/g, '_') // Collapse multiple ____ into _
|
|
30
|
+
.replace(/^_|_$/g, ''); // Trim leading/trailing _
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
} catch {
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
21
38
|
export const NAVIGATION_ACTION = Object.freeze({
|
|
22
39
|
NEXT: 'next',
|
|
23
40
|
PREV: 'prev',
|
|
@@ -27,37 +44,47 @@ export const MARKERS = Object.freeze({
|
|
|
27
44
|
DATE_RANGE_END: 'SECOND',
|
|
28
45
|
});
|
|
29
46
|
export const WEEKDAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
|
|
30
|
-
export const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
{key: '
|
|
34
|
-
{key: '
|
|
35
|
-
{key: '
|
|
36
|
-
{key: '
|
|
37
|
-
{key: '
|
|
38
|
-
{key: '
|
|
39
|
-
{key: '
|
|
40
|
-
{key: '
|
|
41
|
-
{key: '
|
|
42
|
-
{key: '
|
|
47
|
+
export const getMonths = (
|
|
48
|
+
t: ?(key: string, fallback: string) => string,
|
|
49
|
+
): Array<MenuOption> => [
|
|
50
|
+
{key: '0', label: getTranslation(t, 'Jan')},
|
|
51
|
+
{key: '1', label: getTranslation(t, 'Feb')},
|
|
52
|
+
{key: '2', label: getTranslation(t, 'Mar')},
|
|
53
|
+
{key: '3', label: getTranslation(t, 'Apr')},
|
|
54
|
+
{key: '4', label: getTranslation(t, 'May')},
|
|
55
|
+
{key: '5', label: getTranslation(t, 'Jun')},
|
|
56
|
+
{key: '6', label: getTranslation(t, 'Jul')},
|
|
57
|
+
{key: '7', label: getTranslation(t, 'Aug')},
|
|
58
|
+
{key: '8', label: getTranslation(t, 'Sep')},
|
|
59
|
+
{key: '9', label: getTranslation(t, 'Oct')},
|
|
60
|
+
{key: '10', label: getTranslation(t, 'Nov')},
|
|
61
|
+
{key: '11', label: getTranslation(t, 'Dec')},
|
|
43
62
|
];
|
|
44
63
|
|
|
45
|
-
export const
|
|
64
|
+
export const getDateRangePickerErrors = (
|
|
65
|
+
t: ?(key: string, fallback: string) => string,
|
|
66
|
+
): DateRangePickerErrorTypes => ({
|
|
46
67
|
MIN_MAX_INVALID: {
|
|
47
68
|
type: 'MIN_MAX_INVALID',
|
|
48
|
-
description: 'Given minDate and maxDate are invalid.',
|
|
69
|
+
description: getTranslation(t, 'Given minDate and maxDate are invalid.'),
|
|
49
70
|
},
|
|
50
71
|
START_DATE_EARLY: {
|
|
51
72
|
type: 'START_DATE_EARLY',
|
|
52
|
-
description:
|
|
73
|
+
description: getTranslation(
|
|
74
|
+
t,
|
|
75
|
+
'Given startDate can not come before minDate.',
|
|
76
|
+
),
|
|
53
77
|
},
|
|
54
78
|
START_DATE_LATE: {
|
|
55
79
|
type: 'START_DATE_LATE',
|
|
56
|
-
description:
|
|
80
|
+
description: getTranslation(
|
|
81
|
+
t,
|
|
82
|
+
'Given startDate can not come after endDate.',
|
|
83
|
+
),
|
|
57
84
|
},
|
|
58
85
|
END_DATE_LATE: {
|
|
59
86
|
type: 'END_DATE_LATE',
|
|
60
|
-
description: 'Given endDate can not come after maxDate.',
|
|
87
|
+
description: getTranslation(t, 'Given endDate can not come after maxDate.'),
|
|
61
88
|
},
|
|
62
89
|
});
|
|
63
90
|
|
|
@@ -168,11 +195,13 @@ export const getSubtractedDate = (
|
|
|
168
195
|
export const getMonthEndDate = (date: string): string =>
|
|
169
196
|
formatIsoDate(moment.utc(date).endOf('M'));
|
|
170
197
|
|
|
171
|
-
export const getTimezones = (
|
|
198
|
+
export const getTimezones = (
|
|
199
|
+
t: ?(key: string, fallback: string) => string,
|
|
200
|
+
): Array<MenuOption> =>
|
|
172
201
|
Object.keys(TIMEZONES).reduce((menuOptions, key) => {
|
|
173
202
|
menuOptions.push({
|
|
174
203
|
key,
|
|
175
|
-
label: TIMEZONES[key],
|
|
204
|
+
label: getTranslation(t, TIMEZONES[key]),
|
|
176
205
|
});
|
|
177
206
|
return menuOptions;
|
|
178
207
|
}, []);
|
|
@@ -212,17 +241,20 @@ export const getAvailableMonths = ({
|
|
|
212
241
|
maxDate,
|
|
213
242
|
rangeStartMonth,
|
|
214
243
|
rangeEndMonth,
|
|
244
|
+
t,
|
|
215
245
|
}: {
|
|
216
246
|
marker: $Values<typeof MARKERS>,
|
|
217
247
|
minDate: string,
|
|
218
248
|
maxDate: string,
|
|
219
249
|
rangeStartMonth: string,
|
|
220
250
|
rangeEndMonth: string,
|
|
251
|
+
t: ?(key: string, fallback: string) => string,
|
|
221
252
|
}): Array<MenuOption> => {
|
|
222
253
|
const [rangeStartMonthKey, rangeStartYear] = getMonthAndYear(rangeStartMonth);
|
|
223
254
|
const [rangeEndMonthKey, rangeEndYear] = getMonthAndYear(rangeEndMonth);
|
|
224
255
|
const [minDateMonth, minDateYear] = getMonthAndYear(minDate);
|
|
225
256
|
const [maxDateMonth, maxDateYear] = getMonthAndYear(maxDate);
|
|
257
|
+
const MONTHS = getMonths(t);
|
|
226
258
|
|
|
227
259
|
return MONTHS.filter((month: MenuOption) => {
|
|
228
260
|
const isSameYear = rangeStartYear === rangeEndYear;
|
|
@@ -255,12 +287,14 @@ export const getValidDates = ({
|
|
|
255
287
|
maxDate,
|
|
256
288
|
today,
|
|
257
289
|
onError,
|
|
290
|
+
t,
|
|
258
291
|
}: {
|
|
259
292
|
selectedDateRange: DateRangeWithTimezone,
|
|
260
293
|
minDate?: ?string,
|
|
261
294
|
maxDate?: ?string,
|
|
262
295
|
today: string,
|
|
263
296
|
onError?: (DateRangePickerError) => void,
|
|
297
|
+
t: ?(key: string, fallback: string) => string,
|
|
264
298
|
}): {
|
|
265
299
|
validMinDate: string,
|
|
266
300
|
validMaxDate: string,
|
|
@@ -279,7 +313,7 @@ export const getValidDates = ({
|
|
|
279
313
|
const isMinMaxRangeInvalid = !isRangeValid(
|
|
280
314
|
validMinDate,
|
|
281
315
|
validMaxDate,
|
|
282
|
-
|
|
316
|
+
getDateRangePickerErrors(t).MIN_MAX_INVALID,
|
|
283
317
|
);
|
|
284
318
|
|
|
285
319
|
// if startDate is defined and then it should be after minDate
|
|
@@ -289,7 +323,7 @@ export const getValidDates = ({
|
|
|
289
323
|
!isRangeValid(
|
|
290
324
|
validMinDate,
|
|
291
325
|
startDate,
|
|
292
|
-
|
|
326
|
+
getDateRangePickerErrors(t).START_DATE_EARLY,
|
|
293
327
|
);
|
|
294
328
|
|
|
295
329
|
if (isMinMaxRangeInvalid || isStartDateInvalid) {
|
|
@@ -305,13 +339,17 @@ export const getValidDates = ({
|
|
|
305
339
|
!isRangeValid(
|
|
306
340
|
endDate,
|
|
307
341
|
validMaxDate,
|
|
308
|
-
|
|
342
|
+
getDateRangePickerErrors(t).END_DATE_LATE,
|
|
309
343
|
);
|
|
310
344
|
|
|
311
345
|
// startDate should be before endDate
|
|
312
346
|
const isStartEndRangeInvalid =
|
|
313
347
|
isEndDateInvalid ||
|
|
314
|
-
!isRangeValid(
|
|
348
|
+
!isRangeValid(
|
|
349
|
+
startDate,
|
|
350
|
+
endDate,
|
|
351
|
+
getDateRangePickerErrors(t).START_DATE_LATE,
|
|
352
|
+
);
|
|
315
353
|
|
|
316
354
|
if (isEndDateInvalid || isStartEndRangeInvalid) {
|
|
317
355
|
return {
|
|
@@ -376,8 +414,15 @@ export const isValid = (date?: ?string): boolean => moment.utc(date).isValid();
|
|
|
376
414
|
export const getFormattedDate = (
|
|
377
415
|
marker: string,
|
|
378
416
|
dateRange: DateRange,
|
|
417
|
+
locale?: string,
|
|
379
418
|
): string => {
|
|
380
419
|
const {startDate, endDate} = dateRange;
|
|
420
|
+
|
|
421
|
+
// set locale if provided
|
|
422
|
+
if (locale) {
|
|
423
|
+
moment.locale(locale);
|
|
424
|
+
}
|
|
425
|
+
|
|
381
426
|
switch (marker) {
|
|
382
427
|
case MARKERS.DATE_RANGE_START:
|
|
383
428
|
return startDate
|
|
@@ -389,3 +434,9 @@ export const getFormattedDate = (
|
|
|
389
434
|
: 'MMM DD, YYYY';
|
|
390
435
|
}
|
|
391
436
|
};
|
|
437
|
+
|
|
438
|
+
export const getTranslation = (
|
|
439
|
+
t: ?(key: string, fallback: string) => string,
|
|
440
|
+
labelToTranslate: string,
|
|
441
|
+
): string =>
|
|
442
|
+
t ? t(makeKey(labelToTranslate), labelToTranslate) : labelToTranslate;
|