Alerting: Improve time range and max data points info in QueryEditor (#70867)

* Add component to display QueryOptions in editor

* Display QueryOptions in QueryWrapper

* Display real data for time range and max data points

* Improve QueryOptions styling

* Remove Portal from RelativeTimeRangePicker

* Prevent RefID from hiding on small screens

Fixes https://github.com/grafana/grafana/issues/70900

* Address review comments

* Fix lint
This commit is contained in:
Virginia Cepeda 2023-07-04 11:17:14 -03:00 committed by GitHub
parent f2bb9fd92a
commit db2770d992
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 129 additions and 26 deletions

View File

@ -14,7 +14,6 @@ import CustomScrollbar from '../../CustomScrollbar/CustomScrollbar';
import { Field } from '../../Forms/Field';
import { Icon } from '../../Icon/Icon';
import { getInputStyles, Input } from '../../Input/Input';
import { Portal } from '../../Portal/Portal';
import { Tooltip } from '../../Tooltip/Tooltip';
import { TimePickerTitle } from '../TimeRangePicker/TimePickerTitle';
import { TimeRangeList } from '../TimeRangePicker/TimeRangeList';
@ -123,7 +122,7 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
</span>
</button>
{isOpen && (
<Portal>
<div>
<div role="presentation" className={styles.backdrop} {...underlayProps} />
<FocusScope contain autoFocus restoreFocus>
<div ref={ref} {...overlayProps} {...dialogProps}>
@ -178,7 +177,7 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
</div>
</div>
</FocusScope>
</Portal>
</div>
)}
</div>
);

View File

@ -0,0 +1,112 @@
import { css } from '@emotion/css';
import React, { useState } from 'react';
import { dateTime, getDefaultRelativeTimeRange, GrafanaTheme2, RelativeTimeRange } from '@grafana/data';
import { relativeToTimeRange } from '@grafana/data/src/datetime/rangeutil';
import { clearButtonStyles, Icon, RelativeTimeRangePicker, Toggletip, useStyles2 } from '@grafana/ui';
import { AlertQuery } from 'app/types/unified-alerting-dto';
import { AlertQueryOptions, MaxDataPointsOption } from './QueryWrapper';
export interface QueryOptionsProps {
query: AlertQuery;
queryOptions: AlertQueryOptions;
onChangeTimeRange?: (timeRange: RelativeTimeRange, index: number) => void;
onChangeQueryOptions: (options: AlertQueryOptions, index: number) => void;
index: number;
}
export const QueryOptions = ({
query,
queryOptions,
onChangeTimeRange,
onChangeQueryOptions,
index,
}: QueryOptionsProps) => {
const styles = useStyles2(getStyles);
const [showOptions, setShowOptions] = useState(false);
const timeRange = query.relativeTimeRange ? relativeToTimeRange(query.relativeTimeRange) : undefined;
return (
<>
<Toggletip
content={
<div className={styles.container}>
<div>
{onChangeTimeRange && (
<div className={styles.timeRangeContainer}>
<span className={styles.timeRangeLabel}>Time Range</span>
<RelativeTimeRangePicker
timeRange={query.relativeTimeRange ?? getDefaultRelativeTimeRange()}
onChange={(range) => onChangeTimeRange(range, index)}
/>
</div>
)}
</div>
<div className={styles.queryOptions}>
<MaxDataPointsOption
options={queryOptions}
onChange={(options) => onChangeQueryOptions(options, index)}
/>
</div>
</div>
}
closeButton={true}
placement="bottom-start"
>
<button type="button" className={styles.actionLink} onClick={() => setShowOptions(!showOptions)}>
Options {showOptions ? <Icon name="angle-right" /> : <Icon name="angle-down" />}
</button>
</Toggletip>
<div className={styles.staticValues}>
<span>{dateTime(timeRange?.from).locale('en').fromNow(true)}</span>
{queryOptions.maxDataPoints && <span>, MD {queryOptions.maxDataPoints}</span>}
</div>
</>
);
};
const getStyles = (theme: GrafanaTheme2) => {
const clearButton = clearButtonStyles(theme);
return {
container: css`
display: flex;
flex-direction: column;
gap: 10px;
`,
timeRangeContainer: css`
display: flex;
`,
timeRangeLabel: css`
width: 20%;
`,
queryOptions: css`
margin-bottom: -${theme.spacing(2)};
label {
line-height: 12px;
padding: 0px;
}
`,
staticValues: css`
color: ${theme.colors.text.secondary};
margin-right: ${theme.spacing(1)};
`,
actionLink: css`
${clearButton};
color: ${theme.colors.text.link};
cursor: pointer;
&:hover {
text-decoration: underline;
}
`,
};
};

View File

@ -6,7 +6,6 @@ import {
CoreApp,
DataSourceApi,
DataSourceInstanceSettings,
getDefaultRelativeTimeRange,
GrafanaTheme2,
LoadingState,
PanelData,
@ -15,20 +14,13 @@ import {
} from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { DataQuery } from '@grafana/schema';
import {
GraphTresholdsStyleMode,
Icon,
InlineFormLabel,
Input,
RelativeTimeRangePicker,
Tooltip,
useStyles2,
} from '@grafana/ui';
import { GraphTresholdsStyleMode, Icon, InlineFormLabel, Input, Tooltip, useStyles2 } from '@grafana/ui';
import { QueryEditorRow } from 'app/features/query/components/QueryEditorRow';
import { AlertQuery } from 'app/types/unified-alerting-dto';
import { AlertConditionIndicator } from '../expressions/AlertConditionIndicator';
import { QueryOptions } from './QueryOptions';
import { VizWrapper } from './VizWrapper';
export const DEFAULT_MAX_DATA_POINTS = 43200;
@ -123,18 +115,14 @@ export const QueryWrapper = ({
return (
<Stack direction="row" alignItems="baseline" gap={1}>
<SelectingDataSourceTooltip />
{onChangeTimeRange && (
<RelativeTimeRangePicker
timeRange={query.relativeTimeRange ?? getDefaultRelativeTimeRange()}
onChange={(range) => onChangeTimeRange(range, index)}
<QueryOptions
onChangeTimeRange={onChangeTimeRange}
query={query}
queryOptions={alertQueryOptions}
onChangeQueryOptions={onChangeQueryOptions}
index={index}
/>
)}
<div className={styles.queryOptions}>
<MaxDataPointsOption
options={alertQueryOptions}
onChange={(options) => onChangeQueryOptions(options, index)}
/>
</div>
<AlertConditionIndicator
onSetCondition={() => onSetCondition(query.refId)}
enabled={condition === query.refId}
@ -187,7 +175,7 @@ export const EmptyQueryWrapper = ({ children }: React.PropsWithChildren<{}>) =>
return <div className={styles.wrapper}>{children}</div>;
};
function MaxDataPointsOption({
export function MaxDataPointsOption({
options,
onChange,
}: {
@ -240,6 +228,10 @@ const getStyles = (theme: GrafanaTheme2) => ({
margin-bottom: ${theme.spacing(1)};
border: 1px solid ${theme.colors.border.weak};
border-radius: ${theme.shape.borderRadius(1)};
button {
overflow: visible;
}
`,
queryOptions: css`
margin-bottom: -${theme.spacing(2)};