Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving TextAreaControl to support code and modal #2988

Merged
merged 1 commit into from
Jun 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,39 +1,86 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FormGroup, FormControl } from 'react-bootstrap';
import { Button, FormGroup, FormControl } from 'react-bootstrap';
import AceEditor from 'react-ace';
import 'brace/mode/sql';
import 'brace/mode/json';
import 'brace/mode/html';
import 'brace/mode/markdown';

import 'brace/theme/textmate';

import ControlHeader from '../ControlHeader';
import ModalTrigger from '../../../components/ModalTrigger';

const propTypes = {
name: PropTypes.string.isRequired,
label: PropTypes.string,
description: PropTypes.string,
onChange: PropTypes.func,
value: PropTypes.string,
height: PropTypes.number,
language: PropTypes.oneOf([null, 'json', 'html', 'sql', 'markdown']),
};

const defaultProps = {
label: null,
description: null,
onChange: () => {},
value: '',
height: 250,
};

export default class TextAreaControl extends React.Component {
onChange(event) {
onControlChange(event) {
this.props.onChange(event.target.value);
}
onAceChange(value) {
this.props.onChange(value);
}
renderEditor(inModal = false) {
if (this.props.language) {
return (
<AceEditor
mode={this.props.language}
theme="textmate"
style={{ border: '1px solid #CCC' }}
minLines={inModal ? 40 : 10}
maxLines={inModal ? 1000 : 10}
onChange={this.onAceChange.bind(this)}
width="100%"
editorProps={{ $blockScrolling: true }}
enableLiveAutocompletion
value={this.props.value}
/>
);
}
return (
<FormGroup controlId="formControlsTextarea">
<FormControl
componentClass="textarea"
placeholder="textarea"
onChange={this.onControlChange.bind(this)}
value={this.props.value}
style={{ height: this.props.height }}
/>
</FormGroup>);
}
render() {
const controlHeader = <ControlHeader {...this.props} />;
return (
<div>
<ControlHeader {...this.props} />
<FormGroup controlId="formControlsTextarea">
<FormControl
componentClass="textarea"
placeholder="textarea"
onChange={this.onChange.bind(this)}
value={this.props.value}
/>
</FormGroup>
{controlHeader}
{this.renderEditor()}
<ModalTrigger
bsSize="large"
modalTitle={controlHeader}
triggerNode={
<Button bsSize="small" className="m-t-5">
Edit <b>{this.props.language}</b> in modal
</Button>
}
modalBody={this.renderEditor(true)}
/>
</div>
);
}
Expand Down
5 changes: 5 additions & 0 deletions superset/assets/javascripts/explore/stores/controls.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -819,8 +819,10 @@ export const controls = {
markup_type: {
type: 'SelectControl',
label: 'Markup Type',
clearable: false,
choices: formatSelectOptions(['markdown', 'html']),
default: 'markdown',
validators: [v.nonEmpty],
description: 'Pick your favorite markup language',
},

Expand Down Expand Up @@ -858,6 +860,9 @@ export const controls = {
type: 'TextAreaControl',
label: 'Code',
description: 'Put your code here',
mapStateToProps: state => ({
language: state.controls ? state.controls.markup_type.value : null,
}),
default: '',
},

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import sinon from 'sinon';
import { expect } from 'chai';
import { describe, it, beforeEach } from 'mocha';
import { shallow } from 'enzyme';
import AceEditor from 'react-ace';

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

const defaultProps = {
Expand All @@ -15,7 +17,6 @@ const defaultProps = {

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

beforeEach(() => {
wrapper = shallow(<TextAreaControl {...defaultProps} />);
});
Expand All @@ -29,4 +30,12 @@ describe('SelectControl', () => {
select.simulate('change', { target: { value: 'x' } });
expect(defaultProps.onChange.calledWith('x')).to.be.true;
});

it('renders a AceEditor when language is specified', () => {
const props = Object.assign({}, defaultProps);
props.language = 'markdown';
wrapper = shallow(<TextAreaControl {...props} />);
expect(wrapper.find(FormControl)).to.have.lengthOf(0);
expect(wrapper.find(AceEditor)).to.have.lengthOf(1);
});
});
9 changes: 8 additions & 1 deletion superset/assets/stylesheets/superset.css
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,13 @@ div.widget .slice_container {

.editable-title input[type="button"]:focus {
outline: none;
}.m-r-5 {
}
.m-r-5 {
margin-right: 5px;
}
.m-t-5 {
margin-top: 5px;
}
.Select-menu-outer {
z-index: 10 !important;
}