diff --git a/public/app/features/dashboard/panel_editor/DataSourceOption.tsx b/public/app/features/dashboard/panel_editor/DataSourceOption.tsx index 08285960805..a72eaae6ed9 100644 --- a/public/app/features/dashboard/panel_editor/DataSourceOption.tsx +++ b/public/app/features/dashboard/panel_editor/DataSourceOption.tsx @@ -1,16 +1,17 @@ -import React, { FC } from 'react'; +import React, { FC, ChangeEvent } from 'react'; import { FormLabel } from '@grafana/ui'; interface Props { label: string; placeholder?: string; - name?: string; - value?: string; - onChange?: (evt: any) => void; + name: string; + value: string; + onBlur: (event: ChangeEvent) => void; + onChange: (event: ChangeEvent) => void; tooltipInfo?: any; } -export const DataSourceOptions: FC = ({ label, placeholder, name, value, onChange, tooltipInfo }) => { +export const DataSourceOption: FC = ({ label, placeholder, name, value, onBlur, onChange, tooltipInfo }) => { return (
{label} @@ -20,10 +21,10 @@ export const DataSourceOptions: FC = ({ label, placeholder, name, value, placeholder={placeholder} name={name} spellCheck={false} - onBlur={evt => onChange(evt.target.value)} + onBlur={onBlur} + onChange={onChange} + value={value} />
); }; - -export default DataSourceOptions; diff --git a/public/app/features/dashboard/panel_editor/QueryOptions.tsx b/public/app/features/dashboard/panel_editor/QueryOptions.tsx index d203f3bc25f..8c59edf456d 100644 --- a/public/app/features/dashboard/panel_editor/QueryOptions.tsx +++ b/public/app/features/dashboard/panel_editor/QueryOptions.tsx @@ -1,5 +1,5 @@ // Libraries -import React, { PureComponent } from 'react'; +import React, { PureComponent, ChangeEvent, FocusEvent } from 'react'; // Utils import { isValidTimeSpan } from 'app/core/utils/rangeutil'; @@ -9,7 +9,7 @@ import { Switch } from '@grafana/ui'; import { Input } from 'app/core/components/Form'; import { EventsWithValidation } from 'app/core/components/Form/Input'; import { InputStatus } from 'app/core/components/Form/Input'; -import DataSourceOption from './DataSourceOption'; +import { DataSourceOption } from './DataSourceOption'; import { FormLabel } from '@grafana/ui'; // Types @@ -43,32 +43,79 @@ interface Props { interface State { relativeTime: string; timeShift: string; + cacheTimeout: string; + maxDataPoints: string; + interval: string; + hideTimeOverride: boolean; } export class QueryOptions extends PureComponent { + allOptions = { + cacheTimeout: { + label: 'Cache timeout', + placeholder: '60', + name: 'cacheTimeout', + tooltipInfo: ( + <> + If your time series store has a query cache this option can override the default cache timeout. Specify a + numeric value in seconds. + + ), + }, + maxDataPoints: { + label: 'Max data points', + placeholder: 'auto', + name: 'maxDataPoints', + tooltipInfo: ( + <> + The maximum data points the query should return. For graphs this is automatically set to one data point per + pixel. + + ), + }, + minInterval: { + label: 'Min time interval', + placeholder: '0', + name: 'minInterval', + panelKey: 'interval', + tooltipInfo: ( + <> + A lower limit for the auto group by time interval. Recommended to be set to write frequency, for example{' '} + 1m if your data is written every minute. Access auto interval via variable{' '} + $__interval for time range string and $__interval_ms for numeric variable that can + be used in math expressions. + + ), + }, + }; + constructor(props) { super(props); this.state = { relativeTime: props.panel.timeFrom || '', timeShift: props.panel.timeShift || '', + cacheTimeout: props.panel.cacheTimeout || '', + maxDataPoints: props.panel.maxDataPoints || '', + interval: props.panel.interval || '', + hideTimeOverride: props.panel.hideTimeOverride || false, }; } - onRelativeTimeChange = event => { + onRelativeTimeChange = (event: ChangeEvent) => { this.setState({ relativeTime: event.target.value, }); }; - onTimeShiftChange = event => { + onTimeShiftChange = (event: ChangeEvent) => { this.setState({ timeShift: event.target.value, }); }; - onOverrideTime = (evt, status: InputStatus) => { - const { value } = evt.target; + onOverrideTime = (event: FocusEvent, status: InputStatus) => { + const { value } = event.target; const { panel } = this.props; const emptyToNullValue = emptyToNull(value); if (status === InputStatus.Valid && panel.timeFrom !== emptyToNullValue) { @@ -77,8 +124,8 @@ export class QueryOptions extends PureComponent { } }; - onTimeShift = (evt, status: InputStatus) => { - const { value } = evt.target; + onTimeShift = (event: FocusEvent, status: InputStatus) => { + const { value } = event.target; const { panel } = this.props; const emptyToNullValue = emptyToNull(value); if (status === InputStatus.Valid && panel.timeShift !== emptyToNullValue) { @@ -89,77 +136,49 @@ export class QueryOptions extends PureComponent { onToggleTimeOverride = () => { const { panel } = this.props; - panel.hideTimeOverride = !panel.hideTimeOverride; + this.setState({ hideTimeOverride: !this.state.hideTimeOverride }, () => { + panel.hideTimeOverride = this.state.hideTimeOverride; + panel.refresh(); + }); + }; + + onDataSourceOptionBlur = (panelKey: string) => () => { + const { panel } = this.props; + + panel[panelKey] = this.state[panelKey]; panel.refresh(); }; - renderOptions() { - const { datasource, panel } = this.props; + onDataSourceOptionChange = (panelKey: string) => (event: ChangeEvent) => { + this.setState({ ...this.state, [panelKey]: event.target.value }); + }; + + renderOptions = () => { + const { datasource } = this.props; const { queryOptions } = datasource.meta; if (!queryOptions) { return null; } - const onChangeFn = (panelKey: string) => { - return (value: string | number) => { - panel[panelKey] = value; - panel.refresh(); - }; - }; - - const allOptions = { - cacheTimeout: { - label: 'Cache timeout', - placeholder: '60', - name: 'cacheTimeout', - value: panel.cacheTimeout, - tooltipInfo: ( - <> - If your time series store has a query cache this option can override the default cache timeout. Specify a - numeric value in seconds. - - ), - }, - maxDataPoints: { - label: 'Max data points', - placeholder: 'auto', - name: 'maxDataPoints', - value: panel.maxDataPoints, - tooltipInfo: ( - <> - The maximum data points the query should return. For graphs this is automatically set to one data point per - pixel. - - ), - }, - minInterval: { - label: 'Min time interval', - placeholder: '0', - name: 'minInterval', - value: panel.interval, - panelKey: 'interval', - tooltipInfo: ( - <> - A lower limit for the auto group by time interval. Recommended to be set to write frequency, for example{' '} - 1m if your data is written every minute. Access auto interval via variable{' '} - $__interval for time range string and $__interval_ms for numeric variable that can - be used in math expressions. - - ), - }, - }; - return Object.keys(queryOptions).map(key => { - const options = allOptions[key]; - return ; + const options = this.allOptions[key]; + const panelKey = options.panelKey || key; + return ( + + ); }); - } + }; render() { - const hideTimeOverride = this.props.panel.hideTimeOverride; + const { hideTimeOverride } = this.state; const { relativeTime, timeShift } = this.state; - return (
{this.renderOptions()}