UNPKG

@grafana/ui

Version:
295 lines (292 loc) • 11.2 kB
import { jsxs, jsx, Fragment } from 'react/jsx-runtime'; import { css, cx } from '@emotion/css'; import { useState, memo, useMemo } from 'react'; import { isDateTime, rangeUtil } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { t, Trans } from '@grafana/i18n'; import { useStyles2, useTheme2 } from '../../../themes/ThemeContext.mjs'; import { getFocusStyles } from '../../../themes/mixins.mjs'; import { FilterInput } from '../../FilterInput/FilterInput.mjs'; import { Icon } from '../../Icon/Icon.mjs'; import { TextLink } from '../../Link/TextLink.mjs'; import { TimePickerFooter } from './TimePickerFooter.mjs'; import { TimePickerTitle } from './TimePickerTitle.mjs'; import { TimeRangeContent } from './TimeRangeContent.mjs'; import { TimeRangeList } from './TimeRangeList.mjs'; import { mapOptionToTimeRange, mapRangeToTimeOption } from './mapper.mjs'; "use strict"; const TimePickerContentWithScreenSize = (props) => { const { quickOptions = [], isReversed, isFullscreen, hideQuickRanges, timeZone, fiscalYearStartMonth, value, onChange, history, showHistory, className, hideTimeZone, onChangeTimeZone, onChangeFiscalYearStartMonth } = props; const isHistoryEmpty = !(history == null ? void 0 : history.length); const isContainerTall = isFullscreen && showHistory || !isFullscreen && (showHistory && !isHistoryEmpty || !hideQuickRanges); const styles = useStyles2(getStyles, isReversed, hideQuickRanges, isContainerTall, isFullscreen); const historyOptions = mapToHistoryOptions(history, timeZone); const timeOption = useTimeOption(value.raw, quickOptions); const [searchTerm, setSearchQuery] = useState(""); const filteredQuickOptions = quickOptions.filter((o) => o.display.toLowerCase().includes(searchTerm.toLowerCase())); const onChangeTimeOption = (timeOption2) => { return onChange(mapOptionToTimeRange(timeOption2)); }; return /* @__PURE__ */ jsxs("div", { id: "TimePickerContent", className: cx(styles.container, className), children: [ /* @__PURE__ */ jsxs("div", { className: styles.body, children: [ (!isFullscreen || !hideQuickRanges) && /* @__PURE__ */ jsxs("div", { className: styles.rightSide, children: [ /* @__PURE__ */ jsx("div", { className: styles.timeRangeFilter, children: /* @__PURE__ */ jsx( FilterInput, { width: 0, value: searchTerm, onChange: setSearchQuery, placeholder: t("time-picker.content.filter-placeholder", "Search quick ranges") } ) }), /* @__PURE__ */ jsxs("div", { className: styles.scrollContent, children: [ !isFullscreen && /* @__PURE__ */ jsx(NarrowScreenForm, { ...props, historyOptions }), !hideQuickRanges && /* @__PURE__ */ jsx(TimeRangeList, { options: filteredQuickOptions, onChange: onChangeTimeOption, value: timeOption }) ] }) ] }), isFullscreen && /* @__PURE__ */ jsx("div", { className: styles.leftSide, children: /* @__PURE__ */ jsx(FullScreenForm, { ...props, historyOptions }) }) ] }), !hideTimeZone && isFullscreen && /* @__PURE__ */ jsx( TimePickerFooter, { timeZone, fiscalYearStartMonth, onChangeTimeZone, onChangeFiscalYearStartMonth } ) ] }); }; const TimePickerContent = (props) => { const { widthOverride } = props; const theme = useTheme2(); const isFullscreen = (widthOverride || window.innerWidth) >= theme.breakpoints.values.lg; return /* @__PURE__ */ jsx(TimePickerContentWithScreenSize, { ...props, isFullscreen }); }; const NarrowScreenForm = (props) => { const { value, hideQuickRanges, onChange, timeZone, historyOptions = [], showHistory, onError, weekStart } = props; const styles = useStyles2(getNarrowScreenStyles); const isAbsolute = isDateTime(value.raw.from) || isDateTime(value.raw.to); const [collapsedFlag, setCollapsedFlag] = useState(!isAbsolute); const collapsed = hideQuickRanges ? false : collapsedFlag; const onChangeTimeOption = (timeOption) => { return onChange(mapOptionToTimeRange(timeOption, timeZone)); }; return /* @__PURE__ */ jsxs("fieldset", { children: [ /* @__PURE__ */ jsx("div", { className: styles.header, children: /* @__PURE__ */ jsxs( "button", { type: "button", className: styles.expandButton, onClick: () => { if (!hideQuickRanges) { setCollapsedFlag(!collapsed); } }, "data-testid": selectors.components.TimePicker.absoluteTimeRangeTitle, "aria-expanded": !collapsed, "aria-controls": "expanded-timerange", children: [ /* @__PURE__ */ jsx(TimePickerTitle, { children: /* @__PURE__ */ jsx(Trans, { i18nKey: "time-picker.absolute.title", children: "Absolute time range" }) }), !hideQuickRanges && /* @__PURE__ */ jsx(Icon, { name: !collapsed ? "angle-up" : "angle-down" }) ] } ) }), !collapsed && /* @__PURE__ */ jsxs("div", { className: styles.body, id: "expanded-timerange", children: [ /* @__PURE__ */ jsx("div", { className: styles.form, children: /* @__PURE__ */ jsx( TimeRangeContent, { value, onApply: onChange, timeZone, isFullscreen: false, onError, weekStart } ) }), showHistory && /* @__PURE__ */ jsx( TimeRangeList, { title: t("time-picker.absolute.recent-title", "Recently used absolute ranges"), options: historyOptions, onChange: onChangeTimeOption, placeholderEmpty: null } ) ] }) ] }); }; const FullScreenForm = (props) => { const { onChange, value, timeZone, fiscalYearStartMonth, isReversed, historyOptions, onError, weekStart } = props; const styles = useStyles2(getFullScreenStyles, props.hideQuickRanges); const onChangeTimeOption = (timeOption) => { return onChange(mapOptionToTimeRange(timeOption, timeZone)); }; return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsxs("div", { className: styles.container, children: [ /* @__PURE__ */ jsx("div", { className: styles.title, "data-testid": selectors.components.TimePicker.absoluteTimeRangeTitle, children: /* @__PURE__ */ jsx(TimePickerTitle, { children: /* @__PURE__ */ jsx(Trans, { i18nKey: "time-picker.absolute.title", children: "Absolute time range" }) }) }), /* @__PURE__ */ jsx( TimeRangeContent, { value, timeZone, fiscalYearStartMonth, onApply: onChange, isFullscreen: true, isReversed, onError, weekStart } ) ] }), props.showHistory && /* @__PURE__ */ jsx("div", { className: styles.recent, children: /* @__PURE__ */ jsx( TimeRangeList, { title: t("time-picker.absolute.recent-title", "Recently used absolute ranges"), options: historyOptions || [], onChange: onChangeTimeOption, placeholderEmpty: /* @__PURE__ */ jsx(EmptyRecentList, {}) } ) }) ] }); }; const EmptyRecentList = memo(() => { const styles = useStyles2(getEmptyListStyles); const emptyRecentListText = t( "time-picker.content.empty-recent-list-info", "It looks like you haven't used this time picker before. As soon as you enter some time intervals, recently used intervals will appear here." ); return /* @__PURE__ */ jsxs("div", { className: styles.container, children: [ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("span", { children: emptyRecentListText }) }), /* @__PURE__ */ jsx(Trans, { i18nKey: "time-picker.content.empty-recent-list-docs", children: /* @__PURE__ */ jsxs("div", { children: [ /* @__PURE__ */ jsx(TextLink, { href: "https://grafana.com/docs/grafana/latest/dashboards/time-range-controls", external: true, children: "Read the documentation" }), /* @__PURE__ */ jsx("span", { children: " to find out more about how to enter custom time ranges." }) ] }) }) ] }); }); function mapToHistoryOptions(ranges, timeZone) { if (!Array.isArray(ranges) || ranges.length === 0) { return []; } return ranges.map((range) => mapRangeToTimeOption(range, timeZone)); } EmptyRecentList.displayName = "EmptyRecentList"; const useTimeOption = (raw, quickOptions) => { return useMemo(() => { if (!rangeUtil.isRelativeTimeRange(raw)) { return; } return quickOptions.find((option) => { return option.from === raw.from && option.to === raw.to; }); }, [raw, quickOptions]); }; const getStyles = (theme, isReversed, hideQuickRanges, isContainerTall, isFullscreen) => ({ container: css({ background: theme.colors.background.elevated, boxShadow: theme.shadows.z3, width: `${isFullscreen ? "546px" : "262px"}`, borderRadius: theme.shape.radius.default, border: `1px solid ${theme.colors.border.weak}`, [`${isReversed ? "left" : "right"}`]: 0, display: "flex", flexDirection: "column" }), body: css({ display: "flex", flexDirection: "row-reverse", height: `${isContainerTall ? "381px" : "217px"}`, maxHeight: "100vh" }), leftSide: css({ display: "flex", flexDirection: "column", borderRight: `${isReversed ? "none" : `1px solid ${theme.colors.border.weak}`}`, width: `${!hideQuickRanges ? "60%" : "100%"}`, overflow: "auto", scrollbarWidth: "thin", order: isReversed ? 1 : 0 }), rightSide: css({ width: `${isFullscreen ? "40%" : "100%"}; !important`, borderRight: isReversed ? `1px solid ${theme.colors.border.weak}` : "none", display: "flex", flexDirection: "column" }), timeRangeFilter: css({ padding: theme.spacing(1) }), spacing: css({ marginTop: "16px" }), scrollContent: css({ overflowY: "auto", scrollbarWidth: "thin" }) }); const getNarrowScreenStyles = (theme) => ({ header: css({ display: "flex", flexDirection: "row", justifyContent: "space-between", alignItems: "center", borderBottom: `1px solid ${theme.colors.border.weak}`, padding: "7px 9px 7px 9px" }), expandButton: css({ backgroundColor: "transparent", border: "none", display: "flex", width: "100%", "&:focus-visible": getFocusStyles(theme) }), body: css({ borderBottom: `1px solid ${theme.colors.border.weak}` }), form: css({ padding: "7px 9px 7px 9px" }) }); const getFullScreenStyles = (theme, hideQuickRanges) => ({ container: css({ paddingTop: "9px", paddingLeft: "11px", paddingRight: !hideQuickRanges ? "20%" : "11px" }), title: css({ marginBottom: "11px" }), recent: css({ flexGrow: 1, display: "flex", flexDirection: "column", justifyContent: "flex-end", paddingTop: theme.spacing(1) }) }); const getEmptyListStyles = (theme) => ({ container: css({ padding: "12px", margin: "12px", "a, span": { fontSize: "13px" } }) }); export { TimePickerContent, TimePickerContentWithScreenSize }; //# sourceMappingURL=TimePickerContent.mjs.map