@ember-eui/core 5.8.5 → 5.10.2
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/addon/components/eui-checkbox-group/index.hbs +8 -0
- package/addon/components/eui-combo-box/index.hbs +1 -1
- package/addon/components/eui-combo-box/options/index.hbs +1 -0
- package/addon/components/eui-dual-range/index.ts +2 -2
- package/addon/components/eui-field-text/index.hbs +1 -0
- package/addon/components/eui-global-toast-list/index.ts +1 -1
- package/addon/components/eui-i18n/index.ts +9 -41
- package/addon/components/eui-icon/index.ts +2 -2
- package/addon/components/eui-markdown-editor/index.ts +2 -2
- package/addon/components/eui-portal/index.ts +2 -2
- package/addon/components/eui-range/index.ts +2 -2
- package/addon/components/eui-super-date-picker/date-popover/absolute-tab.hbs +42 -0
- package/addon/components/eui-super-date-picker/date-popover/absolute-tab.ts +79 -0
- package/addon/components/eui-super-date-picker/date-popover/datetime-picker.hbs +125 -0
- package/addon/components/eui-super-date-picker/date-popover/datetime-picker.ts +258 -0
- package/addon/components/eui-super-date-picker/date-popover/eui-date-popover-button.hbs +49 -0
- package/addon/components/eui-super-date-picker/date-popover/eui-date-popover-button.ts +49 -0
- package/addon/components/eui-super-date-picker/date-popover/eui-date-popover-content.hbs +42 -0
- package/addon/components/eui-super-date-picker/date-popover/eui-date-popover-content.ts +73 -0
- package/addon/components/eui-super-date-picker/date-popover/now-tab.hbs +45 -0
- package/addon/components/eui-super-date-picker/date-popover/relative-tab.hbs +47 -0
- package/addon/components/eui-super-date-picker/date-popover/relative-tab.ts +89 -0
- package/addon/components/eui-super-date-picker/eui-date-picker-range.hbs +22 -0
- package/addon/components/eui-super-date-picker/eui-quick-select-popover/eui-commonly-used-time-ranges.hbs +42 -0
- package/addon/components/eui-super-date-picker/eui-quick-select-popover/eui-quick-select.hbs +154 -0
- package/addon/components/eui-super-date-picker/eui-quick-select-popover/eui-quick-select.ts +103 -0
- package/addon/components/eui-super-date-picker/eui-quick-select-popover/eui-recently-used.hbs +48 -0
- package/addon/components/eui-super-date-picker/eui-quick-select-popover/index.hbs +60 -0
- package/addon/components/eui-super-date-picker/eui-quick-select-popover/index.ts +34 -0
- package/addon/components/eui-super-date-picker/eui-super-update-button.hbs +43 -0
- package/addon/components/eui-super-date-picker/index.hbs +123 -0
- package/addon/components/eui-super-date-picker/index.ts +220 -0
- package/addon/components/eui-super-date-picker/types/global.d.ts +52 -0
- package/addon/components/eui-super-date-picker/utils/date-utils.ts +59 -0
- package/addon/components/eui-super-date-picker/utils/index.ts +181 -0
- package/addon/components/eui-super-date-picker/utils/pretty-duration.ts +131 -0
- package/addon/components/eui-super-date-picker/utils/quick-select.ts +75 -0
- package/addon/components/eui-super-date-picker/utils/time-options.ts +216 -0
- package/addon/components/eui-tool-tip/index.ts +2 -2
- package/addon/components/text-block/index.hbs +25 -21
- package/addon/{components/eui-i18n → i18n}/util.ts +1 -6
- package/addon/modifiers/outside-click-detector.ts +2 -2
- package/addon/services/eui-i18n.ts +89 -0
- package/addon/utils/markdown/markdown-unified-plugins.d.ts +0 -14
- package/app/components/eui-super-date-picker/date-popover/absolute-tab.js +1 -0
- package/app/components/eui-super-date-picker/date-popover/datetime-picker.js +1 -0
- package/app/components/eui-super-date-picker/date-popover/eui-date-popover-button.js +1 -0
- package/app/components/eui-super-date-picker/date-popover/eui-date-popover-content.js +1 -0
- package/app/components/eui-super-date-picker/date-popover/now-tab.js +1 -0
- package/app/components/eui-super-date-picker/date-popover/relative-tab.js +1 -0
- package/app/components/eui-super-date-picker/eui-date-picker-range.js +1 -0
- package/app/components/eui-super-date-picker/eui-quick-select-popover/eui-commonly-used-time-ranges.js +1 -0
- package/app/components/eui-super-date-picker/eui-quick-select-popover/eui-quick-select.js +1 -0
- package/app/components/eui-super-date-picker/eui-quick-select-popover/eui-recently-used.js +1 -0
- package/app/components/eui-super-date-picker/eui-quick-select-popover/index.js +1 -0
- package/app/components/eui-super-date-picker/eui-super-update-button.js +1 -0
- package/app/components/eui-super-date-picker/index.js +1 -0
- package/app/services/eui-i18n.js +1 -0
- package/docs/forms/super-date-picker/demo/d01-picker.md +90 -0
- package/docs/forms/super-date-picker/index.md +16 -0
- package/package.json +7 -3
- package/tsconfig.json +1 -0
- package/addon/helpers/unique-id.ts +0 -23
- package/addon/i18n/index.ts +0 -8
- package/app/helpers/unique-id.js +0 -1
- package/app/i18n/index.js +0 -1
- package/docs/templates/super-date-picker/demo/d01-update-button.md +0 -10
- package/docs/templates/super-date-picker/demo/d02-quick-select-panels.md +0 -10
- package/docs/templates/super-date-picker/demo/d03-sizing.md +0 -10
- package/docs/templates/super-date-picker/demo/d04-auto-refresh.md +0 -11
- package/docs/templates/super-date-picker/demo/d05-elastic-pattern-with-kql.md +0 -10
- package/docs/templates/super-date-picker/index.md +0 -12
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { action } from '@ember/object';
|
|
2
|
+
import Component from '@glimmer/component';
|
|
3
|
+
import { tracked } from '@glimmer/tracking';
|
|
4
|
+
import { helper } from '@ember/component/helper';
|
|
5
|
+
import moment from 'moment';
|
|
6
|
+
// import { isDayDisabled, isOutOfBounds } from '../utils/date-utils';
|
|
7
|
+
|
|
8
|
+
const isSameDayHelper = helper(function ([year, month, day, selectedDate]: [
|
|
9
|
+
number,
|
|
10
|
+
number,
|
|
11
|
+
number,
|
|
12
|
+
moment.Moment
|
|
13
|
+
]) {
|
|
14
|
+
if (!selectedDate) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
return (
|
|
18
|
+
selectedDate.year() === year &&
|
|
19
|
+
selectedDate.month() === month &&
|
|
20
|
+
selectedDate.date() === day
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
interface DatetimePickerArgs {
|
|
25
|
+
selected: moment.Moment;
|
|
26
|
+
onChange: (value: any) => void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface Day {
|
|
30
|
+
day: number;
|
|
31
|
+
month: number;
|
|
32
|
+
year: number;
|
|
33
|
+
isOutside: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default class DatetimePicker extends Component<DatetimePickerArgs> {
|
|
37
|
+
@tracked month: number = 0;
|
|
38
|
+
@tracked year: number = 0;
|
|
39
|
+
@tracked monthMoment: moment.Moment;
|
|
40
|
+
// Used to style the days outside of the current month
|
|
41
|
+
@tracked offset: number = 0;
|
|
42
|
+
@tracked selectedDate?: moment.Moment;
|
|
43
|
+
@tracked selectedTime?: string;
|
|
44
|
+
@tracked today: moment.Moment;
|
|
45
|
+
|
|
46
|
+
momentConfig: {
|
|
47
|
+
year: number;
|
|
48
|
+
month: number;
|
|
49
|
+
day: number;
|
|
50
|
+
hour: number;
|
|
51
|
+
minute: number;
|
|
52
|
+
second: number;
|
|
53
|
+
millisecond: number;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
isSameDayHelper = isSameDayHelper;
|
|
57
|
+
|
|
58
|
+
constructor(owner: unknown, args: DatetimePickerArgs) {
|
|
59
|
+
super(owner, args);
|
|
60
|
+
|
|
61
|
+
if (this.args.selected) {
|
|
62
|
+
this.monthMoment = this.args.selected;
|
|
63
|
+
this.selectedDate = this.args.selected;
|
|
64
|
+
} else {
|
|
65
|
+
this.monthMoment = moment([this.year, this.month]);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
this.momentConfig = {
|
|
69
|
+
year: this.monthMoment.year(),
|
|
70
|
+
month: this.monthMoment.month(),
|
|
71
|
+
day: this.monthMoment.date(),
|
|
72
|
+
hour: this.monthMoment.hour(),
|
|
73
|
+
minute: this.monthMoment.minute(),
|
|
74
|
+
second: 0,
|
|
75
|
+
millisecond: 0
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
this.month = this.momentConfig.month;
|
|
79
|
+
this.year = this.momentConfig.year;
|
|
80
|
+
let hour = this.momentConfig.hour;
|
|
81
|
+
let minute = this.momentConfig.minute;
|
|
82
|
+
let hourStr = hour < 10 ? `0${hour}` : hour;
|
|
83
|
+
let minuteStr = minute < 10 ? `0${minute}` : minute;
|
|
84
|
+
this.selectedTime = `${hourStr}:${minuteStr}`;
|
|
85
|
+
|
|
86
|
+
this.offset = this.monthMoment.clone().startOf('month').day();
|
|
87
|
+
|
|
88
|
+
this.today = moment();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
get monthNames() {
|
|
92
|
+
return moment.months().map((month, i) => {
|
|
93
|
+
return {
|
|
94
|
+
text: month,
|
|
95
|
+
value: i
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
get years() {
|
|
101
|
+
return Array.from(Array(15).keys()).map((_, i) => {
|
|
102
|
+
// Create a list of years +/- 7 from the current year
|
|
103
|
+
let year = this.year - 7 + i;
|
|
104
|
+
return {
|
|
105
|
+
text: year,
|
|
106
|
+
value: year
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
get times() {
|
|
112
|
+
const timesArray = [];
|
|
113
|
+
// Create entries every 30 minutes
|
|
114
|
+
for (let i = 0; i < 24; i++) {
|
|
115
|
+
let hour = i < 10 ? `0${i}` : i;
|
|
116
|
+
timesArray.push(`${hour}:00`, `${hour}:30`);
|
|
117
|
+
}
|
|
118
|
+
return timesArray;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
get days() {
|
|
122
|
+
// Used for showing days outside of the current month
|
|
123
|
+
// const prevMonth = moment([this.year, this.month - 1]);
|
|
124
|
+
const prevMonth = this.monthMoment.clone().subtract(1, 'month');
|
|
125
|
+
const nextMonth = this.monthMoment.clone().add(1, 'month');
|
|
126
|
+
const offset = this.offset;
|
|
127
|
+
let daysInMonth = this.monthMoment.daysInMonth();
|
|
128
|
+
let daysInPrevMonth = prevMonth.daysInMonth();
|
|
129
|
+
|
|
130
|
+
const daysArray = [];
|
|
131
|
+
for (let i = 0; i < daysInMonth; i++) {
|
|
132
|
+
daysArray[i] = {
|
|
133
|
+
day: i + 1
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Fill the previous and next month days
|
|
138
|
+
for (let i = 0, d = daysInPrevMonth; i < offset; i++, d--) {
|
|
139
|
+
daysArray.unshift({
|
|
140
|
+
day: d,
|
|
141
|
+
month: prevMonth.month(),
|
|
142
|
+
year: prevMonth.year(),
|
|
143
|
+
isOutside: true
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
// All months fit within 6 weeks (42 days)
|
|
147
|
+
for (let d = 1, i = daysInMonth + offset; i < 42; d++, i++) {
|
|
148
|
+
daysArray.push({
|
|
149
|
+
day: d,
|
|
150
|
+
month: nextMonth.month(),
|
|
151
|
+
year: nextMonth.year(),
|
|
152
|
+
isOutside: true
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// All months fit within 6 weeks (42 days)
|
|
157
|
+
// but depending on the starting day, one week may not be needed
|
|
158
|
+
const daysMatrix = [];
|
|
159
|
+
const weeks = daysInMonth + offset > 35 ? 6 : 5;
|
|
160
|
+
for (let i = 0; i < weeks; i++) {
|
|
161
|
+
daysMatrix[i] = daysArray.slice(i * 7, i * 7 + 7);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return daysMatrix;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
updateDate() {
|
|
168
|
+
this.year = this.monthMoment.year();
|
|
169
|
+
this.month = this.monthMoment.month();
|
|
170
|
+
this.offset = this.monthMoment.clone().startOf('month').day();
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@action selectTime(time: string) {
|
|
174
|
+
this.selectedTime = time;
|
|
175
|
+
const [hour, minute] = time.split(':');
|
|
176
|
+
this.momentConfig.hour = parseInt(hour);
|
|
177
|
+
this.momentConfig.minute = parseInt(minute);
|
|
178
|
+
this.momentConfig.second = 0;
|
|
179
|
+
this.momentConfig.millisecond = 0;
|
|
180
|
+
this.selectedDate = moment(this.momentConfig);
|
|
181
|
+
this.args.onChange(this.selectedDate);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
@action selectDate(day: Day) {
|
|
185
|
+
// Only outside days will have year/month
|
|
186
|
+
this.momentConfig.year = day.year || this.year;
|
|
187
|
+
this.momentConfig.month = day.month || this.month;
|
|
188
|
+
this.momentConfig.day = day.day;
|
|
189
|
+
this.selectedDate = moment(this.momentConfig);
|
|
190
|
+
this.args.onChange(this.selectedDate);
|
|
191
|
+
|
|
192
|
+
// Update the state to show the selected month properly
|
|
193
|
+
if (day.isOutside) {
|
|
194
|
+
this.monthMoment.month(day.month);
|
|
195
|
+
this.monthMoment.year(day.year);
|
|
196
|
+
this.updateDate();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// @action setSelected(date, event, keepInput) {
|
|
201
|
+
// let changedDate = date;
|
|
202
|
+
|
|
203
|
+
// if (changedDate !== null && isDayDisabled(changedDate, this.props)) {
|
|
204
|
+
// if (isOutOfBounds(changedDate, this.props)) {
|
|
205
|
+
// this.props.onChange(date, event);
|
|
206
|
+
// this.props.onSelect(changedDate, event);
|
|
207
|
+
// }
|
|
208
|
+
|
|
209
|
+
// return;
|
|
210
|
+
// }
|
|
211
|
+
|
|
212
|
+
// if (changedDate !== null && this.props.selected) {
|
|
213
|
+
// let selected = this.props.selected;
|
|
214
|
+
// if (keepInput) selected = newDate(changedDate);
|
|
215
|
+
// changedDate = setTime(newDate(changedDate), {
|
|
216
|
+
// hour: getHour(selected),
|
|
217
|
+
// minute: getMinute(selected),
|
|
218
|
+
// second: getSecond(selected),
|
|
219
|
+
// millisecond: getMillisecond(selected),
|
|
220
|
+
// });
|
|
221
|
+
// }
|
|
222
|
+
|
|
223
|
+
// if (
|
|
224
|
+
// !isSameTime(this.props.selected, changedDate) ||
|
|
225
|
+
// this.props.allowSameDay
|
|
226
|
+
// ) {
|
|
227
|
+
// if (changedDate !== null) {
|
|
228
|
+
// if (!this.props.inline) {
|
|
229
|
+
// this.setState({
|
|
230
|
+
// preSelection: changedDate
|
|
231
|
+
// });
|
|
232
|
+
// }
|
|
233
|
+
// }
|
|
234
|
+
// this.props.onChange(changedDate, event);
|
|
235
|
+
// }
|
|
236
|
+
|
|
237
|
+
// this.props.onSelect(changedDate, event);
|
|
238
|
+
|
|
239
|
+
// if (!keepInput) {
|
|
240
|
+
// this.setState({ inputValue: null });
|
|
241
|
+
// }
|
|
242
|
+
// }
|
|
243
|
+
|
|
244
|
+
@action setMonth(month: string) {
|
|
245
|
+
this.monthMoment.month(parseInt(month));
|
|
246
|
+
this.updateDate();
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
@action increaseMonth() {
|
|
250
|
+
this.monthMoment.add(1, 'month');
|
|
251
|
+
this.updateDate();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
@action decreaseMonth() {
|
|
255
|
+
this.monthMoment.subtract(1, 'month');
|
|
256
|
+
this.updateDate();
|
|
257
|
+
}
|
|
258
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{{#let
|
|
2
|
+
(class-names
|
|
3
|
+
"euiDatePopoverButton"
|
|
4
|
+
(concat "euiDatePopoverButton--" @position)
|
|
5
|
+
(if @compressed "euiDatePopoverButton--compressed")
|
|
6
|
+
(if this.isOpen "euiDatePopoverButton-isSelected")
|
|
7
|
+
(if @isInvalid "euiDatePopoverButton-isInvalid")
|
|
8
|
+
(if @needsUpdating "euiDatePopoverButton-needsUpdating")
|
|
9
|
+
(if @isDisabled "euiDatePopoverButton-disabled")
|
|
10
|
+
)
|
|
11
|
+
as |classes|
|
|
12
|
+
}}
|
|
13
|
+
<EuiPopover
|
|
14
|
+
@className={{@className}}
|
|
15
|
+
@isOpen={{this.isOpen}}
|
|
16
|
+
@closePopover={{set this "isOpen" false}}
|
|
17
|
+
@anchorPosition={{this.anchorPosition}}
|
|
18
|
+
@panelPaddingSize="none"
|
|
19
|
+
@display="block"
|
|
20
|
+
>
|
|
21
|
+
<:button>
|
|
22
|
+
<button
|
|
23
|
+
type="button"
|
|
24
|
+
{{!-- onClick={onPopoverToggle} --}}
|
|
25
|
+
class={{classes}}
|
|
26
|
+
title={{this.formattedValue}}
|
|
27
|
+
disabled={{@isDisabled}}
|
|
28
|
+
...attributes
|
|
29
|
+
{{on "click" (set this "isOpen" (not this.isOpen))}}
|
|
30
|
+
>
|
|
31
|
+
{{this.formattedValue}}
|
|
32
|
+
</button>
|
|
33
|
+
</:button>
|
|
34
|
+
|
|
35
|
+
<:content>
|
|
36
|
+
<EuiSuperDatePicker::DatePopover::EuiDatePopoverContent
|
|
37
|
+
@position={{@position}}
|
|
38
|
+
@value={{@value}}
|
|
39
|
+
@roundUp={{@roundUp}}
|
|
40
|
+
@dateFormat={{@dateFormat}}
|
|
41
|
+
@timeFormat={{@timeFormat}}
|
|
42
|
+
@locale={{@locale}}
|
|
43
|
+
@utcOffset={{@utcOffset}}
|
|
44
|
+
@timeOptions={{@timeOptions}}
|
|
45
|
+
@onChange={{@onChange}}
|
|
46
|
+
/>
|
|
47
|
+
</:content>
|
|
48
|
+
</EuiPopover>
|
|
49
|
+
{{/let}}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { useFormatTimeString } from '../utils';
|
|
4
|
+
import { LocaleSpecifier } from 'moment';
|
|
5
|
+
import { inject as service } from '@ember/service';
|
|
6
|
+
import type EuiI18n from '../../../services/eui-i18n';
|
|
7
|
+
|
|
8
|
+
interface EuiDatePopoverButtonArgs {
|
|
9
|
+
className?: string;
|
|
10
|
+
// buttonProps?: ButtonHTMLAttributes<HTMLButtonElement>;
|
|
11
|
+
dateFormat: string;
|
|
12
|
+
isDisabled?: boolean;
|
|
13
|
+
isInvalid?: boolean;
|
|
14
|
+
isOpen: boolean;
|
|
15
|
+
needsUpdating?: boolean;
|
|
16
|
+
locale?: LocaleSpecifier;
|
|
17
|
+
// onChange: NonNullable<EuiDatePopoverContentProps['onChange']>;
|
|
18
|
+
// onPopoverClose: EuiPopoverProps['closePopover'];
|
|
19
|
+
// onPopoverToggle: MouseEventHandler<HTMLButtonElement>;
|
|
20
|
+
position: 'start' | 'end';
|
|
21
|
+
roundUp?: boolean;
|
|
22
|
+
timeFormat: string;
|
|
23
|
+
value: string;
|
|
24
|
+
utcOffset?: number;
|
|
25
|
+
compressed?: boolean;
|
|
26
|
+
// timeOptions: TimeOptions;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default class EuiDatePopoverButton extends Component<EuiDatePopoverButtonArgs> {
|
|
30
|
+
@service declare euiI18n: EuiI18n;
|
|
31
|
+
@tracked isOpen = false;
|
|
32
|
+
|
|
33
|
+
get formattedValue() {
|
|
34
|
+
const roundUp = this.args.roundUp ?? false;
|
|
35
|
+
const locale = this.args.locale ?? 'en';
|
|
36
|
+
|
|
37
|
+
return useFormatTimeString(
|
|
38
|
+
this.args.value,
|
|
39
|
+
this.args.dateFormat,
|
|
40
|
+
roundUp,
|
|
41
|
+
locale,
|
|
42
|
+
this.euiI18n
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get anchorPosition() {
|
|
47
|
+
return this.args.position === 'start' ? 'downLeft' : 'downRight';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<EuiTabbedContent
|
|
2
|
+
@className="euiDatePopoverContent"
|
|
3
|
+
@tabs={{this.tabs}}
|
|
4
|
+
@initialSelectedTab={{this.initialSelectedTab}}
|
|
5
|
+
@autoFocus="selected"
|
|
6
|
+
@expand={{true}}
|
|
7
|
+
@size="s"
|
|
8
|
+
{{!-- onTabClick={onTabClick} --}}
|
|
9
|
+
>
|
|
10
|
+
<:selectedTabContent as |selected|>
|
|
11
|
+
{{#if (eq selected.id "relative")}}
|
|
12
|
+
<EuiSuperDatePicker::DatePopover::RelativeTab
|
|
13
|
+
@value={{this.toAbsoluteStringHelper
|
|
14
|
+
@value
|
|
15
|
+
(arg-or-default @roundUp false)
|
|
16
|
+
}}
|
|
17
|
+
@onChange={{@onChange}}
|
|
18
|
+
@labelPrefix={{this.labelPrefix}}
|
|
19
|
+
@roundUp={{this.roundUp}}
|
|
20
|
+
@dateFormat={{@dateFormat}}
|
|
21
|
+
@locale={{@locale}}
|
|
22
|
+
@position={{@position}}
|
|
23
|
+
@timeOptions={{@timeOptions}}
|
|
24
|
+
/>
|
|
25
|
+
{{else if (eq selected.id "now")}}
|
|
26
|
+
<EuiSuperDatePicker::DatePopover::NowTab
|
|
27
|
+
@position={{@position}}
|
|
28
|
+
@onChange={{@onChange}}
|
|
29
|
+
/>
|
|
30
|
+
{{else if (eq selected.id "absolute")}}
|
|
31
|
+
<EuiSuperDatePicker::DatePopover::AbsoluteTab
|
|
32
|
+
@value={{@value}}
|
|
33
|
+
@roundUp={{this.roundUp}}
|
|
34
|
+
@dateFormat={{@dateFormat}}
|
|
35
|
+
@locale={{@locale}}
|
|
36
|
+
@position={{@position}}
|
|
37
|
+
@onChange={{@onChange}}
|
|
38
|
+
@labelPrefix={{this.labelPrefix}}
|
|
39
|
+
/>
|
|
40
|
+
{{/if}}
|
|
41
|
+
</:selectedTabContent>
|
|
42
|
+
</EuiTabbedContent>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { toAbsoluteString, getDateMode } from '../utils';
|
|
4
|
+
import { helper } from '@ember/component/helper';
|
|
5
|
+
import { inject as service } from '@ember/service';
|
|
6
|
+
import type EuiI18n from '../../../services/eui-i18n';
|
|
7
|
+
|
|
8
|
+
interface EuiDatePopoverContentArgs {
|
|
9
|
+
value: string;
|
|
10
|
+
onChange(date: string | null, event?: React.SyntheticEvent<any>): void;
|
|
11
|
+
roundUp?: boolean;
|
|
12
|
+
dateFormat: string;
|
|
13
|
+
timeFormat: string;
|
|
14
|
+
// locale?: LocaleSpecifier;
|
|
15
|
+
position: 'start' | 'end';
|
|
16
|
+
utcOffset?: number;
|
|
17
|
+
// timeOptions: TimeOptions;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const toAbsoluteStringHelper = helper(function ([value, roundUp]: [
|
|
21
|
+
string,
|
|
22
|
+
boolean
|
|
23
|
+
]) {
|
|
24
|
+
return toAbsoluteString(value, roundUp);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export default class EuiDatePopoverContent extends Component<EuiDatePopoverContentArgs> {
|
|
28
|
+
@service declare euiI18n: EuiI18n;
|
|
29
|
+
@tracked selectedTab = 0;
|
|
30
|
+
toAbsoluteStringHelper = toAbsoluteStringHelper;
|
|
31
|
+
|
|
32
|
+
get labelPrefix() {
|
|
33
|
+
return this.args.position === 'start'
|
|
34
|
+
? this.euiI18n.lookupToken(
|
|
35
|
+
'euiDatePopoverContent.startDateLabel',
|
|
36
|
+
'Start date'
|
|
37
|
+
)
|
|
38
|
+
: this.euiI18n.lookupToken(
|
|
39
|
+
'euiDatePopoverContent.endDateLabel',
|
|
40
|
+
'End date'
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
get tabs() {
|
|
45
|
+
return [
|
|
46
|
+
{
|
|
47
|
+
id: 'absolute',
|
|
48
|
+
name: this.euiI18n.lookupToken(
|
|
49
|
+
'euiDatePopoverContent.absoluteTabLabel',
|
|
50
|
+
'Absolute'
|
|
51
|
+
)
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'relative',
|
|
55
|
+
name: this.euiI18n.lookupToken(
|
|
56
|
+
'euiDatePopoverContent.relativeTabLabel',
|
|
57
|
+
'Relative'
|
|
58
|
+
)
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: 'now',
|
|
62
|
+
name: this.euiI18n.lookupToken(
|
|
63
|
+
'euiDatePopoverContent.nowTabLabel',
|
|
64
|
+
'Now'
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
get initialSelectedTab() {
|
|
71
|
+
return this.tabs.find((tab) => tab.id === getDateMode(this.args.value));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<EuiText
|
|
2
|
+
class="euiDatePopoverContent__padded--large"
|
|
3
|
+
@size="s"
|
|
4
|
+
@color="subdued"
|
|
5
|
+
>
|
|
6
|
+
<p>
|
|
7
|
+
<EuiI18n
|
|
8
|
+
@token="euiDatePopoverContent.nowTabContent"
|
|
9
|
+
@default="Setting the time to now means that on every refresh this time will be set to the time of the refresh."
|
|
10
|
+
as |Token|
|
|
11
|
+
>
|
|
12
|
+
<Token as |value|>
|
|
13
|
+
{{value}}
|
|
14
|
+
</Token>
|
|
15
|
+
</EuiI18n>
|
|
16
|
+
</p>
|
|
17
|
+
<EuiButton
|
|
18
|
+
@fullWidth={{true}}
|
|
19
|
+
@size="s"
|
|
20
|
+
@fill={{true}}
|
|
21
|
+
{{on "click" (fn @onChange "now")}}
|
|
22
|
+
>
|
|
23
|
+
{{#if (eq @position "start")}}
|
|
24
|
+
<EuiI18n
|
|
25
|
+
@token="euiDatePopoverContent.nowTabButtonStart"
|
|
26
|
+
@default="Set start date and time to now"
|
|
27
|
+
as |Token|
|
|
28
|
+
>
|
|
29
|
+
<Token as |value|>
|
|
30
|
+
{{value}}
|
|
31
|
+
</Token>
|
|
32
|
+
</EuiI18n>
|
|
33
|
+
{{else}}
|
|
34
|
+
<EuiI18n
|
|
35
|
+
@token="euiDatePopoverContent.nowTabButtonEnd"
|
|
36
|
+
@default="Set end date and time to now"
|
|
37
|
+
as |Token|
|
|
38
|
+
>
|
|
39
|
+
<Token as |value|>
|
|
40
|
+
{{value}}
|
|
41
|
+
</Token>
|
|
42
|
+
</EuiI18n>
|
|
43
|
+
{{/if}}
|
|
44
|
+
</EuiButton>
|
|
45
|
+
</EuiText>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<EuiForm class="euiDatePopoverContent__padded">
|
|
2
|
+
<EuiFlexGroup @gutterSize="s" @responsive={{false}}>
|
|
3
|
+
<EuiFlexItem>
|
|
4
|
+
<EuiFormRow
|
|
5
|
+
{{!-- isInvalid={isInvalid}
|
|
6
|
+
error={getErrorMessage({
|
|
7
|
+
numberInputError,
|
|
8
|
+
dateInputError,
|
|
9
|
+
})} --}}
|
|
10
|
+
>
|
|
11
|
+
<EuiFieldNumber
|
|
12
|
+
@compressed={{true}}
|
|
13
|
+
@value={{this.count}}
|
|
14
|
+
@min="0"
|
|
15
|
+
{{on "input" this.onCountChange}}
|
|
16
|
+
{{!--
|
|
17
|
+
isInvalid={isInvalid} --}}
|
|
18
|
+
/>
|
|
19
|
+
</EuiFormRow>
|
|
20
|
+
</EuiFlexItem>
|
|
21
|
+
<EuiFlexItem>
|
|
22
|
+
<EuiSelect
|
|
23
|
+
@compressed={{true}}
|
|
24
|
+
@value={{this.unit}}
|
|
25
|
+
@options={{@timeOptions.relativeOptions}}
|
|
26
|
+
{{on "change" (pick "target.value" this.onUnitChange)}}
|
|
27
|
+
/>
|
|
28
|
+
</EuiFlexItem>
|
|
29
|
+
</EuiFlexGroup>
|
|
30
|
+
<EuiSpacer @size="s" />
|
|
31
|
+
<EuiFieldText
|
|
32
|
+
@compressed={{true}}
|
|
33
|
+
@value={{this.formattedValue}}
|
|
34
|
+
@readOnly={{true}}
|
|
35
|
+
>
|
|
36
|
+
<:prepend>
|
|
37
|
+
<EuiFormLabel>{{@labelPrefix}}</EuiFormLabel>
|
|
38
|
+
</:prepend>
|
|
39
|
+
</EuiFieldText>
|
|
40
|
+
</EuiForm>
|
|
41
|
+
<EuiPopoverFooter @paddingSize="s">
|
|
42
|
+
<EuiSwitch
|
|
43
|
+
@label={{this.roundingLabel}}
|
|
44
|
+
@checked={{this.round}}
|
|
45
|
+
@onChange={{pick 'target.checked' this.onRoundChange}}
|
|
46
|
+
/>
|
|
47
|
+
</EuiPopoverFooter>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import dateMath from '@elastic/datemath';
|
|
3
|
+
import { INVALID_DATE, toRelativeStringFromParts } from '../utils';
|
|
4
|
+
import { LocaleSpecifier } from 'moment';
|
|
5
|
+
import { tracked } from '@glimmer/tracking';
|
|
6
|
+
import { action } from '@ember/object';
|
|
7
|
+
import { parseRelativeParts } from '../utils';
|
|
8
|
+
import { EuiDatePopoverContentProps, TimeUnitId } from '@elastic/eui';
|
|
9
|
+
import { TimeOptions } from '../utils/time-options';
|
|
10
|
+
|
|
11
|
+
interface RelativeTabArgs {
|
|
12
|
+
dateFormat: string;
|
|
13
|
+
locale?: LocaleSpecifier;
|
|
14
|
+
value: string;
|
|
15
|
+
onChange: EuiDatePopoverContentProps['onChange'];
|
|
16
|
+
roundUp?: boolean;
|
|
17
|
+
position: 'start' | 'end';
|
|
18
|
+
labelPrefix: string;
|
|
19
|
+
timeOptions: TimeOptions;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default class RelativeTab extends Component<RelativeTabArgs> {
|
|
23
|
+
@tracked count?: number;
|
|
24
|
+
@tracked unit: TimeUnitId = 'm';
|
|
25
|
+
@tracked round = false;
|
|
26
|
+
|
|
27
|
+
roundUnit;
|
|
28
|
+
|
|
29
|
+
constructor(owner: unknown, args: RelativeTabArgs) {
|
|
30
|
+
super(owner, args);
|
|
31
|
+
const parsed = parseRelativeParts(this.args.value);
|
|
32
|
+
if (parsed) {
|
|
33
|
+
this.count = parsed.count;
|
|
34
|
+
this.unit = parsed.unit as TimeUnitId;
|
|
35
|
+
this.round = parsed.round;
|
|
36
|
+
this.roundUnit = parsed.roundUnit;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get formattedValue() {
|
|
41
|
+
const invalidDate = this.args.value === INVALID_DATE;
|
|
42
|
+
const invalidValue = this.count === undefined || this.count < 0;
|
|
43
|
+
const isInvalid = invalidValue || invalidDate;
|
|
44
|
+
const parsedValue = dateMath.parse(this.args.value, {
|
|
45
|
+
roundUp: this.args.roundUp
|
|
46
|
+
});
|
|
47
|
+
const invalid = isInvalid || !parsedValue || !parsedValue.isValid();
|
|
48
|
+
return invalid
|
|
49
|
+
? ''
|
|
50
|
+
: parsedValue
|
|
51
|
+
.locale(this.args.locale || 'en')
|
|
52
|
+
.format(this.args.dateFormat);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get roundingLabel() {
|
|
56
|
+
return this.args.timeOptions.relativeRoundingLabels[
|
|
57
|
+
<TimeUnitId>this.unit[0]
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@action onCountChange(e: InputEvent) {
|
|
62
|
+
const sanitizedValue = parseInt((e.target as HTMLInputElement).value, 10);
|
|
63
|
+
this.count = isNaN(sanitizedValue) ? undefined : sanitizedValue;
|
|
64
|
+
this.handleChange();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@action onUnitChange(unit: string) {
|
|
68
|
+
this.unit = unit as TimeUnitId;
|
|
69
|
+
this.handleChange();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@action onRoundChange(checked: boolean) {
|
|
73
|
+
this.round = checked;
|
|
74
|
+
this.handleChange();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
handleChange() {
|
|
78
|
+
if (this.count === undefined || this.count < 0) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const date = toRelativeStringFromParts({
|
|
82
|
+
count: this.count,
|
|
83
|
+
round: this.round,
|
|
84
|
+
roundUnit: this.roundUnit as TimeUnitId,
|
|
85
|
+
unit: this.unit
|
|
86
|
+
});
|
|
87
|
+
this.args.onChange(date);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<div
|
|
2
|
+
class={{class-names
|
|
3
|
+
"euiDatePickerRange"
|
|
4
|
+
(if @readOnly "euiDatePickerRange--readOnly")
|
|
5
|
+
(if @fullWidth "euiDatePickerRange--fullWidth")
|
|
6
|
+
(if @isInvalid "euiDatePickerRange--isInvalid")
|
|
7
|
+
(if @disabled "euiDatePickerRange--isDisabled")
|
|
8
|
+
@className
|
|
9
|
+
}}
|
|
10
|
+
...attributes
|
|
11
|
+
>
|
|
12
|
+
{{yield to="startDateControl"}}
|
|
13
|
+
|
|
14
|
+
<span class="euiDatePickerRange__delimeter">
|
|
15
|
+
<EuiIcon
|
|
16
|
+
@color={{if @isInvalid 'danger' 'subdued'}}
|
|
17
|
+
@type={{if @isInvalid 'alert' 'sortRight'}}
|
|
18
|
+
/>
|
|
19
|
+
</span>
|
|
20
|
+
|
|
21
|
+
{{yield to="endDateControl"}}
|
|
22
|
+
</div>
|