|
import React from 'react' |
|
import Form from 'react-formal' |
|
import { |
|
Alert, |
|
Button, |
|
Col, ControlLabel, |
|
Form as BsForm, FormControl, FormGroup as BsFormGroup, |
|
HelpBlock, |
|
} from 'react-bootstrap' |
|
|
|
import {APPS, APPS_BY_RELEASE} from './metadata' |
|
import schema, { serialize } from './schema'; |
|
import SelectApps from './SelectApps' |
|
|
|
const EMR_RELEASES = Object.keys(APPS_BY_RELEASE) |
|
|
|
|
|
function trimApplications(label, applications) { |
|
// If the release label has been cleared, don't do anything else |
|
if (label === '') { |
|
return applications |
|
} |
|
|
|
let nextAppIds = Object.keys(APPS_BY_RELEASE[label]) |
|
return applications.filter(appId => nextAppIds.indexOf(appId) !== -1) |
|
} |
|
|
|
|
|
function ReleaseSelect({ value, onChange, children }) { |
|
return ( |
|
<FormControl |
|
value={value} |
|
onChange={onChange} |
|
componentClass="select" |
|
> |
|
<option value=""></option> |
|
{EMR_RELEASES.map(version => |
|
<option key={version} value={version}>{version}</option> |
|
)} |
|
</FormControl> |
|
); |
|
} |
|
|
|
// not necessary but takes advantage of the twbs error styling |
|
function FormGroup({ for: forFields, ...props }) { |
|
if (!forFields) return <BsFormGroup {...props} /> |
|
return ( |
|
<Form.Trigger for={forFields} events={null}> |
|
{({ messages, ...triggerProps }) => |
|
<BsFormGroup {...props} {...triggerProps} |
|
validationState={Object.keys(messages).length ? 'error' : null} |
|
/> |
|
} |
|
</Form.Trigger> |
|
); |
|
} |
|
|
|
let FormExample = React.createClass({ |
|
getInitialState() { |
|
return { |
|
value: schema.default(), |
|
errors: {} |
|
} |
|
}, |
|
|
|
handleChange(value) { |
|
// we could also adjust `errors` here to remove application errors |
|
// when releaseLabel is empty instead of the `alsoValidates` on the field |
|
this.setState({ value }) |
|
}, |
|
|
|
handleErrors(errors) { |
|
this.setState({ errors }) |
|
}, |
|
|
|
handleSubmit(cluster) { |
|
console.log(JSON.stringify(serialize(cluster), null, 2)) |
|
}, |
|
|
|
render() { |
|
let { errors, value } = this.state |
|
|
|
let releaseSelected = !!value.releaseLabel |
|
let isV4 = /^emr-4/.test(value.releaseLabel) |
|
|
|
return ( |
|
<Form |
|
debug |
|
horizontal |
|
component={BsForm} |
|
value={value} |
|
errors={errors} |
|
schema={schema} |
|
onChange={this.handleChange} |
|
onError={this.handleErrors} |
|
onSubmit={this.handleSubmit} |
|
> |
|
<legend>React Form Example</legend> |
|
<FormGroup controlId="releaseLabel" for="releaseLabel"> |
|
<Col componentClass={ControlLabel} sm={3} md={2}>Release Label:</Col> |
|
<Col sm={9} md={6}> |
|
<Form.Field |
|
type={ReleaseSelect} |
|
name="releaseLabel" |
|
alsoValidates="applications" |
|
mapFromValue={{ |
|
releaseLabel: e => e.target.value, |
|
applications: e => trimApplications(e.target.value, value.applications) |
|
}} |
|
/> |
|
<Form.Message for="releaseLabel" component={HelpBlock} /> |
|
<HelpBlock> |
|
The identifier for the EMR release, which includes a set of software, |
|
to use with Amazon EC2 instances that are part of an Amazon EMR cluster. |
|
See <a href="http://docs.aws.amazon.com/ElasticMapReduce/latest/ReleaseGuide/emr-release-components.html" target="_blank">About Amazon EMR Releases</a>. |
|
</HelpBlock> |
|
</Col> |
|
</FormGroup> |
|
<FormGroup for='applications'> |
|
<Col componentClass={ControlLabel} sm={3} md={2}>Applications:</Col> |
|
<Col sm={9} md={6}> |
|
{!releaseSelected && <HelpBlock>Select a Release Label to show available applications.</HelpBlock>} |
|
{releaseSelected && <div> |
|
<Form.Field |
|
name="applications" |
|
type={SelectApps} |
|
isV4={isV4} |
|
versions={APPS_BY_RELEASE[value.releaseLabel]} |
|
/> |
|
{errors.applications |
|
? <Form.Message for="applications" component={Alert} bsStyle="danger" /> |
|
: <HelpBlock>Select applications to install on your cluster.</HelpBlock> |
|
} |
|
</div>} |
|
</Col> |
|
</FormGroup> |
|
|
|
<FormGroup> |
|
<Col smOffset={3} sm={9} mdOffset={2} md={6}> |
|
<hr/> |
|
<Button bsStyle="primary" type="submit">Create Cluster</Button> |
|
</Col> |
|
</FormGroup> |
|
</Form> |
|
) |
|
} |
|
}) |
|
|
|
export default FormExample |