UNPKG

@grafana/ui

Version:
263 lines (260 loc) • 9.4 kB
import { jsxs, jsx, Fragment } from 'react/jsx-runtime'; import { cx, css } from '@emotion/css'; import { useDialog } from '@react-aria/dialog'; import { FocusScope } from '@react-aria/focus'; import { useOverlay } from '@react-aria/overlays'; import { useState, useEffect, createRef, memo } from 'react'; import { getTimeZoneInfo, dateTimeFormat, timeZoneFormatUserFriendly, rangeUtil, dateMath } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { t, Trans } from '@grafana/i18n'; import { useStyles2 } from '../../themes/ThemeContext.mjs'; import { ButtonGroup } from '../Button/ButtonGroup.mjs'; import { getModalStyles } from '../Modal/getModalStyles.mjs'; import { getPortalContainer } from '../Portal/Portal.mjs'; import { ToolbarButton } from '../ToolbarButton/ToolbarButton.mjs'; import { Tooltip } from '../Tooltip/Tooltip.mjs'; import { TimePickerContent } from './TimeRangePicker/TimePickerContent.mjs'; import { TimeZoneDescription } from './TimeZonePicker/TimeZoneDescription.mjs'; import { getQuickOptions } from './options.mjs'; import { useTimeSync } from './utils/useTimeSync.mjs'; "use strict"; function TimeRangePicker(props) { var _a; const [isOpen, setOpen] = useState(false); const { value, onMoveBackward, onMoveForward, moveForwardTooltip, moveBackwardTooltip, onZoom, onError, timeZone, fiscalYearStartMonth, history, onChangeTimeZone, onChangeFiscalYearStartMonth, quickRanges, hideQuickRanges, widthOverride, isOnCanvas, onToolbarTimePickerClick, weekStart, initialIsSynced } = props; const { onChangeWithSync, isSynced, timeSyncButton } = useTimeSync({ initialIsSynced, value, onChangeProp: props.onChange, isSyncedProp: props.isSynced, timeSyncButtonProp: props.timeSyncButton }); const onChange = (timeRange) => { onChangeWithSync(timeRange); setOpen(false); }; useEffect(() => { if (isOpen && onToolbarTimePickerClick) { onToolbarTimePickerClick(); } }, [isOpen, onToolbarTimePickerClick]); const onToolbarButtonSwitch = () => { setOpen((prevState) => !prevState); }; const onClose = () => { setOpen(false); }; const overlayRef = createRef(); const buttonRef = createRef(); const { overlayProps, underlayProps } = useOverlay( { onClose, isDismissable: true, isOpen, shouldCloseOnInteractOutside: (element) => { var _a2; const portalContainer = getPortalContainer(); return !((_a2 = buttonRef.current) == null ? void 0 : _a2.contains(element)) && !portalContainer.contains(element); } }, overlayRef ); const { dialogProps } = useDialog({}, overlayRef); const styles = useStyles2(getStyles); const { modalBackdrop } = useStyles2(getModalStyles); const variant = isSynced ? "active" : isOnCanvas ? "canvas" : "default"; const isFromAfterTo = (_a = value == null ? void 0 : value.to) == null ? void 0 : _a.isBefore(value.from); const timePickerIcon = isFromAfterTo ? "exclamation-triangle" : "clock-nine"; const currentTimeRange = formattedRange(value, timeZone, quickRanges); return /* @__PURE__ */ jsxs(ButtonGroup, { className: styles.container, children: [ /* @__PURE__ */ jsx( ToolbarButton, { variant, onClick: onMoveBackward, icon: "angle-double-left", type: "button", iconSize: "xl", tooltip: moveBackwardTooltip != null ? moveBackwardTooltip : t("time-picker.range-picker.backwards-time-aria-label", "Move time range backwards"), narrow: true } ), /* @__PURE__ */ jsx( Tooltip, { ref: buttonRef, content: /* @__PURE__ */ jsx(TimePickerTooltip, { timeRange: value, timeZone }), placement: "bottom", interactive: true, children: /* @__PURE__ */ jsx( ToolbarButton, { "data-testid": selectors.components.TimePicker.openButton, "aria-label": t("time-picker.range-picker.current-time-selected", "Time range selected: {{currentTimeRange}}", { currentTimeRange }), "aria-controls": "TimePickerContent", onClick: onToolbarButtonSwitch, icon: timePickerIcon, isOpen, type: "button", variant, children: /* @__PURE__ */ jsx(TimePickerButtonLabel, { ...props }) } ) } ), isOpen && /* @__PURE__ */ jsxs("div", { "data-testid": selectors.components.TimePicker.overlayContent, children: [ /* @__PURE__ */ jsx("div", { role: "presentation", className: cx(modalBackdrop, styles.backdrop), ...underlayProps }), /* @__PURE__ */ jsx(FocusScope, { contain: true, autoFocus: true, restoreFocus: true, children: /* @__PURE__ */ jsx("section", { className: styles.content, ref: overlayRef, ...overlayProps, ...dialogProps, children: /* @__PURE__ */ jsx( TimePickerContent, { timeZone, fiscalYearStartMonth, value, onChange, quickOptions: quickRanges || getQuickOptions(), history, showHistory: true, widthOverride, onChangeTimeZone, onChangeFiscalYearStartMonth, hideQuickRanges, onError, weekStart } ) }) }) ] }), timeSyncButton, /* @__PURE__ */ jsx( ToolbarButton, { onClick: onMoveForward, icon: "angle-double-right", type: "button", variant, iconSize: "xl", tooltip: moveForwardTooltip != null ? moveForwardTooltip : t("time-picker.range-picker.forwards-time-aria-label", "Move time range forwards"), narrow: true } ), /* @__PURE__ */ jsx(Tooltip, { content: ZoomOutTooltip, placement: "bottom", children: /* @__PURE__ */ jsx( ToolbarButton, { "aria-label": t("time-picker.range-picker.zoom-out-button", "Zoom out time range"), onClick: onZoom, icon: "search-minus", type: "button", variant } ) }) ] }); } TimeRangePicker.displayName = "TimeRangePicker"; const ZoomOutTooltip = () => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Trans, { i18nKey: "time-picker.range-picker.zoom-out-tooltip", children: [ "Time range zoom out ", /* @__PURE__ */ jsx("br", {}), " CTRL+Z" ] }) }); const TimePickerTooltip = ({ timeRange, timeZone }) => { const styles = useStyles2(getLabelStyles); const now = Date.now(); const timeZoneInfo = timeZone ? getTimeZoneInfo(timeZone, now) : void 0; return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsxs("div", { className: "text-center", children: [ dateTimeFormat(timeRange.from, { timeZone }), /* @__PURE__ */ jsx("div", { className: "text-center", children: /* @__PURE__ */ jsx(Trans, { i18nKey: "time-picker.range-picker.to", children: "to" }) }), dateTimeFormat(timeRange.to, { timeZone }) ] }), /* @__PURE__ */ jsxs("div", { className: styles.container, children: [ /* @__PURE__ */ jsx("span", { className: styles.utc, children: timeZoneFormatUserFriendly(timeZone) }), /* @__PURE__ */ jsx(TimeZoneDescription, { info: timeZoneInfo }) ] }) ] }); }; const TimePickerButtonLabel = memo(({ hideText, value, timeZone, quickRanges }) => { const styles = useStyles2(getLabelStyles); if (hideText) { return null; } return /* @__PURE__ */ jsxs("span", { className: styles.container, "aria-live": "polite", "aria-atomic": "true", children: [ /* @__PURE__ */ jsx("span", { children: formattedRange(value, timeZone, quickRanges) }), /* @__PURE__ */ jsx("span", { className: styles.utc, children: rangeUtil.describeTimeRangeAbbreviation(value, timeZone) }) ] }); }); TimePickerButtonLabel.displayName = "TimePickerButtonLabel"; const formattedRange = (value, timeZone, quickRanges) => { const adjustedTimeRange = { to: dateMath.isMathString(value.raw.to) ? value.raw.to : value.to, from: dateMath.isMathString(value.raw.from) ? value.raw.from : value.from }; return rangeUtil.describeTimeRange(adjustedTimeRange, timeZone, quickRanges); }; const getStyles = (theme) => { return { container: css({ position: "relative", display: "flex", verticalAlign: "middle" }), backdrop: css({ display: "none", [theme.breakpoints.down("sm")]: { display: "block" } }), content: css({ position: "absolute", right: 0, top: "116%", zIndex: theme.zIndex.dropdown, [theme.breakpoints.down("sm")]: { position: "fixed", right: "50%", top: "50%", transform: "translate(50%, -50%)", zIndex: theme.zIndex.modal } }) }; }; const getLabelStyles = (theme) => { return { container: css({ display: "flex", alignItems: "center", whiteSpace: "nowrap", columnGap: theme.spacing(0.5) }), utc: css({ color: theme.v1.palette.orange, fontSize: theme.typography.size.sm, paddingLeft: "6px", lineHeight: "28px", verticalAlign: "bottom", fontWeight: theme.typography.fontWeightMedium }) }; }; export { TimePickerButtonLabel, TimePickerTooltip, TimeRangePicker }; //# sourceMappingURL=TimeRangePicker.mjs.map