The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/plugins/datasource/prometheus/components/PromExploreExtraField.tsx

130 lines
4.0 KiB

import React, { memo, useCallback } from 'react';
import { usePrevious } from 'react-use';
import { isEqual } from 'lodash';
import { css, cx } from '@emotion/css';
import { InlineFormLabel, RadioButtonGroup } from '@grafana/ui';
import { PromQuery } from '../types';
import { PromExemplarField } from './PromExemplarField';
import { PrometheusDatasource } from '../datasource';
export interface PromExploreExtraFieldProps {
query: PromQuery;
onChange: (value: PromQuery) => void;
onRunQuery: () => void;
datasource: PrometheusDatasource;
}
export const PromExploreExtraField: React.FC<PromExploreExtraFieldProps> = memo(
({ query, datasource, onChange, onRunQuery }) => {
const rangeOptions = [
{ value: 'range', label: 'Range', description: 'Run query over a range of time.' },
{
value: 'instant',
label: 'Instant',
description: 'Run query against a single point in time. For this query, the "To" time is used.',
},
{ value: 'both', label: 'Both', description: 'Run an Instant query and a Range query.' },
];
const prevQuery = usePrevious(query);
const onExemplarChange = useCallback(
(exemplar: boolean) => {
if (!isEqual(query, prevQuery) || exemplar !== query.exemplar) {
onChange({ ...query, exemplar });
}
},
[prevQuery, query, onChange]
);
function onChangeQueryStep(interval: string) {
onChange({ ...query, interval });
}
function onStepChange(e: React.SyntheticEvent<HTMLInputElement>) {
if (e.currentTarget.value !== query.interval) {
onChangeQueryStep(e.currentTarget.value);
}
}
function onReturnKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
if (e.key === 'Enter' && e.shiftKey) {
onRunQuery();
}
}
function onQueryTypeChange(queryType: string) {
let nextQuery;
if (queryType === 'instant') {
nextQuery = { ...query, instant: true, range: false };
} else if (queryType === 'range') {
nextQuery = { ...query, instant: false, range: true };
} else {
nextQuery = { ...query, instant: true, range: true };
}
onChange(nextQuery);
}
return (
<div aria-label="Prometheus extra field" className="gf-form-inline" data-testid={testIds.extraFieldEditor}>
{/*Query type field*/}
<div
data-testid={testIds.queryTypeField}
className={cx(
'gf-form explore-input-margin',
css`
flex-wrap: nowrap;
`
)}
aria-label="Query type field"
>
<InlineFormLabel width="auto">Query type</InlineFormLabel>
<RadioButtonGroup
options={rangeOptions}
value={query.range && query.instant ? 'both' : query.instant ? 'instant' : 'range'}
onChange={onQueryTypeChange}
/>
</div>
{/*Step field*/}
<div
data-testid={testIds.stepField}
className={cx(
'gf-form',
css`
flex-wrap: nowrap;
`
)}
aria-label="Step field"
>
<InlineFormLabel
width={6}
tooltip={
'Time units and built-in variables can be used here, for example: $__interval, $__rate_interval, 5s, 1m, 3h, 1d, 1y (Default if no unit is specified: s)'
}
>
Min step
</InlineFormLabel>
<input
type={'text'}
className="gf-form-input width-4"
placeholder={'auto'}
onChange={onStepChange}
onKeyDown={onReturnKeyDown}
value={query.interval ?? ''}
/>
</div>
<PromExemplarField onChange={onExemplarChange} datasource={datasource} query={query} />
</div>
);
}
);
PromExploreExtraField.displayName = 'PromExploreExtraField';
export const testIds = {
extraFieldEditor: 'prom-editor-extra-field',
stepField: 'prom-editor-extra-field-step',
queryTypeField: 'prom-editor-extra-field-query-type',
};