Skip to content

Commit

Permalink
React component for creating Nuage subnet
Browse files Browse the repository at this point in the history
With this commit we implement react component used to capture
user inputs for creating CloudSubnet. Also, we add button to
NetworkRouter details page to trigger the flow.

RFE BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1574972

Signed-off-by: Miha Pleško <[email protected]>
  • Loading branch information
miha-plesko committed Jul 31, 2018
1 parent 0d45ee0 commit eb2a14b
Show file tree
Hide file tree
Showing 9 changed files with 293 additions and 0 deletions.
31 changes: 31 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"presets": [
[
"env",
{
"targets": {
"browsers": [
"> 1%",
"last 2 versions",
"Firefox ESR",
"IE 10",
"IE 11"
]
}
}
],
"react",
"es2015",
],
"plugins": [
"transform-class-properties",
"transform-export-extensions",
"transform-object-rest-spread",
"transform-object-assign"
],
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@
/config/environments/*.local.yml

/spec/manageiq

node_modules/
yarn.lock
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# using yarn
package-lock = false
4 changes: 4 additions & 0 deletions .postcssrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
plugins:
postcss-smart-import: {}
precss: {}
autoprefixer: {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module ManageIQ
module Providers
module Nuage
module ToolbarOverrides
class NetworkRouterCenter < ::ApplicationHelper::Toolbar::Override
button_group(
'nuage_network_router',
[
select(
:nuage_network_router,
'fa fa-cog fa-lg',
t = N_('Edit'),
t,
:items => [
button(
:nuage_create_cloud_subnet,
'pficon pficon-add-circle-o fa-lg',
t = N_('Create L3 Cloud Subnet'),
t,
:data => {'function' => 'sendDataWithRx',
'function-data' => {:controller => 'provider_dialogs',
:button => :nuage_create_cloud_subnet,
:modal_title => N_('Create L3 Cloud Subnet'),
:component_name => 'CreateNuageCloudSubnetForm'}.to_json},
:klass => ApplicationHelper::Button::ButtonWithoutRbacCheck
),
]
)
]
)
end
end
end
end
end
68 changes: 68 additions & 0 deletions app/javascript/components/create-nuage-cloud-subnet-form.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import NuageCloudSubnetForm from './nuage-cloud-subnet-form'

const API = window.API;

const createSubnet = (values, emsId, routerRef) => {
API.post(`/api/providers/${emsId}/cloud_subnets`, {
action: 'create',
resource: {...values, router_ref: routerRef},
}).then(response => {
let res = response['results'][0];
window.add_flash(res.message, res.success ? 'success' : 'error');
})
};

class CreateNuageCloudSubnetForm extends React.Component {
constructor(props) {
super(props);
this.handleFormStateUpdate = this.handleFormStateUpdate.bind(this);
this.routerRef = 'ebca9d3b-53a4-4fd4-8268-196cb3fa6072'; // TODO: pass from Rails
this.emsId = 4; // TODO: pass from Rails
}

componentDidMount() {
this.props.dispatch({
type: 'FormButtons.init',
payload: {
newRecord: true,
pristine: true,
addClicked: () => {
createSubnet(this.state.values, this.emsId, this.routerRef);
}
},
});
}

handleFormStateUpdate(formState) {
this.props.dispatch({
type: 'FormButtons.saveable',
payload: formState.valid,
});
this.props.dispatch({
type: 'FormButtons.pristine',
payload: formState.pristine,
});
this.setState({ values: formState.values });
}

render() {
return (
<NuageCloudSubnetForm
onSave={values => createSubnet(values, this.emsId, this.routerRef)}
onCancel={() => {} }
loadData={() => {} }
updateFormState={this.handleFormStateUpdate}
hideControls={true}
/>
);
}
}

CreateNuageCloudSubnetForm.propTypes = {
dispatch: PropTypes.func.isRequired,
};

export default connect()(CreateNuageCloudSubnetForm);
106 changes: 106 additions & 0 deletions app/javascript/components/nuage-cloud-subnet-form.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import React, { Component } from 'react';
import { Form, Field, FormSpy } from 'react-final-form';
import { Form as PfForm, Grid, Button, Col, Row, Spinner } from 'patternfly-react';
import PropTypes from 'prop-types';
import { required, addValidator } from 'redux-form-validators';

import { FinalFormField, FinalFormTextArea, FinalFormSelect } from '@manageiq/react-ui-components/dist/forms';

const ip4Validator = addValidator({
defaultMessage: 'Must be IPv4 address',
validator: function(options, value, allValues) {
return (/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/).test(value)
}
});

const netmaskValidator = addValidator({
defaultMessage: 'Must be netmask',
validator: function(options, value, allValues) {
return (/^(((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(0|128|192|224|240|248|252|254)\.0\.0)|(255\.255\.(0|128|192|224|240|248|252|254)\.0)|(255\.255\.255\.(0|128|192|224|240|248|252|254)))$/).test(value)
}
});

class NuageCloudSubnetForm extends Component {
render() {
const {
onSave,
onCancel,
updateFormState,
hideControls,
} = this.props;
return (
<Form
onSubmit={onSave}
render={({ handleSubmit }) => (
<PfForm horizontal>
<FormSpy onChange={state => updateFormState({ ...state, values: state.values })} />
<Grid fluid>
<Row>
<Col xs={12}>
<Field
name="name"
component={FinalFormField}
label="Name"
placeholder="Subnet Name"
validate={required({ msg: 'Name is required' })}
/>
</Col>
<Col xs={12}>
<Field
name="address"
component={FinalFormField}
label="Address"
placeholder="100.100.100.0"
validate={ip4Validator()}
/>
</Col>
<Col xs={12}>
<Field
name="netmask"
component={FinalFormField}
label="Netmask"
placeholder="255.255.255.0"
validate={netmaskValidator()}
/>
</Col>
<Col xs={12}>
<Field
name="gateway"
component={FinalFormField}
label="Gateway"
placeholder="100.100.100.1"
validate={ip4Validator()}
/>
</Col>
<hr />
</Row>
{
!hideControls &&
<Row>
<Col className="pull-right">
<Button bsStyle="primary" onClick={handleSubmit}>Submit</Button>
<Button onClick={onCancel}>Cancel</Button>
</Col>
</Row>
}
</Grid>
</PfForm>
)}
/>
);
}
}

NuageCloudSubnetForm.propTypes = {
onSave: PropTypes.func.isRequired,
onCancel: PropTypes.func.isRequired,
loadData: PropTypes.func.isRequired,
updateFormState: PropTypes.func.isRequired,
hideControls: PropTypes.bool,
};

NuageCloudSubnetForm.defaultProps = {
hideControls: false,
};

export default NuageCloudSubnetForm;
3 changes: 3 additions & 0 deletions app/javascript/packs/component-definitions-common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import CreateNuageCloudSubnetForm from '../components/create-nuage-cloud-subnet-form';

ManageIQ.component.addReact('CreateNuageCloudSubnetForm', CreateNuageCloudSubnetForm);
41 changes: 41 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "manageiq-providers-nuage",
"version": "1.0.0",
"description": "ManageIQ Cloud Management Platform",
"main": "index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/ManageIQ/manageiq.git"
},
"author": "ManageIQ",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/ManageIQ/manageiq/issues"
},
"homepage": "https://github.com/ManageIQ/manageiq#readme",
"dependencies": {
"@manageiq/react-ui-components": "~0.9.5",
"prop-types": "^15.6.0",
"react": "^16.3.1",
"react-dom": "^16.3.1",
"react-redux": "^5.0.7",
"redux": "^4.0.0"
},
"devDependencies": {
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-export-extensions": "^6.22.0",
"babel-plugin-transform-object-assign": "^6.8.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-1": "^6.24.1"
},
"engines": {
"node": ">= 6.9.1",
"npm": ">= 3.10.3",
"yarn": ">= 0.20.1"
}
}

0 comments on commit eb2a14b

Please sign in to comment.