Commit 48570c62 by Hugo Häggmark Committed by GitHub

Made sure that DataSourceOption displays value and fires onChange/onBlur events (#15757)

* Fixed #15682 

* fix: Add hideTimeOverride to state since we need to control the Switch

* fix: Back the maxDataPoints change, we need to keep it as a string

Co-authored-by:johannes.schill@polyester.se
parent 59045029
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<HTMLInputElement>) => void;
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
tooltipInfo?: any;
}
export const DataSourceOptions: FC<Props> = ({ label, placeholder, name, value, onChange, tooltipInfo }) => {
export const DataSourceOption: FC<Props> = ({ label, placeholder, name, value, onBlur, onChange, tooltipInfo }) => {
return (
<div className="gf-form gf-form--flex-end">
<FormLabel tooltip={tooltipInfo}>{label}</FormLabel>
......@@ -20,10 +21,10 @@ export const DataSourceOptions: FC<Props> = ({ label, placeholder, name, value,
placeholder={placeholder}
name={name}
spellCheck={false}
onBlur={evt => onChange(evt.target.value)}
onBlur={onBlur}
onChange={onChange}
value={value}
/>
</div>
);
};
export default DataSourceOptions;
// 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<Props, State> {
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{' '}
<code>1m</code> if your data is written every minute. Access auto interval via variable{' '}
<code>$__interval</code> for time range string and <code>$__interval_ms</code> 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<HTMLInputElement>) => {
this.setState({
relativeTime: event.target.value,
});
};
onTimeShiftChange = event => {
onTimeShiftChange = (event: ChangeEvent<HTMLInputElement>) => {
this.setState({
timeShift: event.target.value,
});
};
onOverrideTime = (evt, status: InputStatus) => {
const { value } = evt.target;
onOverrideTime = (event: FocusEvent<HTMLInputElement>, 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<Props, State> {
}
};
onTimeShift = (evt, status: InputStatus) => {
const { value } = evt.target;
onTimeShift = (event: FocusEvent<HTMLInputElement>, 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<Props, State> {
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<HTMLInputElement>) => {
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{' '}
<code>1m</code> if your data is written every minute. Access auto interval via variable{' '}
<code>$__interval</code> for time range string and <code>$__interval_ms</code> for numeric variable that can
be used in math expressions.
</>
),
},
};
return Object.keys(queryOptions).map(key => {
const options = allOptions[key];
return <DataSourceOption key={key} {...options} onChange={onChangeFn(allOptions[key].panelKey || key)} />;
const options = this.allOptions[key];
const panelKey = options.panelKey || key;
return (
<DataSourceOption
key={key}
{...options}
onChange={this.onDataSourceOptionChange(panelKey)}
onBlur={this.onDataSourceOptionBlur(panelKey)}
value={this.state[panelKey]}
/>
);
});
}
};
render() {
const hideTimeOverride = this.props.panel.hideTimeOverride;
const { hideTimeOverride } = this.state;
const { relativeTime, timeShift } = this.state;
return (
<div className="gf-form-inline">
{this.renderOptions()}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment