Refactor axes into redux state instead of CEO state

pull/10616/head
Alex P 2018-02-20 23:39:38 -08:00
parent 7770017f4e
commit 9336326199
6 changed files with 193 additions and 223 deletions

View File

@ -43,3 +43,10 @@ export const updateGaugeColors = gaugeColors => ({
gaugeColors, gaugeColors,
}, },
}) })
export const updateAxes = axes => ({
type: 'UPDATE_AXES',
payload: {
axes,
},
})

View File

@ -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 OptIn from 'shared/components/OptIn'
import Input from 'src/dashboards/components/DisplayOptionsInput' import Input from 'src/dashboards/components/DisplayOptionsInput'
@ -11,19 +13,71 @@ import {GRAPH_TYPES} from 'src/dashboards/graphics/graph'
const {LINEAR, LOG, BASE_2, BASE_10} = DISPLAY_OPTIONS const {LINEAR, LOG, BASE_2, BASE_10} = DISPLAY_OPTIONS
const getInputMin = scale => (scale === LOG ? '0' : null) const getInputMin = scale => (scale === LOG ? '0' : null)
const AxesOptions = ({ import {updateAxes} from 'src/dashboards/actions/cellEditorOverlay'
class AxesOptions extends Component {
handleSetPrefixSuffix = e => {
const {handleUpdateAxes, axes} = this.props
const {prefix, suffix} = e.target.form
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}}, axes: {y: {bounds, label, prefix, suffix, base, scale, defaultYLabel}},
onSetBase, type,
onSetScale, } = this.props
onSetLabel,
onSetPrefixSuffix,
onSetYAxisBoundMin,
onSetYAxisBoundMax,
cellType,
}) => {
const [min, max] = bounds const [min, max] = bounds
const {menuOption} = GRAPH_TYPES.find(graph => graph.type === cellType) const {menuOption} = GRAPH_TYPES.find(graph => graph.type === type)
return ( return (
<FancyScrollbar <FancyScrollbar
@ -40,7 +94,7 @@ const AxesOptions = ({
<OptIn <OptIn
customPlaceholder={defaultYLabel || 'y-axis title'} customPlaceholder={defaultYLabel || 'y-axis title'}
customValue={label} customValue={label}
onSetValue={onSetLabel} onSetValue={this.handleSetLabel}
type="text" type="text"
/> />
</div> </div>
@ -49,7 +103,7 @@ const AxesOptions = ({
<OptIn <OptIn
customPlaceholder={'min'} customPlaceholder={'min'}
customValue={min} customValue={min}
onSetValue={onSetYAxisBoundMin} onSetValue={this.handleSetYAxisBoundMin}
type="number" type="number"
min={getInputMin(scale)} min={getInputMin(scale)}
/> />
@ -59,7 +113,7 @@ const AxesOptions = ({
<OptIn <OptIn
customPlaceholder={'max'} customPlaceholder={'max'}
customValue={max} customValue={max}
onSetValue={onSetYAxisBoundMax} onSetValue={this.handleSetYAxisBoundMax}
type="number" type="number"
min={getInputMin(scale)} min={getInputMin(scale)}
/> />
@ -69,14 +123,14 @@ const AxesOptions = ({
id="prefix" id="prefix"
value={prefix} value={prefix}
labelText="Y-Value's Prefix" labelText="Y-Value's Prefix"
onChange={onSetPrefixSuffix} onChange={this.handleSetPrefixSuffix}
/> />
<Input <Input
name="suffix" name="suffix"
id="suffix" id="suffix"
value={suffix} value={suffix}
labelText="Y-Value's Suffix" labelText="Y-Value's Suffix"
onChange={onSetPrefixSuffix} onChange={this.handleSetPrefixSuffix}
/> />
<Tabber <Tabber
labelText="Y-Value's Format" labelText="Y-Value's Format"
@ -86,24 +140,24 @@ const AxesOptions = ({
<Tab <Tab
text="K/M/B" text="K/M/B"
isActive={base === BASE_10} isActive={base === BASE_10}
onClickTab={onSetBase(BASE_10)} onClickTab={this.handleSetBase(BASE_10)}
/> />
<Tab <Tab
text="K/M/G" text="K/M/G"
isActive={base === BASE_2} isActive={base === BASE_2}
onClickTab={onSetBase(BASE_2)} onClickTab={this.handleSetBase(BASE_2)}
/> />
</Tabber> </Tabber>
<Tabber labelText="Scale"> <Tabber labelText="Scale">
<Tab <Tab
text="Linear" text="Linear"
isActive={scale === LINEAR} isActive={scale === LINEAR}
onClickTab={onSetScale(LINEAR)} onClickTab={this.handleSetScale(LINEAR)}
/> />
<Tab <Tab
text="Logarithmic" text="Logarithmic"
isActive={scale === LOG} isActive={scale === LOG}
onClickTab={onSetScale(LOG)} onClickTab={this.handleSetScale(LOG)}
/> />
</Tabber> </Tabber>
</form> </form>
@ -111,6 +165,7 @@ const AxesOptions = ({
</FancyScrollbar> </FancyScrollbar>
) )
} }
}
const {arrayOf, func, shape, string} = PropTypes const {arrayOf, func, shape, string} = PropTypes
@ -128,13 +183,7 @@ AxesOptions.defaultProps = {
} }
AxesOptions.propTypes = { AxesOptions.propTypes = {
cellType: string.isRequired, type: string.isRequired,
onSetPrefixSuffix: func.isRequired,
onSetYAxisBoundMin: func.isRequired,
onSetYAxisBoundMax: func.isRequired,
onSetLabel: func.isRequired,
onSetScale: func.isRequired,
onSetBase: func.isRequired,
axes: shape({ axes: shape({
y: shape({ y: shape({
bounds: arrayOf(string), bounds: arrayOf(string),
@ -142,6 +191,16 @@ AxesOptions.propTypes = {
defaultYLabel: string, defaultYLabel: string,
}), }),
}).isRequired, }).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)

View File

@ -28,7 +28,7 @@ class CellEditorOverlay extends Component {
constructor(props) { constructor(props) {
super(props) super(props)
const {cell: {queries, axes}, sources} = props const {cell: {queries}, sources} = props
let source = _.get(queries, ['0', 'source'], null) let source = _.get(queries, ['0', 'source'], null)
source = sources.find(s => s.links.self === source) || props.source source = sources.find(s => s.links.self === source) || props.source
@ -45,7 +45,6 @@ class CellEditorOverlay extends Component {
queriesWorkingDraft, queriesWorkingDraft,
activeQueryIndex: 0, activeQueryIndex: 0,
isDisplayOptionsTabActive: false, isDisplayOptionsTabActive: false,
axes,
} }
} }
@ -67,7 +66,7 @@ class CellEditorOverlay extends Component {
} }
handleSetSuffix = e => { handleSetSuffix = e => {
const {axes} = this.state const {axes} = this.props.cell
this.setState({ this.setState({
axes: { axes: {
@ -96,46 +95,6 @@ class CellEditorOverlay extends Component {
this.setState({queriesWorkingDraft: nextQueries}) 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 = () => { handleAddQuery = () => {
const {queriesWorkingDraft} = this.state const {queriesWorkingDraft} = this.state
const newIndex = queriesWorkingDraft.length const newIndex = queriesWorkingDraft.length
@ -157,7 +116,7 @@ class CellEditorOverlay extends Component {
} }
handleSaveCell = () => { handleSaveCell = () => {
const {queriesWorkingDraft, axes} = this.state const {queriesWorkingDraft} = this.state
const {cell, singleStatColors, gaugeColors} = this.props const {cell, singleStatColors, gaugeColors} = this.props
@ -185,7 +144,6 @@ class CellEditorOverlay extends Component {
this.props.onSave({ this.props.onSave({
...cell, ...cell,
queries, queries,
axes,
colors, colors,
}) })
} }
@ -198,34 +156,6 @@ class CellEditorOverlay extends Component {
this.setState({activeQueryIndex}) 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 => { handleSetQuerySource = source => {
const queriesWorkingDraft = this.state.queriesWorkingDraft.map(q => ({ const queriesWorkingDraft = this.state.queriesWorkingDraft.map(q => ({
..._.cloneDeep(q), ..._.cloneDeep(q),
@ -325,7 +255,6 @@ class CellEditorOverlay extends Component {
} = this.props } = this.props
const { const {
axes,
activeQueryIndex, activeQueryIndex,
isDisplayOptionsTabActive, isDisplayOptionsTabActive,
queriesWorkingDraft, queriesWorkingDraft,
@ -355,7 +284,6 @@ class CellEditorOverlay extends Component {
initialBottomHeight={INITIAL_HEIGHTS.queryMaker} initialBottomHeight={INITIAL_HEIGHTS.queryMaker}
> >
<Visualization <Visualization
axes={axes}
timeRange={timeRange} timeRange={timeRange}
templates={templates} templates={templates}
autoRefresh={autoRefresh} autoRefresh={autoRefresh}
@ -376,20 +304,8 @@ class CellEditorOverlay extends Component {
/> />
{isDisplayOptionsTabActive {isDisplayOptionsTabActive
? <DisplayOptions ? <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} queryConfigs={queriesWorkingDraft}
onSetPrefixSuffix={this.handleSetPrefixSuffix}
onSetSuffix={this.handleSetSuffix} onSetSuffix={this.handleSetSuffix}
onSetYAxisBoundMin={this.handleSetYAxisBoundMin}
onSetYAxisBoundMax={this.handleSetYAxisBoundMax}
/> />
: <QueryMaker : <QueryMaker
source={this.getSource()} source={this.getSource()}

View File

@ -35,17 +35,7 @@ class DisplayOptions extends Component {
} }
renderOptions = () => { renderOptions = () => {
const { const {cell, cell: {axes: {y: {suffix}}}, onSetSuffix} = this.props
cell,
onSetBase,
onSetScale,
onSetLabel,
onSetPrefixSuffix,
onSetYAxisBoundMin,
onSetYAxisBoundMax,
onSetSuffix,
} = this.props
const {axes, axes: {y: {suffix}}} = this.state
switch (cell.type) { switch (cell.type) {
case 'gauge': case 'gauge':
@ -53,18 +43,7 @@ class DisplayOptions extends Component {
case 'single-stat': case 'single-stat':
return <SingleStatOptions suffix={suffix} onSetSuffix={onSetSuffix} /> return <SingleStatOptions suffix={suffix} onSetSuffix={onSetSuffix} />
default: default:
return ( return <AxesOptions />
<AxesOptions
cellType={cell.type}
axes={axes}
onSetBase={onSetBase}
onSetLabel={onSetLabel}
onSetScale={onSetScale}
onSetPrefixSuffix={onSetPrefixSuffix}
onSetYAxisBoundMin={onSetYAxisBoundMin}
onSetYAxisBoundMax={onSetYAxisBoundMax}
/>
)
} }
} }
@ -83,19 +62,20 @@ DisplayOptions.propTypes = {
cell: shape({ cell: shape({
type: string.isRequired, type: string.isRequired,
}).isRequired, }).isRequired,
onSetPrefixSuffix: func.isRequired, axes: shape({
y: shape({
bounds: arrayOf(string),
label: string,
defaultYLabel: string,
}),
}).isRequired,
onSetSuffix: func.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, queryConfigs: arrayOf(shape()).isRequired,
} }
const mapStateToProps = ({cellEditorOverlay: {cell}}) => ({ const mapStateToProps = ({cellEditorOverlay: {cell, cell: {axes}}}) => ({
cell, cell,
axes,
}) })
export default connect(mapStateToProps, null)(DisplayOptions) export default connect(mapStateToProps, null)(DisplayOptions)

View File

@ -90,11 +90,12 @@ DashVisualization.contextTypes = {
} }
const mapStateToProps = ({ const mapStateToProps = ({
cellEditorOverlay: {singleStatColors, gaugeColors, cell: {type}}, cellEditorOverlay: {singleStatColors, gaugeColors, cell: {type, axes}},
}) => ({ }) => ({
gaugeColors, gaugeColors,
singleStatColors, singleStatColors,
type, type,
axes,
}) })
export default connect(mapStateToProps, null)(DashVisualization) export default connect(mapStateToProps, null)(DashVisualization)

View File

@ -68,6 +68,13 @@ export default function cellEditorOverlay(state = initialState, action) {
return {...state, gaugeColors} return {...state, gaugeColors}
} }
case 'UPDATE_AXES': {
const {axes} = action.payload
const cell = {...state.cell, axes}
return {...state, cell}
}
} }
return state return state