Refactor axes into redux state instead of CEO state
parent
7770017f4e
commit
9336326199
|
@ -43,3 +43,10 @@ export const updateGaugeColors = gaugeColors => ({
|
|||
gaugeColors,
|
||||
},
|
||||
})
|
||||
|
||||
export const updateAxes = axes => ({
|
||||
type: 'UPDATE_AXES',
|
||||
payload: {
|
||||
axes,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import React, {PropTypes} from 'react'
|
||||
import React, {Component, PropTypes} from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
import {bindActionCreators} from 'redux'
|
||||
|
||||
import OptIn from 'shared/components/OptIn'
|
||||
import Input from 'src/dashboards/components/DisplayOptionsInput'
|
||||
|
@ -11,105 +13,158 @@ import {GRAPH_TYPES} from 'src/dashboards/graphics/graph'
|
|||
const {LINEAR, LOG, BASE_2, BASE_10} = DISPLAY_OPTIONS
|
||||
const getInputMin = scale => (scale === LOG ? '0' : null)
|
||||
|
||||
const AxesOptions = ({
|
||||
axes: {y: {bounds, label, prefix, suffix, base, scale, defaultYLabel}},
|
||||
onSetBase,
|
||||
onSetScale,
|
||||
onSetLabel,
|
||||
onSetPrefixSuffix,
|
||||
onSetYAxisBoundMin,
|
||||
onSetYAxisBoundMax,
|
||||
cellType,
|
||||
}) => {
|
||||
const [min, max] = bounds
|
||||
import {updateAxes} from 'src/dashboards/actions/cellEditorOverlay'
|
||||
|
||||
const {menuOption} = GRAPH_TYPES.find(graph => graph.type === cellType)
|
||||
class AxesOptions extends Component {
|
||||
handleSetPrefixSuffix = e => {
|
||||
const {handleUpdateAxes, axes} = this.props
|
||||
const {prefix, suffix} = e.target.form
|
||||
|
||||
return (
|
||||
<FancyScrollbar
|
||||
className="display-options--cell y-axis-controls"
|
||||
autoHide={false}
|
||||
>
|
||||
<div className="display-options--cell-wrapper">
|
||||
<h5 className="display-options--header">
|
||||
{menuOption} Controls
|
||||
</h5>
|
||||
<form autoComplete="off" style={{margin: '0 -6px'}}>
|
||||
<div className="form-group col-sm-12">
|
||||
<label htmlFor="prefix">Title</label>
|
||||
<OptIn
|
||||
customPlaceholder={defaultYLabel || 'y-axis title'}
|
||||
customValue={label}
|
||||
onSetValue={onSetLabel}
|
||||
type="text"
|
||||
const newAxes = {
|
||||
...axes,
|
||||
y: {
|
||||
...axes.y,
|
||||
prefix: prefix.value,
|
||||
suffix: suffix.value,
|
||||
},
|
||||
}
|
||||
|
||||
handleUpdateAxes(newAxes)
|
||||
}
|
||||
|
||||
handleSetYAxisBoundMin = min => {
|
||||
const {handleUpdateAxes, axes} = this.props
|
||||
const {y: {bounds: [, max]}} = this.props.axes
|
||||
const newAxes = {...axes, y: {...axes.y, bounds: [min, max]}}
|
||||
|
||||
handleUpdateAxes(newAxes)
|
||||
}
|
||||
|
||||
handleSetYAxisBoundMax = max => {
|
||||
const {handleUpdateAxes, axes} = this.props
|
||||
const {y: {bounds: [min]}} = axes
|
||||
const newAxes = {...axes, y: {...axes.y, bounds: [min, max]}}
|
||||
|
||||
handleUpdateAxes(newAxes)
|
||||
}
|
||||
|
||||
handleSetLabel = label => {
|
||||
const {handleUpdateAxes, axes} = this.props
|
||||
const newAxes = {...axes, y: {...axes.y, label}}
|
||||
|
||||
handleUpdateAxes(newAxes)
|
||||
}
|
||||
|
||||
handleSetScale = scale => () => {
|
||||
const {handleUpdateAxes, axes} = this.props
|
||||
const newAxes = {...axes, y: {...axes.y, scale}}
|
||||
|
||||
handleUpdateAxes(newAxes)
|
||||
}
|
||||
|
||||
handleSetBase = base => () => {
|
||||
const {handleUpdateAxes, axes} = this.props
|
||||
const newAxes = {...axes, y: {...axes.y, base}}
|
||||
|
||||
handleUpdateAxes(newAxes)
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
axes: {y: {bounds, label, prefix, suffix, base, scale, defaultYLabel}},
|
||||
type,
|
||||
} = this.props
|
||||
|
||||
const [min, max] = bounds
|
||||
|
||||
const {menuOption} = GRAPH_TYPES.find(graph => graph.type === type)
|
||||
|
||||
return (
|
||||
<FancyScrollbar
|
||||
className="display-options--cell y-axis-controls"
|
||||
autoHide={false}
|
||||
>
|
||||
<div className="display-options--cell-wrapper">
|
||||
<h5 className="display-options--header">
|
||||
{menuOption} Controls
|
||||
</h5>
|
||||
<form autoComplete="off" style={{margin: '0 -6px'}}>
|
||||
<div className="form-group col-sm-12">
|
||||
<label htmlFor="prefix">Title</label>
|
||||
<OptIn
|
||||
customPlaceholder={defaultYLabel || 'y-axis title'}
|
||||
customValue={label}
|
||||
onSetValue={this.handleSetLabel}
|
||||
type="text"
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group col-sm-6">
|
||||
<label htmlFor="min">Min</label>
|
||||
<OptIn
|
||||
customPlaceholder={'min'}
|
||||
customValue={min}
|
||||
onSetValue={this.handleSetYAxisBoundMin}
|
||||
type="number"
|
||||
min={getInputMin(scale)}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group col-sm-6">
|
||||
<label htmlFor="max">Max</label>
|
||||
<OptIn
|
||||
customPlaceholder={'max'}
|
||||
customValue={max}
|
||||
onSetValue={this.handleSetYAxisBoundMax}
|
||||
type="number"
|
||||
min={getInputMin(scale)}
|
||||
/>
|
||||
</div>
|
||||
<Input
|
||||
name="prefix"
|
||||
id="prefix"
|
||||
value={prefix}
|
||||
labelText="Y-Value's Prefix"
|
||||
onChange={this.handleSetPrefixSuffix}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group col-sm-6">
|
||||
<label htmlFor="min">Min</label>
|
||||
<OptIn
|
||||
customPlaceholder={'min'}
|
||||
customValue={min}
|
||||
onSetValue={onSetYAxisBoundMin}
|
||||
type="number"
|
||||
min={getInputMin(scale)}
|
||||
<Input
|
||||
name="suffix"
|
||||
id="suffix"
|
||||
value={suffix}
|
||||
labelText="Y-Value's Suffix"
|
||||
onChange={this.handleSetPrefixSuffix}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group col-sm-6">
|
||||
<label htmlFor="max">Max</label>
|
||||
<OptIn
|
||||
customPlaceholder={'max'}
|
||||
customValue={max}
|
||||
onSetValue={onSetYAxisBoundMax}
|
||||
type="number"
|
||||
min={getInputMin(scale)}
|
||||
/>
|
||||
</div>
|
||||
<Input
|
||||
name="prefix"
|
||||
id="prefix"
|
||||
value={prefix}
|
||||
labelText="Y-Value's Prefix"
|
||||
onChange={onSetPrefixSuffix}
|
||||
/>
|
||||
<Input
|
||||
name="suffix"
|
||||
id="suffix"
|
||||
value={suffix}
|
||||
labelText="Y-Value's Suffix"
|
||||
onChange={onSetPrefixSuffix}
|
||||
/>
|
||||
<Tabber
|
||||
labelText="Y-Value's Format"
|
||||
tipID="Y-Values's Format"
|
||||
tipContent={TOOLTIP_CONTENT.FORMAT}
|
||||
>
|
||||
<Tab
|
||||
text="K/M/B"
|
||||
isActive={base === BASE_10}
|
||||
onClickTab={onSetBase(BASE_10)}
|
||||
/>
|
||||
<Tab
|
||||
text="K/M/G"
|
||||
isActive={base === BASE_2}
|
||||
onClickTab={onSetBase(BASE_2)}
|
||||
/>
|
||||
</Tabber>
|
||||
<Tabber labelText="Scale">
|
||||
<Tab
|
||||
text="Linear"
|
||||
isActive={scale === LINEAR}
|
||||
onClickTab={onSetScale(LINEAR)}
|
||||
/>
|
||||
<Tab
|
||||
text="Logarithmic"
|
||||
isActive={scale === LOG}
|
||||
onClickTab={onSetScale(LOG)}
|
||||
/>
|
||||
</Tabber>
|
||||
</form>
|
||||
</div>
|
||||
</FancyScrollbar>
|
||||
)
|
||||
<Tabber
|
||||
labelText="Y-Value's Format"
|
||||
tipID="Y-Values's Format"
|
||||
tipContent={TOOLTIP_CONTENT.FORMAT}
|
||||
>
|
||||
<Tab
|
||||
text="K/M/B"
|
||||
isActive={base === BASE_10}
|
||||
onClickTab={this.handleSetBase(BASE_10)}
|
||||
/>
|
||||
<Tab
|
||||
text="K/M/G"
|
||||
isActive={base === BASE_2}
|
||||
onClickTab={this.handleSetBase(BASE_2)}
|
||||
/>
|
||||
</Tabber>
|
||||
<Tabber labelText="Scale">
|
||||
<Tab
|
||||
text="Linear"
|
||||
isActive={scale === LINEAR}
|
||||
onClickTab={this.handleSetScale(LINEAR)}
|
||||
/>
|
||||
<Tab
|
||||
text="Logarithmic"
|
||||
isActive={scale === LOG}
|
||||
onClickTab={this.handleSetScale(LOG)}
|
||||
/>
|
||||
</Tabber>
|
||||
</form>
|
||||
</div>
|
||||
</FancyScrollbar>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const {arrayOf, func, shape, string} = PropTypes
|
||||
|
@ -128,13 +183,7 @@ AxesOptions.defaultProps = {
|
|||
}
|
||||
|
||||
AxesOptions.propTypes = {
|
||||
cellType: string.isRequired,
|
||||
onSetPrefixSuffix: func.isRequired,
|
||||
onSetYAxisBoundMin: func.isRequired,
|
||||
onSetYAxisBoundMax: func.isRequired,
|
||||
onSetLabel: func.isRequired,
|
||||
onSetScale: func.isRequired,
|
||||
onSetBase: func.isRequired,
|
||||
type: string.isRequired,
|
||||
axes: shape({
|
||||
y: shape({
|
||||
bounds: arrayOf(string),
|
||||
|
@ -142,6 +191,16 @@ AxesOptions.propTypes = {
|
|||
defaultYLabel: string,
|
||||
}),
|
||||
}).isRequired,
|
||||
handleUpdateAxes: func.isRequired,
|
||||
}
|
||||
|
||||
export default AxesOptions
|
||||
const mapStateToProps = ({cellEditorOverlay: {cell: {axes, type}}}) => ({
|
||||
axes,
|
||||
type,
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
handleUpdateAxes: bindActionCreators(updateAxes, dispatch),
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(AxesOptions)
|
||||
|
|
|
@ -28,7 +28,7 @@ class CellEditorOverlay extends Component {
|
|||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
const {cell: {queries, axes}, sources} = props
|
||||
const {cell: {queries}, sources} = props
|
||||
|
||||
let source = _.get(queries, ['0', 'source'], null)
|
||||
source = sources.find(s => s.links.self === source) || props.source
|
||||
|
@ -45,7 +45,6 @@ class CellEditorOverlay extends Component {
|
|||
queriesWorkingDraft,
|
||||
activeQueryIndex: 0,
|
||||
isDisplayOptionsTabActive: false,
|
||||
axes,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +66,7 @@ class CellEditorOverlay extends Component {
|
|||
}
|
||||
|
||||
handleSetSuffix = e => {
|
||||
const {axes} = this.state
|
||||
const {axes} = this.props.cell
|
||||
|
||||
this.setState({
|
||||
axes: {
|
||||
|
@ -96,46 +95,6 @@ class CellEditorOverlay extends Component {
|
|||
this.setState({queriesWorkingDraft: nextQueries})
|
||||
}
|
||||
|
||||
handleSetYAxisBoundMin = min => {
|
||||
const {axes} = this.state
|
||||
const {y: {bounds: [, max]}} = axes
|
||||
|
||||
this.setState({
|
||||
axes: {...axes, y: {...axes.y, bounds: [min, max]}},
|
||||
})
|
||||
}
|
||||
|
||||
handleSetYAxisBoundMax = max => {
|
||||
const {axes} = this.state
|
||||
const {y: {bounds: [min]}} = axes
|
||||
|
||||
this.setState({
|
||||
axes: {...axes, y: {...axes.y, bounds: [min, max]}},
|
||||
})
|
||||
}
|
||||
|
||||
handleSetLabel = label => {
|
||||
const {axes} = this.state
|
||||
|
||||
this.setState({axes: {...axes, y: {...axes.y, label}}})
|
||||
}
|
||||
|
||||
handleSetPrefixSuffix = e => {
|
||||
const {axes} = this.state
|
||||
const {prefix, suffix} = e.target.form
|
||||
|
||||
this.setState({
|
||||
axes: {
|
||||
...axes,
|
||||
y: {
|
||||
...axes.y,
|
||||
prefix: prefix.value,
|
||||
suffix: suffix.value,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
handleAddQuery = () => {
|
||||
const {queriesWorkingDraft} = this.state
|
||||
const newIndex = queriesWorkingDraft.length
|
||||
|
@ -157,7 +116,7 @@ class CellEditorOverlay extends Component {
|
|||
}
|
||||
|
||||
handleSaveCell = () => {
|
||||
const {queriesWorkingDraft, axes} = this.state
|
||||
const {queriesWorkingDraft} = this.state
|
||||
|
||||
const {cell, singleStatColors, gaugeColors} = this.props
|
||||
|
||||
|
@ -185,7 +144,6 @@ class CellEditorOverlay extends Component {
|
|||
this.props.onSave({
|
||||
...cell,
|
||||
queries,
|
||||
axes,
|
||||
colors,
|
||||
})
|
||||
}
|
||||
|
@ -198,34 +156,6 @@ class CellEditorOverlay extends Component {
|
|||
this.setState({activeQueryIndex})
|
||||
}
|
||||
|
||||
handleSetBase = base => () => {
|
||||
const {axes} = this.state
|
||||
|
||||
this.setState({
|
||||
axes: {
|
||||
...axes,
|
||||
y: {
|
||||
...axes.y,
|
||||
base,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
handleSetScale = scale => () => {
|
||||
const {axes} = this.state
|
||||
|
||||
this.setState({
|
||||
axes: {
|
||||
...axes,
|
||||
y: {
|
||||
...axes.y,
|
||||
scale,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
handleSetQuerySource = source => {
|
||||
const queriesWorkingDraft = this.state.queriesWorkingDraft.map(q => ({
|
||||
..._.cloneDeep(q),
|
||||
|
@ -325,7 +255,6 @@ class CellEditorOverlay extends Component {
|
|||
} = this.props
|
||||
|
||||
const {
|
||||
axes,
|
||||
activeQueryIndex,
|
||||
isDisplayOptionsTabActive,
|
||||
queriesWorkingDraft,
|
||||
|
@ -355,7 +284,6 @@ class CellEditorOverlay extends Component {
|
|||
initialBottomHeight={INITIAL_HEIGHTS.queryMaker}
|
||||
>
|
||||
<Visualization
|
||||
axes={axes}
|
||||
timeRange={timeRange}
|
||||
templates={templates}
|
||||
autoRefresh={autoRefresh}
|
||||
|
@ -376,20 +304,8 @@ class CellEditorOverlay extends Component {
|
|||
/>
|
||||
{isDisplayOptionsTabActive
|
||||
? <DisplayOptions
|
||||
axes={axes}
|
||||
onChooseColor={this.handleChooseColor}
|
||||
onValidateColorValue={this.handleValidateColorValue}
|
||||
onUpdateColorValue={this.handleUpdateColorValue}
|
||||
onAddGaugeThreshold={this.handleAddGaugeThreshold}
|
||||
onDeleteThreshold={this.handleDeleteThreshold}
|
||||
onSetBase={this.handleSetBase}
|
||||
onSetLabel={this.handleSetLabel}
|
||||
onSetScale={this.handleSetScale}
|
||||
queryConfigs={queriesWorkingDraft}
|
||||
onSetPrefixSuffix={this.handleSetPrefixSuffix}
|
||||
onSetSuffix={this.handleSetSuffix}
|
||||
onSetYAxisBoundMin={this.handleSetYAxisBoundMin}
|
||||
onSetYAxisBoundMax={this.handleSetYAxisBoundMax}
|
||||
/>
|
||||
: <QueryMaker
|
||||
source={this.getSource()}
|
||||
|
|
|
@ -35,17 +35,7 @@ class DisplayOptions extends Component {
|
|||
}
|
||||
|
||||
renderOptions = () => {
|
||||
const {
|
||||
cell,
|
||||
onSetBase,
|
||||
onSetScale,
|
||||
onSetLabel,
|
||||
onSetPrefixSuffix,
|
||||
onSetYAxisBoundMin,
|
||||
onSetYAxisBoundMax,
|
||||
onSetSuffix,
|
||||
} = this.props
|
||||
const {axes, axes: {y: {suffix}}} = this.state
|
||||
const {cell, cell: {axes: {y: {suffix}}}, onSetSuffix} = this.props
|
||||
|
||||
switch (cell.type) {
|
||||
case 'gauge':
|
||||
|
@ -53,18 +43,7 @@ class DisplayOptions extends Component {
|
|||
case 'single-stat':
|
||||
return <SingleStatOptions suffix={suffix} onSetSuffix={onSetSuffix} />
|
||||
default:
|
||||
return (
|
||||
<AxesOptions
|
||||
cellType={cell.type}
|
||||
axes={axes}
|
||||
onSetBase={onSetBase}
|
||||
onSetLabel={onSetLabel}
|
||||
onSetScale={onSetScale}
|
||||
onSetPrefixSuffix={onSetPrefixSuffix}
|
||||
onSetYAxisBoundMin={onSetYAxisBoundMin}
|
||||
onSetYAxisBoundMax={onSetYAxisBoundMax}
|
||||
/>
|
||||
)
|
||||
return <AxesOptions />
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,19 +62,20 @@ DisplayOptions.propTypes = {
|
|||
cell: shape({
|
||||
type: string.isRequired,
|
||||
}).isRequired,
|
||||
onSetPrefixSuffix: func.isRequired,
|
||||
axes: shape({
|
||||
y: shape({
|
||||
bounds: arrayOf(string),
|
||||
label: string,
|
||||
defaultYLabel: string,
|
||||
}),
|
||||
}).isRequired,
|
||||
onSetSuffix: func.isRequired,
|
||||
onSetYAxisBoundMin: func.isRequired,
|
||||
onSetYAxisBoundMax: func.isRequired,
|
||||
onSetScale: func.isRequired,
|
||||
onSetLabel: func.isRequired,
|
||||
onSetBase: func.isRequired,
|
||||
axes: shape({}).isRequired,
|
||||
queryConfigs: arrayOf(shape()).isRequired,
|
||||
}
|
||||
|
||||
const mapStateToProps = ({cellEditorOverlay: {cell}}) => ({
|
||||
const mapStateToProps = ({cellEditorOverlay: {cell, cell: {axes}}}) => ({
|
||||
cell,
|
||||
axes,
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, null)(DisplayOptions)
|
||||
|
|
|
@ -90,11 +90,12 @@ DashVisualization.contextTypes = {
|
|||
}
|
||||
|
||||
const mapStateToProps = ({
|
||||
cellEditorOverlay: {singleStatColors, gaugeColors, cell: {type}},
|
||||
cellEditorOverlay: {singleStatColors, gaugeColors, cell: {type, axes}},
|
||||
}) => ({
|
||||
gaugeColors,
|
||||
singleStatColors,
|
||||
type,
|
||||
axes,
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, null)(DashVisualization)
|
||||
|
|
|
@ -68,6 +68,13 @@ export default function cellEditorOverlay(state = initialState, action) {
|
|||
|
||||
return {...state, gaugeColors}
|
||||
}
|
||||
|
||||
case 'UPDATE_AXES': {
|
||||
const {axes} = action.payload
|
||||
const cell = {...state.cell, axes}
|
||||
|
||||
return {...state, cell}
|
||||
}
|
||||
}
|
||||
|
||||
return state
|
||||
|
|
Loading…
Reference in New Issue