updates on thresholds component

This commit is contained in:
Peter Holmberg 2018-12-14 16:27:42 +01:00
parent f8c8f2ec2c
commit 7c83d7ba82
3 changed files with 56 additions and 88 deletions

View File

@ -2,7 +2,7 @@ import React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import Thresholds from './Thresholds'; import Thresholds from './Thresholds';
import { defaultProps, OptionsProps } from './module'; import { defaultProps, OptionsProps } from './module';
import { PanelOptionsProps } from '../../../types'; import { BasicGaugeColor, PanelOptionsProps } from '../../../types';
const setup = (propOverrides?: object) => { const setup = (propOverrides?: object) => {
const props: PanelOptionsProps<OptionsProps> = { const props: PanelOptionsProps<OptionsProps> = {
@ -69,6 +69,7 @@ describe('Add at index', () => {
it('should return 1, one added threshold', () => { it('should return 1, one added threshold', () => {
const instance = setup(); const instance = setup();
instance.state = { instance.state = {
baseColor: BasicGaugeColor.Green,
thresholds: [ thresholds: [
{ index: 0, label: 'Min', value: 0, canRemove: false }, { index: 0, label: 'Min', value: 0, canRemove: false },
{ index: 1, label: '', value: 50, canRemove: true }, { index: 1, label: '', value: 50, canRemove: true },
@ -101,6 +102,7 @@ describe('Add at index', () => {
it('should return 2, one added threshold', () => { it('should return 2, one added threshold', () => {
const instance = setup(); const instance = setup();
instance.state = { instance.state = {
baseColor: BasicGaugeColor.Green,
thresholds: [ thresholds: [
{ index: 0, label: 'Min', value: 0, canRemove: false }, { index: 0, label: 'Min', value: 0, canRemove: false },
{ index: 1, label: '', value: 50, canRemove: true }, { index: 1, label: '', value: 50, canRemove: true },
@ -125,6 +127,7 @@ describe('change threshold value', () => {
]; ];
instance.state = { instance.state = {
baseColor: BasicGaugeColor.Green,
thresholds: mockThresholds, thresholds: mockThresholds,
}; };

View File

@ -1,5 +1,4 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import classNames from 'classnames/bind';
import tinycolor from 'tinycolor2'; import tinycolor from 'tinycolor2';
import { ColorPicker } from 'app/core/components/colorpicker/ColorPicker'; import { ColorPicker } from 'app/core/components/colorpicker/ColorPicker';
import { OptionModuleProps } from './module'; import { OptionModuleProps } from './module';
@ -7,6 +6,7 @@ import { BasicGaugeColor, Threshold } from 'app/types';
interface State { interface State {
thresholds: Threshold[]; thresholds: Threshold[];
baseColor: string;
} }
export default class Thresholds extends PureComponent<OptionModuleProps, State> { export default class Thresholds extends PureComponent<OptionModuleProps, State> {
@ -14,7 +14,8 @@ export default class Thresholds extends PureComponent<OptionModuleProps, State>
super(props); super(props);
this.state = { this.state = {
thresholds: props.options.thresholds, thresholds: [{ value: 50, canRemove: true, color: '#f2f2f2', index: 0, label: '' }],
baseColor: props.options.baseColor,
}; };
} }
@ -119,17 +120,24 @@ export default class Thresholds extends PureComponent<OptionModuleProps, State>
return index < thresholds.length ? thresholds[index].color : BasicGaugeColor.Red; return index < thresholds.length ? thresholds[index].color : BasicGaugeColor.Red;
}; };
insertAtIndex(index) {
const { thresholds } = this.state;
// If thresholds.length is greater or equal to 3
// it means a user has added one threshold
if (thresholds.length < 3 || index < 0) {
return 1;
}
return index;
}
renderThresholds() { renderThresholds() {
const { thresholds } = this.state; const { thresholds } = this.state;
return thresholds.map((threshold, index) => { return thresholds.map((threshold, index) => {
const rowStyle = classNames({
'threshold-row': true,
'threshold-row-min': index === 0,
});
return ( return (
<div className={rowStyle} key={`${threshold.index}-${index}`}> <div className="threshold-row" key={`${threshold.index}-${index}`}>
<div className="threshold-row-inner"> <div className="threshold-row-inner">
<div className="threshold-row-color"> <div className="threshold-row-color">
{threshold.color && ( {threshold.color && (
@ -157,112 +165,71 @@ export default class Thresholds extends PureComponent<OptionModuleProps, State>
}); });
} }
insertAtIndex(index) {
const { thresholds } = this.state;
// If thresholds.length is greater or equal to 3
// it means a user has added one threshold
if (thresholds.length < 3 || index < 0) {
return 1;
}
return index;
}
renderIndicatorSection(index) {
const { thresholds } = this.state;
const indicators = thresholds.length - 1;
if (index === 0 || index === thresholds.length) {
return (
<div
key={index}
className="indicator-section"
style={{
height: `calc(100%/${indicators})`,
}}
>
<div
onClick={() => this.onAddThreshold(this.insertAtIndex(index - 1))}
style={{
height: '100%',
background: this.getIndicatorColor(index),
}}
/>
</div>
);
}
return (
<div
key={index}
className="indicator-section"
style={{
height: `calc(100%/${indicators})`,
}}
>
<div
onClick={() => this.onAddThreshold(this.insertAtIndex(index))}
style={{
height: '50%',
background: this.getIndicatorColor(index),
}}
/>
<div
onClick={() => this.onAddThreshold(this.insertAtIndex(index + 1))}
style={{
height: `50%`,
background: this.getIndicatorColor(index),
}}
/>
</div>
);
}
renderIndicator() { renderIndicator() {
const { thresholds } = this.state; const { thresholds } = this.state;
if (thresholds.length > 0) {
return thresholds.map((t, i) => { return thresholds.map((t, i) => {
if (i <= thresholds.length - 1) { return (
return this.renderIndicatorSection(i); <div
} key={`${t.value}-${i}`}
className="indicator-section"
return null; style={{
height: '50%',
}}
>
<div
onClick={() => this.onAddThreshold(this.insertAtIndex(1))}
style={{
height: '100%',
background: this.getIndicatorColor(i),
}}
/>
</div>
);
}); });
} }
renderBaseIndicator() {
return ( return (
<div className="indicator-section" style={{ height: '100%' }}> <div className="indicator-section" style={{ height: '100%' }}>
<div <div
onClick={() => this.onAddThreshold(0)} onClick={() => this.onAddThreshold(1)}
style={{ height: '100%', backgroundColor: this.props.options.baseColor }} style={{ height: '50px', backgroundColor: this.props.options.baseColor }}
/> />
</div> </div>
); );
} }
render() { renderBase() {
const { thresholds } = this.state; const { baseColor } = this.props.options;
return ( return (
<div className="section gf-form-group">
<h5 className="page-heading">Thresholds</h5>
<span>Click the colored line to add a threshold</span>
<div className="thresholds">
<div className="color-indicators">{this.renderIndicator()}</div>
<div className="threshold-rows">
<div className="threshold-row threshold-row-base"> <div className="threshold-row threshold-row-base">
<div className="threshold-row-inner"> <div className="threshold-row-inner threshold-row-inner--base">
<div className="threshold-row-color"> <div className="threshold-row-color">
<div className="threshold-row-color-inner"> <div className="threshold-row-color-inner">
<ColorPicker color={BasicGaugeColor.Green} onChange={color => this.onChangeBaseColor(color)} /> <ColorPicker color={baseColor} onChange={color => this.onChangeBaseColor(color)} />
</div> </div>
</div> </div>
<div className="threshold-row-label">Base</div> <div className="threshold-row-label">Base</div>
</div> </div>
</div> </div>
{thresholds.length > 0 && this.renderThresholds()} );
}
render() {
return (
<div className="section gf-form-group">
<h5 className="page-heading">Thresholds</h5>
<span>Click the colored line to add a threshold</span>
<div className="thresholds">
<div className="color-indicators">
{this.renderIndicator()}
{this.renderBaseIndicator()}
</div>
<div className="threshold-rows">
{this.renderThresholds()}
{this.renderBase()}
</div> </div>
</div> </div>
</div> </div>

View File

@ -25,8 +25,11 @@
border-radius: $border-radius; border-radius: $border-radius;
display: flex; display: flex;
overflow: hidden; overflow: hidden;
width: 300px;
height: 37px; height: 37px;
&--base {
width: auto;
}
} }
.threshold-row-color { .threshold-row-color {
@ -48,13 +51,12 @@
.threshold-row-input { .threshold-row-input {
padding: 8px 10px; padding: 8px 10px;
width: 230px; width: 150px;
} }
.threshold-row-label { .threshold-row-label {
background-color: $input-label-bg; background-color: $input-label-bg;
padding: 5px; padding: 5px;
width: 36px;
display: flex; display: flex;
align-items: center; align-items: center;
} }
@ -66,11 +68,6 @@
} }
.threshold-row-base { .threshold-row-base {
margin-top: -22px;
}
.threshold-row-max {
margin-bottom: -22px;
} }
.threshold-row-remove { .threshold-row-remove {
@ -103,6 +100,7 @@
.color-indicators { .color-indicators {
width: 15px; width: 15px;
border-radius: $border-radius; border-bottom-left-radius: $border-radius;
border-bottom-right-radius: $border-radius;
overflow: hidden; overflow: hidden;
} }