Skip to content

Commit

Permalink
[explore] include ControlHeader as part of Control interface (#2809)
Browse files Browse the repository at this point in the history
* [explore] include ControlHeader as part of Control interface

* Adressing comments
  • Loading branch information
mistercrunch committed May 25, 2017
1 parent 0c9f9b6 commit 4d12251
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 36 deletions.
8 changes: 0 additions & 8 deletions superset/assets/javascripts/explore/components/Control.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import ControlHeader from './ControlHeader';

import CheckboxControl from './controls/CheckboxControl';
import FilterControl from './controls/FilterControl';
Expand Down Expand Up @@ -90,13 +89,6 @@ export default class Control extends React.PureComponent {
const divStyle = this.props.hidden ? { display: 'none' } : null;
return (
<div style={divStyle}>
<ControlHeader
label={this.props.label}
description={this.props.description}
renderTrigger={this.props.renderTrigger}
validationErrors={this.props.validationErrors}
rightNode={this.props.rightNode}
/>
<ControlType
onChange={this.onChange}
{...this.props}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const propTypes = {
validationErrors: PropTypes.array,
renderTrigger: PropTypes.bool,
rightNode: PropTypes.node,
leftNode: PropTypes.node,
};

const defaultProps = {
Expand All @@ -17,7 +18,7 @@ const defaultProps = {
};

export default function ControlHeader({
label, description, validationErrors, renderTrigger, rightNode }) {
label, description, validationErrors, renderTrigger, leftNode, rightNode }) {
const hasError = (validationErrors.length > 0);
return (
<div>
Expand Down Expand Up @@ -64,6 +65,9 @@ export default function ControlHeader({
{' '}
</span>
}
{leftNode &&
<span>{leftNode}</span>
}
</ControlLabel>
</div>
{rightNode &&
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Checkbox } from 'react-bootstrap';
import ControlHeader from '../ControlHeader';

const propTypes = {
name: PropTypes.string.isRequired,
Expand All @@ -21,9 +22,14 @@ export default class CheckboxControl extends React.Component {
}
render() {
return (
<Checkbox
checked={this.props.value}
onChange={this.onToggle.bind(this)}
<ControlHeader
{...this.props}
leftNode={
<Checkbox
checked={this.props.value}
onChange={this.onToggle.bind(this)}
/>
}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export default class Filter extends React.Component {
renderFilterFormControl(filter) {
const operator = operators[filter.op];
if (operator.useSelect && !this.props.having) {
// TODO should use a simple Select, not a control here...
return (
<SelectControl
multi={operator.multi}
Expand All @@ -103,6 +104,7 @@ export default class Filter extends React.Component {
isLoading={this.state.valuesLoading}
choices={this.state.valueChoices}
onChange={this.changeSelect.bind(this)}
showHeader={false}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import Select, { Creatable } from 'react-select';
import ControlHeader from '../ControlHeader';

const propTypes = {
choices: PropTypes.array,
Expand All @@ -13,6 +14,7 @@ const propTypes = {
name: PropTypes.string.isRequired,
onChange: PropTypes.func,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array]),
showHeader: PropTypes.bool,
};

const defaultProps = {
Expand All @@ -24,6 +26,7 @@ const defaultProps = {
label: null,
multi: false,
onChange: () => {},
showHeader: true,
};

export default class SelectControl extends React.PureComponent {
Expand Down Expand Up @@ -115,6 +118,9 @@ export default class SelectControl extends React.PureComponent {
(<Creatable {...selectProps} />) : (<Select {...selectProps} />);
return (
<div>
{this.props.showHeader &&
<ControlHeader {...this.props} />
}
{selectWrap}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormGroup, FormControl } from 'react-bootstrap';
import ControlHeader from '../ControlHeader';

const propTypes = {
name: PropTypes.string.isRequired,
Expand All @@ -23,14 +24,17 @@ export default class TextAreaControl extends React.Component {
}
render() {
return (
<FormGroup controlId="formControlsTextarea">
<FormControl
componentClass="textarea"
placeholder="textarea"
onChange={this.onChange.bind(this)}
value={this.props.value}
/>
</FormGroup>
<div>
<ControlHeader {...this.props} />
<FormGroup controlId="formControlsTextarea">
<FormControl
componentClass="textarea"
placeholder="textarea"
onChange={this.onChange.bind(this)}
value={this.props.value}
/>
</FormGroup>
</div>
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { FormGroup, FormControl } from 'react-bootstrap';
import * as v from '../../validators';
import ControlHeader from '../ControlHeader';

const propTypes = {
name: PropTypes.string.isRequired,
Expand Down Expand Up @@ -58,14 +59,17 @@ export default class TextControl extends React.Component {
}
render() {
return (
<FormGroup controlId="formInlineName" bsSize="small">
<FormControl
type="text"
placeholder=""
onChange={this.onChange}
value={this.state.value}
/>
</FormGroup>
<div>
<ControlHeader {...this.props} />
<FormGroup controlId="formInlineName" bsSize="small">
<FormControl
type="text"
placeholder=""
onChange={this.onChange}
value={this.state.value}
/>
</FormGroup>
</div>
);
}
}
Expand Down
2 changes: 2 additions & 0 deletions superset/assets/javascripts/explore/stores/controls.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -972,13 +972,15 @@ export const controls = {
type: 'CheckboxControl',
label: 'Donut',
default: false,
renderTrigger: true,
description: 'Do you want a donut or a pie?',
},

labels_outside: {
type: 'CheckboxControl',
label: 'Put labels outside',
default: true,
renderTrigger: true,
description: 'Put the labels outside the pie?',
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,24 @@ import { Checkbox } from 'react-bootstrap';
import sinon from 'sinon';
import { expect } from 'chai';
import { describe, it, beforeEach } from 'mocha';
import { shallow } from 'enzyme';
import { mount } from 'enzyme';

import CheckboxControl from '../../../../javascripts/explore/components/controls/CheckboxControl';

const defaultProps = {
name: 'show_legend',
onChange: sinon.spy(),
value: false,
};

describe('CheckboxControl', () => {
let wrapper;

beforeEach(() => {
wrapper = shallow(<CheckboxControl {...defaultProps} />);
wrapper = mount(<CheckboxControl {...defaultProps} />);
});

it('renders a Checkbox', () => {
expect(wrapper.find(Checkbox)).to.have.lengthOf(1);
});

it('calls onChange when toggled', () => {
const checkbox = wrapper.find(Checkbox);
checkbox.simulate('change', { value: true });
expect(defaultProps.onChange.calledWith(true)).to.be.true;
});
});

0 comments on commit 4d12251

Please sign in to comment.