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
This commit is contained in:
Hugo Häggmark 2019-03-05 10:49:45 +01:00 committed by GitHub
parent 590450291a
commit 48570c6272
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 93 additions and 73 deletions

View File

@ -1,16 +1,17 @@
import React, { FC } from 'react'; import React, { FC, ChangeEvent } from 'react';
import { FormLabel } from '@grafana/ui'; import { FormLabel } from '@grafana/ui';
interface Props { interface Props {
label: string; label: string;
placeholder?: string; placeholder?: string;
name?: string; name: string;
value?: string; value: string;
onChange?: (evt: any) => void; onBlur: (event: ChangeEvent<HTMLInputElement>) => void;
onChange: (event: ChangeEvent<HTMLInputElement>) => void;
tooltipInfo?: any; 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 ( return (
<div className="gf-form gf-form--flex-end"> <div className="gf-form gf-form--flex-end">
<FormLabel tooltip={tooltipInfo}>{label}</FormLabel> <FormLabel tooltip={tooltipInfo}>{label}</FormLabel>
@ -20,10 +21,10 @@ export const DataSourceOptions: FC<Props> = ({ label, placeholder, name, value,
placeholder={placeholder} placeholder={placeholder}
name={name} name={name}
spellCheck={false} spellCheck={false}
onBlur={evt => onChange(evt.target.value)} onBlur={onBlur}
onChange={onChange}
value={value}
/> />
</div> </div>
); );
}; };
export default DataSourceOptions;

View File

@ -1,5 +1,5 @@
// Libraries // Libraries
import React, { PureComponent } from 'react'; import React, { PureComponent, ChangeEvent, FocusEvent } from 'react';
// Utils // Utils
import { isValidTimeSpan } from 'app/core/utils/rangeutil'; import { isValidTimeSpan } from 'app/core/utils/rangeutil';
@ -9,7 +9,7 @@ import { Switch } from '@grafana/ui';
import { Input } from 'app/core/components/Form'; import { Input } from 'app/core/components/Form';
import { EventsWithValidation } from 'app/core/components/Form/Input'; import { EventsWithValidation } from 'app/core/components/Form/Input';
import { InputStatus } 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'; import { FormLabel } from '@grafana/ui';
// Types // Types
@ -43,77 +43,18 @@ interface Props {
interface State { interface State {
relativeTime: string; relativeTime: string;
timeShift: string; timeShift: string;
cacheTimeout: string;
maxDataPoints: string;
interval: string;
hideTimeOverride: boolean;
} }
export class QueryOptions extends PureComponent<Props, State> { export class QueryOptions extends PureComponent<Props, State> {
constructor(props) { allOptions = {
super(props);
this.state = {
relativeTime: props.panel.timeFrom || '',
timeShift: props.panel.timeShift || '',
};
}
onRelativeTimeChange = event => {
this.setState({
relativeTime: event.target.value,
});
};
onTimeShiftChange = event => {
this.setState({
timeShift: event.target.value,
});
};
onOverrideTime = (evt, status: InputStatus) => {
const { value } = evt.target;
const { panel } = this.props;
const emptyToNullValue = emptyToNull(value);
if (status === InputStatus.Valid && panel.timeFrom !== emptyToNullValue) {
panel.timeFrom = emptyToNullValue;
panel.refresh();
}
};
onTimeShift = (evt, status: InputStatus) => {
const { value } = evt.target;
const { panel } = this.props;
const emptyToNullValue = emptyToNull(value);
if (status === InputStatus.Valid && panel.timeShift !== emptyToNullValue) {
panel.timeShift = emptyToNullValue;
panel.refresh();
}
};
onToggleTimeOverride = () => {
const { panel } = this.props;
panel.hideTimeOverride = !panel.hideTimeOverride;
panel.refresh();
};
renderOptions() {
const { datasource, panel } = 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: { cacheTimeout: {
label: 'Cache timeout', label: 'Cache timeout',
placeholder: '60', placeholder: '60',
name: 'cacheTimeout', name: 'cacheTimeout',
value: panel.cacheTimeout,
tooltipInfo: ( tooltipInfo: (
<> <>
If your time series store has a query cache this option can override the default cache timeout. Specify a If your time series store has a query cache this option can override the default cache timeout. Specify a
@ -125,7 +66,6 @@ export class QueryOptions extends PureComponent<Props, State> {
label: 'Max data points', label: 'Max data points',
placeholder: 'auto', placeholder: 'auto',
name: 'maxDataPoints', name: 'maxDataPoints',
value: panel.maxDataPoints,
tooltipInfo: ( tooltipInfo: (
<> <>
The maximum data points the query should return. For graphs this is automatically set to one data point per The maximum data points the query should return. For graphs this is automatically set to one data point per
@ -137,7 +77,6 @@ export class QueryOptions extends PureComponent<Props, State> {
label: 'Min time interval', label: 'Min time interval',
placeholder: '0', placeholder: '0',
name: 'minInterval', name: 'minInterval',
value: panel.interval,
panelKey: 'interval', panelKey: 'interval',
tooltipInfo: ( tooltipInfo: (
<> <>
@ -150,16 +89,96 @@ export class QueryOptions extends PureComponent<Props, State> {
}, },
}; };
return Object.keys(queryOptions).map(key => { constructor(props) {
const options = allOptions[key]; super(props);
return <DataSourceOption key={key} {...options} onChange={onChangeFn(allOptions[key].panelKey || key)} />;
}); 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,
};
} }
render() { onRelativeTimeChange = (event: ChangeEvent<HTMLInputElement>) => {
const hideTimeOverride = this.props.panel.hideTimeOverride; this.setState({
const { relativeTime, timeShift } = this.state; relativeTime: event.target.value,
});
};
onTimeShiftChange = (event: ChangeEvent<HTMLInputElement>) => {
this.setState({
timeShift: event.target.value,
});
};
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) {
panel.timeFrom = emptyToNullValue;
panel.refresh();
}
};
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) {
panel.timeShift = emptyToNullValue;
panel.refresh();
}
};
onToggleTimeOverride = () => {
const { panel } = this.props;
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();
};
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;
}
return Object.keys(queryOptions).map(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.state;
const { relativeTime, timeShift } = this.state;
return ( return (
<div className="gf-form-inline"> <div className="gf-form-inline">
{this.renderOptions()} {this.renderOptions()}