mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
parent
f2bb9fd92a
commit
db2770d992
@ -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>
|
||||
);
|
||||
|
@ -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;
|
||||
}
|
||||
`,
|
||||
};
|
||||
};
|
@ -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)}
|
||||
/>
|
||||
)}
|
||||
<div className={styles.queryOptions}>
|
||||
<MaxDataPointsOption
|
||||
options={alertQueryOptions}
|
||||
onChange={(options) => onChangeQueryOptions(options, index)}
|
||||
/>
|
||||
</div>
|
||||
<QueryOptions
|
||||
onChangeTimeRange={onChangeTimeRange}
|
||||
query={query}
|
||||
queryOptions={alertQueryOptions}
|
||||
onChangeQueryOptions={onChangeQueryOptions}
|
||||
index={index}
|
||||
/>
|
||||
|
||||
<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)};
|
||||
|
Loading…
Reference in New Issue
Block a user