@elastic/eui
Version:
Elastic UI Component Library
280 lines (266 loc) • 10.7 kB
JavaScript
/*
* 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, isRelativeToNow } 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;
});
};
export var showPrettyDuration = function showPrettyDuration(timeFrom, timeTo, quickRanges) {
if (hasRangeMatch(timeFrom, timeTo, quickRanges)) {
return true;
}
return isRelativeToNow(timeFrom, timeTo);
};