@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.
Files changed (60) hide show
  1. package/addon/components/eui-field-text/index.hbs +1 -0
  2. package/addon/components/eui-global-toast-list/index.ts +1 -1
  3. package/addon/components/eui-i18n/index.ts +9 -41
  4. package/addon/components/eui-super-date-picker/date-popover/absolute-tab.hbs +42 -0
  5. package/addon/components/eui-super-date-picker/date-popover/absolute-tab.ts +79 -0
  6. package/addon/components/eui-super-date-picker/date-popover/datetime-picker.hbs +125 -0
  7. package/addon/components/eui-super-date-picker/date-popover/datetime-picker.ts +258 -0
  8. package/addon/components/eui-super-date-picker/date-popover/eui-date-popover-button.hbs +49 -0
  9. package/addon/components/eui-super-date-picker/date-popover/eui-date-popover-button.ts +49 -0
  10. package/addon/components/eui-super-date-picker/date-popover/eui-date-popover-content.hbs +42 -0
  11. package/addon/components/eui-super-date-picker/date-popover/eui-date-popover-content.ts +73 -0
  12. package/addon/components/eui-super-date-picker/date-popover/now-tab.hbs +45 -0
  13. package/addon/components/eui-super-date-picker/date-popover/relative-tab.hbs +47 -0
  14. package/addon/components/eui-super-date-picker/date-popover/relative-tab.ts +89 -0
  15. package/addon/components/eui-super-date-picker/eui-date-picker-range.hbs +22 -0
  16. package/addon/components/eui-super-date-picker/eui-quick-select-popover/eui-commonly-used-time-ranges.hbs +42 -0
  17. package/addon/components/eui-super-date-picker/eui-quick-select-popover/eui-quick-select.hbs +154 -0
  18. package/addon/components/eui-super-date-picker/eui-quick-select-popover/eui-quick-select.ts +103 -0
  19. package/addon/components/eui-super-date-picker/eui-quick-select-popover/eui-recently-used.hbs +48 -0
  20. package/addon/components/eui-super-date-picker/eui-quick-select-popover/index.hbs +60 -0
  21. package/addon/components/eui-super-date-picker/eui-quick-select-popover/index.ts +34 -0
  22. package/addon/components/eui-super-date-picker/eui-super-update-button.hbs +43 -0
  23. package/addon/components/eui-super-date-picker/index.hbs +123 -0
  24. package/addon/components/eui-super-date-picker/index.ts +220 -0
  25. package/addon/components/eui-super-date-picker/types/global.d.ts +52 -0
  26. package/addon/components/eui-super-date-picker/utils/date-utils.ts +59 -0
  27. package/addon/components/eui-super-date-picker/utils/index.ts +181 -0
  28. package/addon/components/eui-super-date-picker/utils/pretty-duration.ts +131 -0
  29. package/addon/components/eui-super-date-picker/utils/quick-select.ts +75 -0
  30. package/addon/components/eui-super-date-picker/utils/time-options.ts +216 -0
  31. package/addon/components/text-block/index.hbs +25 -21
  32. package/addon/{components/eui-i18n → i18n}/util.ts +1 -6
  33. package/addon/services/eui-i18n.ts +89 -0
  34. package/addon/utils/markdown/markdown-unified-plugins.d.ts +0 -14
  35. package/app/components/eui-super-date-picker/date-popover/absolute-tab.js +1 -0
  36. package/app/components/eui-super-date-picker/date-popover/datetime-picker.js +1 -0
  37. package/app/components/eui-super-date-picker/date-popover/eui-date-popover-button.js +1 -0
  38. package/app/components/eui-super-date-picker/date-popover/eui-date-popover-content.js +1 -0
  39. package/app/components/eui-super-date-picker/date-popover/now-tab.js +1 -0
  40. package/app/components/eui-super-date-picker/date-popover/relative-tab.js +1 -0
  41. package/app/components/eui-super-date-picker/eui-date-picker-range.js +1 -0
  42. package/app/components/eui-super-date-picker/eui-quick-select-popover/eui-commonly-used-time-ranges.js +1 -0
  43. package/app/components/eui-super-date-picker/eui-quick-select-popover/eui-quick-select.js +1 -0
  44. package/app/components/eui-super-date-picker/eui-quick-select-popover/eui-recently-used.js +1 -0
  45. package/app/components/eui-super-date-picker/eui-quick-select-popover/index.js +1 -0
  46. package/app/components/eui-super-date-picker/eui-super-update-button.js +1 -0
  47. package/app/components/eui-super-date-picker/index.js +1 -0
  48. package/app/services/eui-i18n.js +1 -0
  49. package/docs/forms/super-date-picker/demo/d01-picker.md +90 -0
  50. package/docs/forms/super-date-picker/index.md +16 -0
  51. package/package.json +6 -3
  52. package/tsconfig.json +1 -0
  53. package/addon/i18n/index.ts +0 -8
  54. package/app/i18n/index.js +0 -1
  55. package/docs/templates/super-date-picker/demo/d01-update-button.md +0 -10
  56. package/docs/templates/super-date-picker/demo/d02-quick-select-panels.md +0 -10
  57. package/docs/templates/super-date-picker/demo/d03-sizing.md +0 -10
  58. package/docs/templates/super-date-picker/demo/d04-auto-refresh.md +0 -11
  59. package/docs/templates/super-date-picker/demo/d05-elastic-pattern-with-kql.md +0 -10
  60. 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
+ }