UNPKG

@elastic/eui

Version:

Elastic UI Component Library

256 lines (250 loc) 11.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ZOOM_FACTOR_DEFAULT = exports.ZOOM_DELTA_FALLBACK_MS = exports.EuiTimeWindowButtons = void 0; exports.useEuiTimeWindow = useEuiTimeWindow; var _react = _interopRequireDefault(require("react")); var _datemath = _interopRequireDefault(require("@elastic/datemath")); var _moment = _interopRequireDefault(require("moment")); var _pretty_interval = require("./pretty_interval"); var _relative_utils = require("./relative_utils"); var _button_group_button = require("../../button/button_group/button_group_button"); var _button_group = require("../../button/button_group/button_group.styles"); var _services = require("../../../services"); var _i18n = require("../../i18n"); var _react2 = require("@emotion/react"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /* * 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. */ var ZOOM_FACTOR_DEFAULT = exports.ZOOM_FACTOR_DEFAULT = 0.5; var ZOOM_DELTA_FALLBACK_MS = exports.ZOOM_DELTA_FALLBACK_MS = 500; /** * Button group with time window controls for shifting the time window * forwards and backwards, and zooming out. */ var EuiTimeWindowButtons = exports.EuiTimeWindowButtons = function EuiTimeWindowButtons(_ref) { var applyTime = _ref.applyTime, start = _ref.start, end = _ref.end, compressed = _ref.compressed, isDisabled = _ref.isDisabled, _ref$showZoomOut = _ref.showZoomOut, showZoomOut = _ref$showZoomOut === void 0 ? true : _ref$showZoomOut, _ref$showZoomIn = _ref.showZoomIn, showZoomIn = _ref$showZoomIn === void 0 ? false : _ref$showZoomIn, _ref$showShiftArrows = _ref.showShiftArrows, showShiftArrows = _ref$showShiftArrows === void 0 ? true : _ref$showShiftArrows, _ref$zoomFactor = _ref.zoomFactor, zoomFactor = _ref$zoomFactor === void 0 ? ZOOM_FACTOR_DEFAULT : _ref$zoomFactor; var buttonColor = 'text'; var buttonSize = compressed ? 's' : 'm'; var iconSize = 'm'; var styles = (0, _services.useEuiMemoizedStyles)(_button_group.euiButtonGroupButtonsStyles); var _useEuiTimeWindow = useEuiTimeWindow(start, end, applyTime, { zoomFactor: zoomFactor }), displayInterval = _useEuiTimeWindow.displayInterval, isInvalid = _useEuiTimeWindow.isInvalid, stepForward = _useEuiTimeWindow.stepForward, stepBackward = _useEuiTimeWindow.stepBackward, expandWindow = _useEuiTimeWindow.expandWindow, shrinkWindow = _useEuiTimeWindow.shrinkWindow, isWindowDurationZero = _useEuiTimeWindow.isWindowDurationZero; var previousDescription = (0, _i18n.useEuiI18n)('euiTimeWindowButtons.previousDescription', 'Previous {displayInterval}', { displayInterval: displayInterval }); var nextDescription = (0, _i18n.useEuiI18n)('euiTimeWindowButtons.nextDescription', 'Next {displayInterval}', { displayInterval: displayInterval }); var invalidShiftDescription = (0, _i18n.useEuiI18n)('euiTimeWindowButtons.invalidShiftLabel', 'Cannot shift invalid time window'); var invalidZoomInDescription = (0, _i18n.useEuiI18n)('euiTimeWindowButtons.invalidZoomInLabel', 'Cannot zoom in invalid time window'); var cannotZoomInDescription = (0, _i18n.useEuiI18n)('euiTimeWindowButtons.cannotZoomInLabel', 'Cannot zoom in any further'); var invalidZoomOutDescription = (0, _i18n.useEuiI18n)('euiTimeWindowButtons.invalidZoomOutLabel', 'Cannot zoom out invalid time window'); var previousId = (0, _services.useGeneratedHtmlId)({ prefix: 'previous' }); var previousLabel = (0, _i18n.useEuiI18n)('euiTimeWindowButtons.previousLabel', 'Previous'); var previousTooltipContent = isInvalid ? invalidShiftDescription : previousDescription; var zoomInId = (0, _services.useGeneratedHtmlId)({ prefix: 'zoom_in' }); var zoomInLabel = (0, _i18n.useEuiI18n)('euiTimeWindowButtons.zoomInLabel', 'Zoom in'); var zoomInTooltipContent = isInvalid ? invalidZoomInDescription : isWindowDurationZero ? cannotZoomInDescription : zoomInLabel; var zoomOutId = (0, _services.useGeneratedHtmlId)({ prefix: 'zoom_out' }); var zoomOutLabel = (0, _i18n.useEuiI18n)('euiTimeWindowButtons.zoomOutLabel', 'Zoom out'); var zoomOutTooltipContent = isInvalid ? invalidZoomOutDescription : zoomOutLabel; var nextId = (0, _services.useGeneratedHtmlId)({ prefix: 'next' }); var nextLabel = (0, _i18n.useEuiI18n)('euiTimeWindowButtons.nextLabel', 'Next'); var nextTooltipContent = isInvalid ? invalidShiftDescription : nextDescription; if (!showZoomIn && !showZoomOut && !showShiftArrows) return null; return (0, _react2.jsx)("div", { className: "euiSuperDatePicker__timeWindowButtons", css: [styles.euiButtonGroup__buttons, styles[buttonSize], ";label:EuiTimeWindowButtons;"], "data-test-subj": "timeWindowButtons" }, showShiftArrows && (0, _react2.jsx)(_button_group_button.EuiButtonGroupButton, { id: previousId, "data-test-subj": "timeWindowButtonsPrevious", label: previousLabel, title: "", toolTipContent: !isDisabled && previousTooltipContent, color: buttonColor, size: buttonSize, iconType: "chevronSingleLeft", iconSize: iconSize, isIconOnly: true, isDisabled: isWindowDurationZero || isDisabled, onClick: stepBackward }), showZoomIn && (0, _react2.jsx)(_button_group_button.EuiButtonGroupButton, { id: zoomInId, "data-test-subj": "timeWindowButtonsZoomIn", label: zoomInLabel, title: "", toolTipContent: !isDisabled && zoomInTooltipContent, toolTipProps: { disableScreenReaderOutput: zoomInLabel === zoomInTooltipContent }, color: buttonColor, size: buttonSize, iconType: "magnifyPlus", iconSize: iconSize, isIconOnly: true, isDisabled: isWindowDurationZero || isDisabled, onClick: shrinkWindow }), showZoomOut && (0, _react2.jsx)(_button_group_button.EuiButtonGroupButton, { id: zoomOutId, "data-test-subj": "timeWindowButtonsZoomOut", label: zoomOutLabel, title: "", toolTipContent: !isDisabled && zoomOutTooltipContent, toolTipProps: { disableScreenReaderOutput: zoomOutLabel === zoomOutTooltipContent }, color: buttonColor, size: buttonSize, iconType: "magnifyMinus", iconSize: iconSize, isIconOnly: true, isDisabled: isDisabled, onClick: expandWindow }), showShiftArrows && (0, _react2.jsx)(_button_group_button.EuiButtonGroupButton, { id: nextId, "data-test-subj": "timeWindowButtonsNext", label: nextLabel, title: "", toolTipContent: !isDisabled && nextTooltipContent, color: buttonColor, size: buttonSize, iconType: "chevronSingleRight", iconSize: iconSize, isIconOnly: true, isDisabled: isWindowDurationZero || isDisabled, onClick: stepForward })); }; /** * Partly adapted from date_picker/super_date_picker/quick_select_popover/quick_select.tsx */ function useEuiTimeWindow(start, end, apply, options) { var _options$zoomFactor; var min = _datemath.default.parse(start); /* `roundUp: true` will result in an "inclusive" time (e.g. 23:59:59.999 for 'now/d'). It only changes the value for relative expressions (e.g. 'now/d') but not absolute ISO strings. */ var max = _datemath.default.parse(end, { roundUp: true }); var isInvalid = !min || !min.isValid() || !max || !max.isValid(); /* An end at .999ms is always considered an inclusive boundary (either as result of `roundUp: true` or entered manually). To avoid a 1ms drift on every time window or zoom step, windowDuration has to be increased by 1ms. This ensures the window is always at a clean boundary (e.g. 00:00:00.000 - 23:59:59.999). */ var isInclusiveBoundary = !isInvalid && max.milliseconds() === 999; var endBoundary = !isInvalid ? isInclusiveBoundary ? (0, _moment.default)(max).add(1, 'ms') : (0, _moment.default)(max) : null; var windowDuration = isInvalid || !endBoundary ? -1 : endBoundary.diff(min); var isWindowDurationZero = windowDuration === 0; var zoomFactor = getPercentageMultiplier((_options$zoomFactor = options === null || options === void 0 ? void 0 : options.zoomFactor) !== null && _options$zoomFactor !== void 0 ? _options$zoomFactor : ZOOM_FACTOR_DEFAULT); var zoomDelta = windowDuration * (zoomFactor / 2); // Gets added to each end, that's why it's split in half var prettyInterval = (0, _pretty_interval.usePrettyInterval)(false, windowDuration); var displayInterval = isInvalid ? '' : prettyInterval; if (!isInvalid && !(0, _relative_utils.isRelativeToNow)(start, end) && !isExactMinuteRange(windowDuration)) { displayInterval = "~".concat(displayInterval); } return { displayInterval: displayInterval, isInvalid: isInvalid, stepForward: stepForward, stepBackward: stepBackward, expandWindow: expandWindow, shrinkWindow: shrinkWindow, isWindowDurationZero: isWindowDurationZero }; function stepForward() { if (isInvalid || isWindowDurationZero) return; apply({ /* Prevent 1ms drifts for inclusive boundaries by using the exclusive max (+ 1ms) as the start of the next window (e.g. 00:00:00.000 instead of 23:59:59.999) */ start: (isInclusiveBoundary ? endBoundary // `!` is safe here because we early return on `isInvalid` : (0, _moment.default)(max)).toISOString(), end: (0, _moment.default)(max).add(windowDuration, 'ms').toISOString() }); } function stepBackward() { if (isInvalid || isWindowDurationZero) return; apply({ start: (0, _moment.default)(min).subtract(windowDuration, 'ms').toISOString(), /* Prevent 1ms drifts for inclusive boundaries by using the exclusive min (- 1ms) as the end of the previous window (e.g. 23:59:59.999 instead of 00:00:00.000) */ end: (isInclusiveBoundary ? (0, _moment.default)(min).subtract(1, 'ms') : (0, _moment.default)(min)).toISOString() }); } function expandWindow() { if (isInvalid) return; // when the window is 0 it'll remain 0 unless we help it a little var addition = zoomDelta === 0 ? ZOOM_DELTA_FALLBACK_MS : zoomDelta; apply({ start: (0, _moment.default)(min).subtract(addition, 'ms').toISOString(), end: (0, _moment.default)(max).add(addition, 'ms').toISOString() }); } function shrinkWindow() { if (isInvalid || isWindowDurationZero) return; apply({ start: (0, _moment.default)(min).add(zoomDelta, 'ms').toISOString(), end: (0, _moment.default)(max).subtract(zoomDelta, 'ms').toISOString() }); } } /** * Convert strings with % to a multiplier e.g. "50%" = 0.5 * Strings without % are returned as-is as number */ function getPercentageMultiplier(value) { if (typeof value === 'string' && value.includes('%')) { var parsed = parseFloat(value.replace('%', '').trim()); if (isNaN(parsed)) { throw new TypeError('Invalid percentage string'); } return parsed / 100; } var result = typeof value === 'number' ? value : parseFloat(String(value)); if (isNaN(result)) { throw new TypeError('Please provide a valid number or percentage string e.g. "25%"'); } return result; } /** * Useful to determine whether to show the tilde in the display */ function isExactMinuteRange(diffMs) { // 60 * 1000 = ms per minute return diffMs % (60 * 1000) === 0; }