UNPKG

@elastic/eui

Version:

Elastic UI Component Library

287 lines (273 loc) 11 kB
/* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0 and the Server Side Public License, v 1; you may not use this file except * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ import React from 'react'; import dateMath from '@elastic/datemath'; import moment from 'moment'; // eslint-disable-line import/named import { useEuiI18n } from '../../i18n'; import { getDateMode, DATE_MODES } from './date_modes'; import { parseRelativeParts } from './relative_utils'; import { useI18nTimeOptions } from './time_options'; import { jsx as ___EmotionJSX } from "@emotion/react"; /** * Pretty duration i18n strings * Units should not be simply concatenated because different languages * will have different grammar/positions for time than English */ var useRelativeDurationI18n = function useRelativeDurationI18n(duration) { return { s: useEuiI18n('euiPrettyDuration.lastDurationSeconds', function (_ref) { var duration = _ref.duration; return "Last ".concat(duration, " second").concat(duration === 1 ? '' : 's'); }, { duration: duration }), 's+': useEuiI18n('euiPrettyDuration.nextDurationSeconds', function (_ref2) { var duration = _ref2.duration; return "Next ".concat(duration, " second").concat(duration === 1 ? '' : 's'); }, { duration: duration }), m: useEuiI18n('euiPrettyDuration.lastDurationMinutes', function (_ref3) { var duration = _ref3.duration; return "Last ".concat(duration, " minute").concat(duration === 1 ? '' : 's'); }, { duration: duration }), 'm+': useEuiI18n('euiPrettyDuration.nextDurationMinutes', function (_ref4) { var duration = _ref4.duration; return "Next ".concat(duration, " minute").concat(duration === 1 ? '' : 's'); }, { duration: duration }), h: useEuiI18n('euiPrettyDuration.lastDurationHours', function (_ref5) { var duration = _ref5.duration; return "Last ".concat(duration, " hour").concat(duration === 1 ? '' : 's'); }, { duration: duration }), 'h+': useEuiI18n('euiPrettyDuration.nextDurationHours', function (_ref6) { var duration = _ref6.duration; return "Next ".concat(duration, " hour").concat(duration === 1 ? '' : 's'); }, { duration: duration }), d: useEuiI18n('euiPrettyDuration.lastDurationDays', function (_ref7) { var duration = _ref7.duration; return "Last ".concat(duration, " day").concat(duration === 1 ? '' : 's'); }, { duration: duration }), 'd+': useEuiI18n('euiPrettyDuration.nexttDurationDays', function (_ref8) { var duration = _ref8.duration; return "Next ".concat(duration, " day").concat(duration === 1 ? '' : 's'); }, { duration: duration }), w: useEuiI18n('euiPrettyDuration.lastDurationWeeks', function (_ref9) { var duration = _ref9.duration; return "Last ".concat(duration, " week").concat(duration === 1 ? '' : 's'); }, { duration: duration }), 'w+': useEuiI18n('euiPrettyDuration.nextDurationWeeks', function (_ref10) { var duration = _ref10.duration; return "Next ".concat(duration, " week").concat(duration === 1 ? '' : 's'); }, { duration: duration }), M: useEuiI18n('euiPrettyDuration.lastDurationMonths', function (_ref11) { var duration = _ref11.duration; return "Last ".concat(duration, " month").concat(duration === 1 ? '' : 's'); }, { duration: duration }), 'M+': useEuiI18n('euiPrettyDuration.nextDurationMonths', function (_ref12) { var duration = _ref12.duration; return "Next ".concat(duration, " month").concat(duration === 1 ? '' : 's'); }, { duration: duration }), y: useEuiI18n('euiPrettyDuration.lastDurationYears', function (_ref13) { var duration = _ref13.duration; return "Last ".concat(duration, " year").concat(duration === 1 ? '' : 's'); }, { duration: duration }), 'y+': useEuiI18n('euiPrettyDuration.nextDurationYears', function (_ref14) { var duration = _ref14.duration; return "Next ".concat(duration, " year").concat(duration === 1 ? '' : 's'); }, { duration: duration }) }; }; var useRelativeDurationRoundedI18n = function useRelativeDurationRoundedI18n(prettyDuration) { return { s: useEuiI18n('euiPrettyDuration.durationRoundedToSecond', '{prettyDuration} rounded to the second', { prettyDuration: prettyDuration }), m: useEuiI18n('euiPrettyDuration.durationRoundedToMinute', '{prettyDuration} rounded to the minute', { prettyDuration: prettyDuration }), h: useEuiI18n('euiPrettyDuration.durationRoundedToHour', '{prettyDuration} rounded to the hour', { prettyDuration: prettyDuration }), d: useEuiI18n('euiPrettyDuration.durationRoundedToDay', '{prettyDuration} rounded to the day', { prettyDuration: prettyDuration }), w: useEuiI18n('euiPrettyDuration.durationRoundedToWeek', '{prettyDuration} rounded to the week', { prettyDuration: prettyDuration }), M: useEuiI18n('euiPrettyDuration.durationRoundedToMonth', '{prettyDuration} rounded to the month', { prettyDuration: prettyDuration }), y: useEuiI18n('euiPrettyDuration.durationRoundedToYear', '{prettyDuration} rounded to the year', { prettyDuration: prettyDuration }) }; }; /** * Reusable format time string util */ var ISO_FORMAT = 'YYYY-MM-DDTHH:mm:ss.SSSZ'; export var useFormatTimeString = function useFormatTimeString(timeString, dateFormat, options) { var _ref15 = options || {}, _ref15$locale = _ref15.locale, locale = _ref15$locale === void 0 ? 'en' : _ref15$locale, _ref15$roundUp = _ref15.roundUp, roundUp = _ref15$roundUp === void 0 ? false : _ref15$roundUp, _ref15$canRoundRelati = _ref15.canRoundRelativeUnits, canRoundRelativeUnits = _ref15$canRoundRelati === void 0 ? true : _ref15$canRoundRelati; // i18n'd strings var nowDisplay = useEuiI18n('euiPrettyDuration.now', 'now'); var invalidDateDisplay = useEuiI18n('euiPrettyDuration.invalid', 'Invalid date'); var timeAsMoment = moment(timeString, ISO_FORMAT, true); if (timeAsMoment.isValid()) { return timeAsMoment.locale(locale).format(dateFormat); } if (timeString === 'now') { return nowDisplay; } var tryParse = dateMath.parse(timeString, { roundUp: roundUp }); if (!moment(tryParse).isValid()) { return invalidDateDisplay; } if (moment.isMoment(tryParse)) { if (canRoundRelativeUnits) { return "~ ".concat(tryParse.locale(locale).fromNow()); } else { // To force a specific unit to be used, we need to skip moment.fromNow() // entirely and write our own custom moment formatted output. var _parseRelativeParts = parseRelativeParts(timeString), count = _parseRelativeParts.count, _unit = _parseRelativeParts.unit; var isFuture = _unit.endsWith('+'); var unit = isFuture ? _unit.slice(0, -1) : _unit; // We want just the unit letter without the trailing + // @see https://momentjs.com/docs/#/customization/relative-time/ var relativeUnitKey = count === 1 ? unit : unit + unit; // @see https://momentjs.com/docs/#/i18n/locale-data/ return moment.localeData().pastFuture(isFuture ? count : count * -1, moment.localeData().relativeTime(count, false, relativeUnitKey, false) // Booleans don't seem to actually matter for output, .pastFuture() handles that ); } } return timeString; }; /** * Pretty duration hook+component */ export var usePrettyDuration = function usePrettyDuration(_ref16) { var timeFrom = _ref16.timeFrom, timeTo = _ref16.timeTo, quickRanges = _ref16.quickRanges, dateFormat = _ref16.dateFormat; var prettyDuration = ''; /** * If it's a quick range, use the quick range label */ var _useI18nTimeOptions = useI18nTimeOptions(), commonDurationRanges = _useI18nTimeOptions.commonDurationRanges; var matchingQuickRange = hasRangeMatch(timeFrom, timeTo, quickRanges || commonDurationRanges); if (matchingQuickRange && matchingQuickRange.label) { prettyDuration = matchingQuickRange.label; } /** * Otherwise if it's a relative (possibly rounded) duration, figure out * a pretty i18n'd duration to display */ var relativeDuration = 0; var relativeParts = {}; if (isRelativeToNow(timeFrom, timeTo)) { if (getDateMode(timeTo) === DATE_MODES.NOW) { relativeParts = parseRelativeParts(timeFrom); } else { relativeParts = parseRelativeParts(timeTo); } relativeDuration = relativeParts.count; } var relativeDurationI18n = useRelativeDurationI18n(relativeDuration); var relativeDurationString = relativeParts.unit ? relativeDurationI18n[relativeParts.unit] : ''; var roundedDurationI18n = useRelativeDurationRoundedI18n(relativeDurationString); var roundedDurationString = relativeParts.round && relativeParts.roundUnit ? roundedDurationI18n[relativeParts.roundUnit] : ''; if (!prettyDuration) { prettyDuration = roundedDurationString || relativeDurationString; } /** * If it's none of the above, display basic fallback copy */ var displayFrom = useFormatTimeString(timeFrom, dateFormat); var displayTo = useFormatTimeString(timeTo, dateFormat, { roundUp: true }); var fallbackDuration = useEuiI18n('euiPrettyDuration.fallbackDuration', '{displayFrom} to {displayTo}', { displayFrom: displayFrom, displayTo: displayTo }); if (!prettyDuration) { prettyDuration = fallbackDuration; } return prettyDuration; }; export var PrettyDuration = function PrettyDuration(_ref17) { var timeFrom = _ref17.timeFrom, timeTo = _ref17.timeTo, quickRanges = _ref17.quickRanges, dateFormat = _ref17.dateFormat; var prettyDuration = usePrettyDuration({ timeFrom: timeFrom, timeTo: timeTo, quickRanges: quickRanges, dateFormat: dateFormat }); return ___EmotionJSX(React.Fragment, null, prettyDuration); }; /** * Non-hook utils */ var hasRangeMatch = function hasRangeMatch(timeFrom, timeTo, ranges) { return ranges.find(function (_ref18) { var start = _ref18.start, end = _ref18.end; return timeFrom === start && timeTo === end; }); }; var isRelativeToNow = function isRelativeToNow(timeFrom, timeTo) { var fromDateMode = getDateMode(timeFrom); var toDateMode = getDateMode(timeTo); var isLast = fromDateMode === DATE_MODES.RELATIVE && toDateMode === DATE_MODES.NOW; var isNext = fromDateMode === DATE_MODES.NOW && toDateMode === DATE_MODES.RELATIVE; return isLast || isNext; }; export var showPrettyDuration = function showPrettyDuration(timeFrom, timeTo, quickRanges) { if (hasRangeMatch(timeFrom, timeTo, quickRanges)) { return true; } return isRelativeToNow(timeFrom, timeTo); };