diff --git a/CHANGELOG.md b/CHANGELOG.md index dcfc7e59ea5..97848458071 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ **Bug Fixes** - Fixed EuiBasicTable proptypes of itemId ([#3133](https://github.com/elastic/eui/pull/3133)) +- Updated `EuiSuperDatePicker` to inherit the selected value in quick select ([#3105](https://github.com/elastic/eui/pull/3105)) ## [`22.1.0`](https://github.com/elastic/eui/tree/v22.1.0) @@ -2971,4 +2972,4 @@ instead of just string ([#516](https://github.com/elastic/eui/pull/516)) ## [`0.0.1`](https://github.com/elastic/eui/tree/v0.0.1) Initial Release -- Initial public release +- Initial public release \ No newline at end of file diff --git a/src/components/date_picker/super_date_picker/quick_select_popover/quick_select.js b/src/components/date_picker/super_date_picker/quick_select_popover/quick_select.js index 08a1cc5322e..5e7de8ff3f5 100644 --- a/src/components/date_picker/super_date_picker/quick_select_popover/quick_select.js +++ b/src/components/date_picker/super_date_picker/quick_select_popover/quick_select.js @@ -12,6 +12,7 @@ import { EuiHorizontalRule } from '../../../horizontal_rule'; import { EuiI18n } from '../../../i18n'; import { timeUnits } from '../time_units'; import { EuiScreenReaderOnly } from '../../../accessibility'; +import { parseTimeParts } from './quick_select_utils'; const LAST = 'last'; const NEXT = 'next'; @@ -29,10 +30,15 @@ export class EuiQuickSelect extends Component { super(props); const { timeTense, timeValue, timeUnits } = this.props.prevQuickSelect; + const { + timeTenseDefault, + timeValueDefault, + timeUnitsDefault, + } = parseTimeParts(this.props.start, this.props.end); this.state = { - timeTense: timeTense ? timeTense : LAST, - timeValue: timeValue ? timeValue : 15, - timeUnits: timeUnits ? timeUnits : 'm', + timeTense: timeTense ? timeTense : timeTenseDefault, + timeValue: timeValue ? timeValue : timeValueDefault, + timeUnits: timeUnits ? timeUnits : timeUnitsDefault, }; } diff --git a/src/components/date_picker/super_date_picker/quick_select_popover/quick_select_utils.js b/src/components/date_picker/super_date_picker/quick_select_popover/quick_select_utils.js new file mode 100644 index 00000000000..8b88f7ebb62 --- /dev/null +++ b/src/components/date_picker/super_date_picker/quick_select_popover/quick_select_utils.js @@ -0,0 +1,72 @@ +/** + * This function returns time value, time unit and time tense for a given time string. + * For example: for `now-40m` it will parse output as time value to `40` + * time unit to `m` and time unit to `last`. + * If given a datetime string it will return a default value. + * If the given string is in the format such as `now/d` it will parse the string to moment object + * and find the time value, time unit and time tense using moment + * This function accepts two strings start and end time. I the start value is now then it uses + * the end value to parse. + * + * @param {string} start start time + * @param {string} start end time + * @returns {object} time value, time unit and time tense + */ + +import moment from 'moment'; +import dateMath from '@elastic/datemath'; +import { isString } from '../../../../services/predicate'; +import { relativeUnitsFromLargestToSmallest } from '../relative_options'; +import { DATE_MODES } from '../date_modes'; + +const LAST = 'last'; +const NEXT = 'next'; + +const isNow = value => value === DATE_MODES.NOW; + +export const parseTimeParts = (start, end) => { + const results = { + timeValueDefault: 15, + timeUnitsDefault: 'm', + timeTenseDefault: LAST, + }; + + const value = isNow(start) ? end : start; + + const matches = + isString(value) && + value.match(/now(([-+])(\d+)([smhdwMy])(\/[smhdwMy])?)?/); + + if (!matches) { + return results; + } + + const operator = matches[2]; + const timeValue = matches[3]; + const timeUnitsDefault = matches[4]; + + if (timeValue && timeUnitsDefault && operator) { + const timeValueDefault = parseInt(timeValue, 10); + const timeTenseDefault = operator === '+' ? NEXT : LAST; + + return { + timeValueDefault, + timeUnitsDefault, + timeTenseDefault, + }; + } + + const duration = moment.duration(moment().diff(dateMath.parse(value))); + let unitOp = ''; + for (let i = 0; i < relativeUnitsFromLargestToSmallest.length; i++) { + const as = duration.as(relativeUnitsFromLargestToSmallest[i]); + if (as < 0) unitOp = '+'; + if (Math.abs(as) > 1) { + results.timeValueDefault = Math.round(Math.abs(as)); + results.timeUnitsDefault = relativeUnitsFromLargestToSmallest[i]; + results.timeTenseDefault = unitOp === '+' ? NEXT : LAST; + break; + } + } + return results; +}; diff --git a/src/components/date_picker/super_date_picker/quick_select_popover/quick_select_utils.test.js b/src/components/date_picker/super_date_picker/quick_select_popover/quick_select_utils.test.js new file mode 100644 index 00000000000..1a104afd8ef --- /dev/null +++ b/src/components/date_picker/super_date_picker/quick_select_popover/quick_select_utils.test.js @@ -0,0 +1,51 @@ +import moment from 'moment'; +import { parseTimeParts } from './quick_select_utils'; + +describe('parseTimeParts', () => { + it('should parse now', () => { + const out = parseTimeParts('now', 'now+5m'); + expect(out).toEqual({ + timeValueDefault: 5, + timeUnitsDefault: 'm', + timeTenseDefault: 'next', + }); + }); + + it('should parse now-2h', () => { + const out = parseTimeParts('now-2h', 'now+5m'); + expect(out).toEqual({ + timeValueDefault: 2, + timeUnitsDefault: 'h', + timeTenseDefault: 'last', + }); + }); + + it('should parse now+2h', () => { + const out = parseTimeParts('now+2h', 'now+5m'); + expect(out).toEqual({ + timeValueDefault: 2, + timeUnitsDefault: 'h', + timeTenseDefault: 'next', + }); + }); + + describe('duration parsing', () => { + const duration = moment.duration; + beforeEach(() => { + moment.duration = () => duration(6 * 60 * 60 * 1000); + }); + + afterEach(() => { + moment.duration = duration; + }); + + it('should parse now/d', () => { + const out = parseTimeParts('now/d', 'now+5m'); + expect(out).toEqual({ + timeValueDefault: 6, + timeUnitsDefault: 'h', + timeTenseDefault: 'last', + }); + }); + }); +});