mirror of https://github.com/grafana/grafana.git
Fixing array direction, adding simple render test, fixes #15478
Fixed unit test and updated gauge Added migration for threshold order
This commit is contained in:
parent
2afd3cf5aa
commit
93e8edfddd
|
|
@ -84,9 +84,9 @@ describe('Get thresholds formatted', () => {
|
||||||
it('should get the correct formatted values when thresholds are added', () => {
|
it('should get the correct formatted values when thresholds are added', () => {
|
||||||
const { instance } = setup({
|
const { instance } = setup({
|
||||||
thresholds: [
|
thresholds: [
|
||||||
{ index: 2, value: 75, color: '#6ED0E0' },
|
|
||||||
{ index: 1, value: 50, color: '#EAB839' },
|
|
||||||
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
||||||
|
{ index: 1, value: 50, color: '#EAB839' },
|
||||||
|
{ index: 2, value: 75, color: '#6ED0E0' },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,16 +98,15 @@ export class Gauge extends PureComponent<Props> {
|
||||||
getFormattedThresholds() {
|
getFormattedThresholds() {
|
||||||
const { maxValue, minValue, thresholds, theme } = this.props;
|
const { maxValue, minValue, thresholds, theme } = this.props;
|
||||||
|
|
||||||
const thresholdsSortedByIndex = [...thresholds].sort((t1, t2) => t1.index - t2.index);
|
const lastThreshold = thresholds[thresholds.length - 1];
|
||||||
const lastThreshold = thresholdsSortedByIndex[thresholdsSortedByIndex.length - 1];
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
...thresholdsSortedByIndex.map(threshold => {
|
...thresholds.map(threshold => {
|
||||||
if (threshold.index === 0) {
|
if (threshold.index === 0) {
|
||||||
return { value: minValue, color: getColorFromHexRgbOrName(threshold.color, theme.type) };
|
return { value: minValue, color: getColorFromHexRgbOrName(threshold.color, theme.type) };
|
||||||
}
|
}
|
||||||
|
|
||||||
const previousThreshold = thresholdsSortedByIndex[threshold.index - 1];
|
const previousThreshold = thresholds[threshold.index - 1];
|
||||||
return { value: threshold.value, color: getColorFromHexRgbOrName(previousThreshold.color, theme.type) };
|
return { value: threshold.value, color: getColorFromHexRgbOrName(previousThreshold.color, theme.type) };
|
||||||
}),
|
}),
|
||||||
{ value: maxValue, color: getColorFromHexRgbOrName(lastThreshold.color, theme.type) },
|
{ value: maxValue, color: getColorFromHexRgbOrName(lastThreshold.color, theme.type) },
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import React, { ChangeEvent } from 'react';
|
import React, { ChangeEvent } from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
|
|
||||||
import { ThresholdsEditor, Props } from './ThresholdsEditor';
|
import { ThresholdsEditor, Props } from './ThresholdsEditor';
|
||||||
|
|
||||||
const setup = (propOverrides?: object) => {
|
const setup = (propOverrides?: Partial<Props>) => {
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
onChange: jest.fn(),
|
onChange: jest.fn(),
|
||||||
thresholds: [],
|
thresholds: [],
|
||||||
|
|
@ -11,12 +10,26 @@ const setup = (propOverrides?: object) => {
|
||||||
|
|
||||||
Object.assign(props, propOverrides);
|
Object.assign(props, propOverrides);
|
||||||
|
|
||||||
return shallow(<ThresholdsEditor {...props} />).instance() as ThresholdsEditor;
|
const wrapper = mount(<ThresholdsEditor {...props} />);
|
||||||
|
const instance = wrapper.instance() as ThresholdsEditor;
|
||||||
|
|
||||||
|
return {
|
||||||
|
instance,
|
||||||
|
wrapper,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
describe('Render', () => {
|
||||||
|
it('should render with base threshold', () => {
|
||||||
|
const { wrapper } = setup();
|
||||||
|
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Initialization', () => {
|
describe('Initialization', () => {
|
||||||
it('should add a base threshold if missing', () => {
|
it('should add a base threshold if missing', () => {
|
||||||
const instance = setup();
|
const { instance } = setup();
|
||||||
|
|
||||||
expect(instance.state.thresholds).toEqual([{ index: 0, value: -Infinity, color: '#7EB26D' }]);
|
expect(instance.state.thresholds).toEqual([{ index: 0, value: -Infinity, color: '#7EB26D' }]);
|
||||||
});
|
});
|
||||||
|
|
@ -24,7 +37,7 @@ describe('Initialization', () => {
|
||||||
|
|
||||||
describe('Add threshold', () => {
|
describe('Add threshold', () => {
|
||||||
it('should not add threshold at index 0', () => {
|
it('should not add threshold at index 0', () => {
|
||||||
const instance = setup();
|
const { instance } = setup();
|
||||||
|
|
||||||
instance.onAddThreshold(0);
|
instance.onAddThreshold(0);
|
||||||
|
|
||||||
|
|
@ -32,32 +45,32 @@ describe('Add threshold', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add threshold', () => {
|
it('should add threshold', () => {
|
||||||
const instance = setup();
|
const { instance } = setup();
|
||||||
|
|
||||||
instance.onAddThreshold(1);
|
instance.onAddThreshold(1);
|
||||||
|
|
||||||
expect(instance.state.thresholds).toEqual([
|
expect(instance.state.thresholds).toEqual([
|
||||||
{ index: 1, value: 50, color: '#EAB839' },
|
|
||||||
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
||||||
|
{ index: 1, value: 50, color: '#EAB839' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add another threshold above a first', () => {
|
it('should add another threshold above a first', () => {
|
||||||
const instance = setup({
|
const { instance } = setup({
|
||||||
thresholds: [{ index: 0, value: -Infinity, color: '#7EB26D' }, { index: 1, value: 50, color: '#EAB839' }],
|
thresholds: [{ index: 0, value: -Infinity, color: '#7EB26D' }, { index: 1, value: 50, color: '#EAB839' }],
|
||||||
});
|
});
|
||||||
|
|
||||||
instance.onAddThreshold(2);
|
instance.onAddThreshold(2);
|
||||||
|
|
||||||
expect(instance.state.thresholds).toEqual([
|
expect(instance.state.thresholds).toEqual([
|
||||||
{ index: 2, value: 75, color: '#6ED0E0' },
|
|
||||||
{ index: 1, value: 50, color: '#EAB839' },
|
|
||||||
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
||||||
|
{ index: 1, value: 50, color: '#EAB839' },
|
||||||
|
{ index: 2, value: 75, color: '#6ED0E0' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add another threshold between first and second index', () => {
|
it('should add another threshold between first and second index', () => {
|
||||||
const instance = setup({
|
const { instance } = setup({
|
||||||
thresholds: [
|
thresholds: [
|
||||||
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
||||||
{ index: 1, value: 50, color: '#EAB839' },
|
{ index: 1, value: 50, color: '#EAB839' },
|
||||||
|
|
@ -68,10 +81,10 @@ describe('Add threshold', () => {
|
||||||
instance.onAddThreshold(2);
|
instance.onAddThreshold(2);
|
||||||
|
|
||||||
expect(instance.state.thresholds).toEqual([
|
expect(instance.state.thresholds).toEqual([
|
||||||
{ index: 3, value: 75, color: '#6ED0E0' },
|
|
||||||
{ index: 2, value: 62.5, color: '#EF843C' },
|
|
||||||
{ index: 1, value: 50, color: '#EAB839' },
|
|
||||||
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
||||||
|
{ index: 1, value: 50, color: '#EAB839' },
|
||||||
|
{ index: 2, value: 62.5, color: '#EF843C' },
|
||||||
|
{ index: 3, value: 75, color: '#6ED0E0' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -83,7 +96,7 @@ describe('Remove threshold', () => {
|
||||||
{ index: 1, value: 50, color: '#EAB839' },
|
{ index: 1, value: 50, color: '#EAB839' },
|
||||||
{ index: 2, value: 75, color: '#6ED0E0' },
|
{ index: 2, value: 75, color: '#6ED0E0' },
|
||||||
];
|
];
|
||||||
const instance = setup({ thresholds });
|
const { instance } = setup({ thresholds });
|
||||||
|
|
||||||
instance.onRemoveThreshold(thresholds[0]);
|
instance.onRemoveThreshold(thresholds[0]);
|
||||||
|
|
||||||
|
|
@ -96,9 +109,7 @@ describe('Remove threshold', () => {
|
||||||
{ index: 1, value: 50, color: '#EAB839' },
|
{ index: 1, value: 50, color: '#EAB839' },
|
||||||
{ index: 2, value: 75, color: '#6ED0E0' },
|
{ index: 2, value: 75, color: '#6ED0E0' },
|
||||||
];
|
];
|
||||||
const instance = setup({
|
const { instance } = setup({ thresholds });
|
||||||
thresholds,
|
|
||||||
});
|
|
||||||
|
|
||||||
instance.onRemoveThreshold(thresholds[1]);
|
instance.onRemoveThreshold(thresholds[1]);
|
||||||
|
|
||||||
|
|
@ -116,7 +127,7 @@ describe('change threshold value', () => {
|
||||||
{ index: 1, value: 50, color: '#EAB839' },
|
{ index: 1, value: 50, color: '#EAB839' },
|
||||||
{ index: 2, value: 75, color: '#6ED0E0' },
|
{ index: 2, value: 75, color: '#6ED0E0' },
|
||||||
];
|
];
|
||||||
const instance = setup({ thresholds });
|
const { instance } = setup({ thresholds });
|
||||||
|
|
||||||
const mockEvent = ({ target: { value: '12' } } as any) as ChangeEvent<HTMLInputElement>;
|
const mockEvent = ({ target: { value: '12' } } as any) as ChangeEvent<HTMLInputElement>;
|
||||||
|
|
||||||
|
|
@ -126,7 +137,7 @@ describe('change threshold value', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update value', () => {
|
it('should update value', () => {
|
||||||
const instance = setup();
|
const { instance } = setup();
|
||||||
const thresholds = [
|
const thresholds = [
|
||||||
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
||||||
{ index: 1, value: 50, color: '#EAB839' },
|
{ index: 1, value: 50, color: '#EAB839' },
|
||||||
|
|
@ -150,24 +161,24 @@ describe('change threshold value', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('on blur threshold value', () => {
|
describe('on blur threshold value', () => {
|
||||||
it('should resort rows and update indexes', () => {
|
it.only('should resort rows and update indexes', () => {
|
||||||
const instance = setup();
|
const { instance } = setup();
|
||||||
const thresholds = [
|
const thresholds = [
|
||||||
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
||||||
{ index: 1, value: 78, color: '#EAB839' },
|
{ index: 1, value: 78, color: '#EAB839' },
|
||||||
{ index: 2, value: 75, color: '#6ED0E0' },
|
{ index: 2, value: 75, color: '#6ED0E0' },
|
||||||
];
|
];
|
||||||
|
|
||||||
instance.state = {
|
instance.setState({
|
||||||
thresholds,
|
thresholds,
|
||||||
};
|
});
|
||||||
|
|
||||||
instance.onBlur();
|
instance.onBlur();
|
||||||
|
|
||||||
expect(instance.state.thresholds).toEqual([
|
expect(instance.state.thresholds).toEqual([
|
||||||
{ index: 2, value: 78, color: '#EAB839' },
|
|
||||||
{ index: 1, value: 75, color: '#6ED0E0' },
|
|
||||||
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
{ index: 0, value: -Infinity, color: '#7EB26D' },
|
||||||
|
{ index: 1, value: 75, color: '#6ED0E0' },
|
||||||
|
{ index: 2, value: 78, color: '#EAB839' },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { PureComponent, ChangeEvent } from 'react';
|
import React, { PureComponent, ChangeEvent } from 'react';
|
||||||
import { Threshold } from '../../types';
|
import { Threshold } from '../../types';
|
||||||
import { ColorPicker } from '../ColorPicker/ColorPicker';
|
import { ColorPicker } from '..';
|
||||||
import { PanelOptionsGroup } from '../PanelOptionsGroup/PanelOptionsGroup';
|
import { PanelOptionsGroup } from '..';
|
||||||
import { colors } from '../../utils';
|
import { colors } from '../../utils';
|
||||||
import { getColorFromHexRgbOrName, ThemeContext } from '@grafana/ui';
|
import { getColorFromHexRgbOrName, ThemeContext } from '@grafana/ui';
|
||||||
|
|
||||||
|
|
@ -54,16 +54,16 @@ export class ThresholdsEditor extends PureComponent<Props, State> {
|
||||||
const value = afterThresholdValue - (afterThresholdValue - beforeThresholdValue) / 2;
|
const value = afterThresholdValue - (afterThresholdValue - beforeThresholdValue) / 2;
|
||||||
|
|
||||||
// Set a color
|
// Set a color
|
||||||
const color = colors.filter(c => newThresholds.some(t => t.color === c) === false)[0];
|
const color = colors.filter(c => !newThresholds.some(t => t.color === c))[0];
|
||||||
|
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
thresholds: this.sortThresholds([
|
thresholds: this.sortThresholds([
|
||||||
...newThresholds,
|
...newThresholds,
|
||||||
{
|
{
|
||||||
|
color,
|
||||||
index,
|
index,
|
||||||
value: value as number,
|
value: value as number,
|
||||||
color,
|
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
|
|
@ -137,10 +137,11 @@ export class ThresholdsEditor extends PureComponent<Props, State> {
|
||||||
onBlur = () => {
|
onBlur = () => {
|
||||||
this.setState(prevState => {
|
this.setState(prevState => {
|
||||||
const sortThresholds = this.sortThresholds([...prevState.thresholds]);
|
const sortThresholds = this.sortThresholds([...prevState.thresholds]);
|
||||||
let index = sortThresholds.length - 1;
|
let index = 0;
|
||||||
sortThresholds.forEach(t => {
|
sortThresholds.forEach(t => {
|
||||||
t.index = index--;
|
t.index = index++;
|
||||||
});
|
});
|
||||||
|
|
||||||
return { thresholds: sortThresholds };
|
return { thresholds: sortThresholds };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -153,12 +154,13 @@ export class ThresholdsEditor extends PureComponent<Props, State> {
|
||||||
|
|
||||||
sortThresholds = (thresholds: Threshold[]) => {
|
sortThresholds = (thresholds: Threshold[]) => {
|
||||||
return thresholds.sort((t1, t2) => {
|
return thresholds.sort((t1, t2) => {
|
||||||
return t2.value - t1.value;
|
return t1.value - t2.value;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
renderInput = (threshold: Threshold) => {
|
renderInput = (threshold: Threshold) => {
|
||||||
const value = threshold.index === 0 ? 'Base' : threshold.value;
|
const value = threshold.index === 0 ? 'Base' : threshold.value;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="thresholds-row-input-inner">
|
<div className="thresholds-row-input-inner">
|
||||||
<span className="thresholds-row-input-inner-arrow" />
|
<span className="thresholds-row-input-inner-arrow" />
|
||||||
|
|
@ -190,30 +192,32 @@ export class ThresholdsEditor extends PureComponent<Props, State> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { thresholds } = this.state;
|
const { thresholds } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeContext.Consumer>
|
<ThemeContext.Consumer>
|
||||||
{theme => {
|
{theme => {
|
||||||
return (
|
return (
|
||||||
<PanelOptionsGroup title="Thresholds">
|
<PanelOptionsGroup title="Thresholds">
|
||||||
<div className="thresholds">
|
<div className="thresholds">
|
||||||
{thresholds.map((threshold, index) => {
|
{thresholds
|
||||||
return (
|
.slice(0)
|
||||||
<div className="thresholds-row" key={`${threshold.index}-${index}`}>
|
.reverse()
|
||||||
<div
|
.map((threshold, index) => {
|
||||||
className="thresholds-row-add-button"
|
return (
|
||||||
onClick={() => this.onAddThreshold(threshold.index + 1)}
|
<div className="thresholds-row" key={`${threshold.index}-${index}`}>
|
||||||
>
|
<div
|
||||||
<i className="fa fa-plus" />
|
className="thresholds-row-add-button"
|
||||||
|
onClick={() => this.onAddThreshold(threshold.index + 1)}
|
||||||
|
>
|
||||||
|
<i className="fa fa-plus" />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="thresholds-row-color-indicator"
|
||||||
|
style={{ backgroundColor: getColorFromHexRgbOrName(threshold.color, theme.type) }}
|
||||||
|
/>
|
||||||
|
<div className="thresholds-row-input">{this.renderInput(threshold)}</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
);
|
||||||
className="thresholds-row-color-indicator"
|
})}
|
||||||
style={{ backgroundColor: getColorFromHexRgbOrName(threshold.color, theme.type) }}
|
|
||||||
/>
|
|
||||||
<div className="thresholds-row-input">{this.renderInput(threshold)}</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
</PanelOptionsGroup>
|
</PanelOptionsGroup>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Render should render with base threshold 1`] = `
|
||||||
|
<ContextConsumer>
|
||||||
|
<Component />
|
||||||
|
</ContextConsumer>
|
||||||
|
`;
|
||||||
|
|
@ -399,6 +399,12 @@ export class DashboardMigrator {
|
||||||
prefix: panel.options.prefix,
|
prefix: panel.options.prefix,
|
||||||
suffix: panel.options.suffix,
|
suffix: panel.options.suffix,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// correct order
|
||||||
|
if (panel.options.thresholds) {
|
||||||
|
panel.options.thresholds.reverse();
|
||||||
|
}
|
||||||
|
|
||||||
// this options prop was due to a bug
|
// this options prop was due to a bug
|
||||||
delete panel.options.options;
|
delete panel.options.options;
|
||||||
delete panel.options.unit;
|
delete panel.options.unit;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue