@ember-eui/core 5.8.5 → 5.9.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-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-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/text-block/index.hbs +25 -21
- package/addon/{components/eui-i18n → i18n}/util.ts +1 -6
- 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 +6 -3
- package/tsconfig.json +1 -0
- package/addon/i18n/index.ts +0 -8
- 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,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>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{{#let (unique-id) as |legendId|}}
|
|
2
|
+
<fieldset>
|
|
3
|
+
<EuiTitle
|
|
4
|
+
id={{legendId}}
|
|
5
|
+
@tagName="legend"
|
|
6
|
+
@size="xxxs"
|
|
7
|
+
>
|
|
8
|
+
<EuiI18n
|
|
9
|
+
@token="euiCommonlyUsedTimeRanges.legend"
|
|
10
|
+
@default="Commonly used"
|
|
11
|
+
as |Token|
|
|
12
|
+
>
|
|
13
|
+
<Token as |value|>
|
|
14
|
+
{{value}}
|
|
15
|
+
</Token>
|
|
16
|
+
</EuiI18n>
|
|
17
|
+
</EuiTitle>
|
|
18
|
+
<div class="euiQuickSelectPopover__section">
|
|
19
|
+
<EuiFlexGrid
|
|
20
|
+
aria-labelledby={{legendId}}
|
|
21
|
+
@gutterSize="s"
|
|
22
|
+
@columns="2"
|
|
23
|
+
@direction="column"
|
|
24
|
+
@responsive={{false}}
|
|
25
|
+
@tagName="ul"
|
|
26
|
+
>
|
|
27
|
+
{{#each @commonlyUsedRanges as |range|}}
|
|
28
|
+
<EuiFlexItem
|
|
29
|
+
class="euiQuickSelectPopover__sectionItem"
|
|
30
|
+
@tagName="li"
|
|
31
|
+
>
|
|
32
|
+
<EuiLink
|
|
33
|
+
{{on "click" (fn @applyTime (hash start=range.start end=range.end))}}
|
|
34
|
+
>
|
|
35
|
+
{{range.label}}
|
|
36
|
+
</EuiLink>
|
|
37
|
+
</EuiFlexItem>
|
|
38
|
+
{{/each}}
|
|
39
|
+
</EuiFlexGrid>
|
|
40
|
+
</div>
|
|
41
|
+
</fieldset>
|
|
42
|
+
{{/let}}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
{{#let (unique-id) as |legendId|}}
|
|
2
|
+
<fieldset>
|
|
3
|
+
{{!-- <EuiI18n
|
|
4
|
+
token="euiQuickSelect.legendText"
|
|
5
|
+
default="Quick select a time range"
|
|
6
|
+
>
|
|
7
|
+
{(legendText: string) => (
|
|
8
|
+
// Legend needs to be the first thing in a fieldset, but we want the visible title within the flex.
|
|
9
|
+
// So we hide it, but allow screen readers to see it
|
|
10
|
+
<EuiScreenReaderOnly>
|
|
11
|
+
<legend id={{legendId}} class="euiFormLabel">
|
|
12
|
+
{legendText}
|
|
13
|
+
</legend>
|
|
14
|
+
</EuiScreenReaderOnly>
|
|
15
|
+
)}
|
|
16
|
+
</EuiI18n> --}}
|
|
17
|
+
<EuiFlexGroup
|
|
18
|
+
@responsive={{false}}
|
|
19
|
+
@alignItems="center"
|
|
20
|
+
@justifyContent="spaceBetween"
|
|
21
|
+
@gutterSize="s"
|
|
22
|
+
>
|
|
23
|
+
<EuiFlexItem @grow={{false}}>
|
|
24
|
+
<EuiI18n
|
|
25
|
+
@token="euiQuickSelect.quickSelectTitle"
|
|
26
|
+
@default="Quick select"
|
|
27
|
+
as |Token|
|
|
28
|
+
>
|
|
29
|
+
<Token as |quickSelectTitle|>
|
|
30
|
+
<div aria-hidden class="euiFormLabel">
|
|
31
|
+
{{quickSelectTitle}}
|
|
32
|
+
</div>
|
|
33
|
+
</Token>
|
|
34
|
+
</EuiI18n>
|
|
35
|
+
</EuiFlexItem>
|
|
36
|
+
<EuiFlexItem @grow={{false}}>
|
|
37
|
+
<EuiFlexGroup @alignItems="center" @gutterSize="s" @responsive={{false}}>
|
|
38
|
+
<EuiFlexItem @grow={{false}}>
|
|
39
|
+
<EuiI18n
|
|
40
|
+
@token="euiQuickSelect.previousLabel"
|
|
41
|
+
@default="Previous time window"
|
|
42
|
+
as |Token|
|
|
43
|
+
>
|
|
44
|
+
<Token as |previousLabel|>
|
|
45
|
+
<EuiToolTip @content={{previousLabel}}>
|
|
46
|
+
<EuiButtonIcon
|
|
47
|
+
aria-label={{previousLabel}}
|
|
48
|
+
@iconType="arrowLeft"
|
|
49
|
+
{{on "click" this.stepBackward}}
|
|
50
|
+
/>
|
|
51
|
+
</EuiToolTip>
|
|
52
|
+
</Token>
|
|
53
|
+
</EuiI18n>
|
|
54
|
+
</EuiFlexItem>
|
|
55
|
+
<EuiFlexItem @grow={{false}}>
|
|
56
|
+
<EuiI18n
|
|
57
|
+
@token="euiQuickSelect.nextLabel"
|
|
58
|
+
@default="Next time window"
|
|
59
|
+
as |Token|
|
|
60
|
+
>
|
|
61
|
+
<Token as |nextLabel|>
|
|
62
|
+
<EuiToolTip @content={{nextLabel}}>
|
|
63
|
+
<EuiButtonIcon
|
|
64
|
+
aria-label={{nextLabel}}
|
|
65
|
+
@iconType="arrowRight"
|
|
66
|
+
{{on "click" this.stepForward}}
|
|
67
|
+
/>
|
|
68
|
+
</EuiToolTip>
|
|
69
|
+
</Token>
|
|
70
|
+
</EuiI18n>
|
|
71
|
+
</EuiFlexItem>
|
|
72
|
+
</EuiFlexGroup>
|
|
73
|
+
</EuiFlexItem>
|
|
74
|
+
</EuiFlexGroup>
|
|
75
|
+
<EuiSpacer @size="s" />
|
|
76
|
+
<EuiFlexGroup @gutterSize="s" @responsive={{false}}>
|
|
77
|
+
<EuiFlexItem>
|
|
78
|
+
<EuiI18n
|
|
79
|
+
@token="euiQuickSelect.tenseLabel"
|
|
80
|
+
@default="Time tense"
|
|
81
|
+
as |Token|
|
|
82
|
+
>
|
|
83
|
+
<Token as |tenseLabel|>
|
|
84
|
+
<EuiSelect
|
|
85
|
+
@compressed={{true}}
|
|
86
|
+
@onKeyDown={{this.handleKeyDown}}
|
|
87
|
+
aria-label={{tenseLabel}}
|
|
88
|
+
aria-describedby={{concat this.timeSelectionId " " legendId}}
|
|
89
|
+
@value={{this.timeTense}}
|
|
90
|
+
@options={{@timeOptions.timeTenseOptions}}
|
|
91
|
+
{{on "change" (pick "target.value" (set this "timeTense"))}}
|
|
92
|
+
/>
|
|
93
|
+
</Token>
|
|
94
|
+
</EuiI18n>
|
|
95
|
+
</EuiFlexItem>
|
|
96
|
+
<EuiFlexItem>
|
|
97
|
+
<EuiI18n
|
|
98
|
+
@token="euiQuickSelect.valueLabel"
|
|
99
|
+
@default="Time value"
|
|
100
|
+
as |Token|
|
|
101
|
+
>
|
|
102
|
+
<Token as |valueLabel|>
|
|
103
|
+
<EuiFieldNumber
|
|
104
|
+
@compressed={{true}}
|
|
105
|
+
@onKeyDown={{this.handleKeyDown}}
|
|
106
|
+
aria-describedby={{concat this.timeSelectionId " " legendId}}
|
|
107
|
+
aria-label={{valueLabel}}
|
|
108
|
+
@value={{this.timeValue}}
|
|
109
|
+
@onChange={{this.onTimeValueChange}}
|
|
110
|
+
/>
|
|
111
|
+
</Token>
|
|
112
|
+
</EuiI18n>
|
|
113
|
+
</EuiFlexItem>
|
|
114
|
+
<EuiFlexItem>
|
|
115
|
+
<EuiI18n
|
|
116
|
+
@token="euiQuickSelect.unitLabel"
|
|
117
|
+
@default="Time unit"
|
|
118
|
+
as |Token|
|
|
119
|
+
>
|
|
120
|
+
<Token as |unitLabel|>
|
|
121
|
+
<EuiSelect
|
|
122
|
+
@compressed={{true}}
|
|
123
|
+
@onKeyDown={{this.handleKeyDown}}
|
|
124
|
+
aria-label={{unitLabel}}
|
|
125
|
+
aria-describedby={{concat this.timeSelectionId " " legendId}}
|
|
126
|
+
@value={{this.timeUnits}}
|
|
127
|
+
@options={{@timeOptions.timeUnitsOptions}}
|
|
128
|
+
{{on "change" (pick "target.value" (set this "timeUnits"))}}
|
|
129
|
+
/>
|
|
130
|
+
</Token>
|
|
131
|
+
</EuiI18n>
|
|
132
|
+
</EuiFlexItem>
|
|
133
|
+
<EuiFlexItem @grow={{false}}>
|
|
134
|
+
<EuiButton
|
|
135
|
+
aria-describedby={{concat this.timeSelectionId " " legendId}}
|
|
136
|
+
class="euiQuickSelect__applyButton"
|
|
137
|
+
@size="s"
|
|
138
|
+
@disabled={{lte this.timeValue 0}}
|
|
139
|
+
{{on "click" this.applyQuickSelect}}
|
|
140
|
+
>
|
|
141
|
+
<EuiI18n
|
|
142
|
+
@token="euiQuickSelect.applyButton"
|
|
143
|
+
@default="Apply"
|
|
144
|
+
as |Token|
|
|
145
|
+
>
|
|
146
|
+
<Token as |value|>
|
|
147
|
+
{{value}}
|
|
148
|
+
</Token>
|
|
149
|
+
</EuiI18n>
|
|
150
|
+
</EuiButton>
|
|
151
|
+
</EuiFlexItem>
|
|
152
|
+
</EuiFlexGroup>
|
|
153
|
+
</fieldset>
|
|
154
|
+
{{/let}}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { action } from '@ember/object';
|
|
2
|
+
import Component from '@glimmer/component';
|
|
3
|
+
import { tracked } from '@glimmer/tracking';
|
|
4
|
+
import { ApplyTime, TimeUnitId } from '../types/global';
|
|
5
|
+
import { parseTimeParts } from '../utils/quick-select';
|
|
6
|
+
import { NEXT, TimeOptions } from '../utils/time-options';
|
|
7
|
+
import moment from 'moment';
|
|
8
|
+
import dateMath from '@elastic/datemath';
|
|
9
|
+
|
|
10
|
+
interface EuiQuickSelectState {
|
|
11
|
+
timeTense: string;
|
|
12
|
+
timeValue: number;
|
|
13
|
+
timeUnits: TimeUnitId;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface EuiQuickSelectArgs {
|
|
17
|
+
applyTime: ApplyTime;
|
|
18
|
+
start: string;
|
|
19
|
+
end: string;
|
|
20
|
+
prevQuickSelect?: EuiQuickSelectState;
|
|
21
|
+
timeOptions: TimeOptions;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default class EuiQuickSelect extends Component<EuiQuickSelectArgs> {
|
|
25
|
+
@tracked timeTense: string;
|
|
26
|
+
@tracked timeValue: number;
|
|
27
|
+
@tracked timeUnits: TimeUnitId;
|
|
28
|
+
|
|
29
|
+
constructor(owner: unknown, args: EuiQuickSelectArgs) {
|
|
30
|
+
super(owner, args);
|
|
31
|
+
|
|
32
|
+
const {
|
|
33
|
+
timeTense: timeTenseDefault,
|
|
34
|
+
timeUnits: timeUnitsDefault,
|
|
35
|
+
timeValue: timeValueDefault
|
|
36
|
+
} = parseTimeParts(this.args.start, this.args.end);
|
|
37
|
+
|
|
38
|
+
this.timeTense =
|
|
39
|
+
this.args.prevQuickSelect && this.args.prevQuickSelect.timeTense
|
|
40
|
+
? this.args.prevQuickSelect.timeTense
|
|
41
|
+
: timeTenseDefault;
|
|
42
|
+
this.timeValue =
|
|
43
|
+
this.args.prevQuickSelect && this.args.prevQuickSelect.timeValue
|
|
44
|
+
? this.args.prevQuickSelect.timeValue
|
|
45
|
+
: timeValueDefault;
|
|
46
|
+
this.timeUnits =
|
|
47
|
+
this.args.prevQuickSelect && this.args.prevQuickSelect.timeUnits
|
|
48
|
+
? this.args.prevQuickSelect.timeUnits
|
|
49
|
+
: timeUnitsDefault;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
getBounds() {
|
|
53
|
+
const startMoment = dateMath.parse(this.args.start);
|
|
54
|
+
const endMoment = dateMath.parse(this.args.end, { roundUp: true });
|
|
55
|
+
return {
|
|
56
|
+
min:
|
|
57
|
+
startMoment && startMoment.isValid()
|
|
58
|
+
? startMoment
|
|
59
|
+
: moment().subtract(15, 'minute'),
|
|
60
|
+
max: endMoment && endMoment.isValid() ? endMoment : moment()
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@action applyQuickSelect() {
|
|
65
|
+
if (this.timeTense === NEXT) {
|
|
66
|
+
this.args.applyTime({
|
|
67
|
+
start: 'now',
|
|
68
|
+
end: `now+${this.timeValue}${this.timeUnits}`
|
|
69
|
+
// quickSelect: { ...this.state },
|
|
70
|
+
});
|
|
71
|
+
} else {
|
|
72
|
+
this.args.applyTime({
|
|
73
|
+
start: `now-${this.timeValue}${this.timeUnits}`,
|
|
74
|
+
end: 'now'
|
|
75
|
+
// quickSelect: { ...this.state },
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@action stepForward() {
|
|
81
|
+
const { min, max } = this.getBounds();
|
|
82
|
+
const diff = max.diff(min);
|
|
83
|
+
this.args.applyTime({
|
|
84
|
+
start: moment(max).add(1, 'ms').toISOString(),
|
|
85
|
+
end: moment(max)
|
|
86
|
+
.add(diff + 1, 'ms')
|
|
87
|
+
.toISOString(),
|
|
88
|
+
keepPopoverOpen: true
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@action stepBackward() {
|
|
93
|
+
const { min, max } = this.getBounds();
|
|
94
|
+
const diff = max.diff(min);
|
|
95
|
+
this.args.applyTime({
|
|
96
|
+
start: moment(min)
|
|
97
|
+
.subtract(diff + 1, 'ms')
|
|
98
|
+
.toISOString(),
|
|
99
|
+
end: moment(min).subtract(1, 'ms').toISOString(),
|
|
100
|
+
keepPopoverOpen: true
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|