164 lines
5.4 KiB
JavaScript
164 lines
5.4 KiB
JavaScript
import * as _ from 'lodash';
|
|
import { connect } from 'react-redux';
|
|
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
|
|
import Formsy from 'formsy-react';
|
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
|
import { Link } from 'react-router';
|
|
import React from 'react';
|
|
import { List, Map } from 'immutable';
|
|
|
|
import { getAvailableNodesByRole,
|
|
getUntaggedAvailableNodes } from '../../selectors/nodesAssignment';
|
|
import { getNodesOperationInProgress } from '../../selectors/nodes';
|
|
import { getRoles } from '../../selectors/roles';
|
|
import { getCurrentPlan } from '../../selectors/plans';
|
|
import FormErrorList from '../ui/forms/FormErrorList';
|
|
import Modal from '../ui/Modal';
|
|
import NodesActions from '../../actions/NodesActions';
|
|
import NodesTable from '../nodes/NodesTable';
|
|
|
|
const messages = defineMessages({
|
|
assignUnassignNodes: {
|
|
id: 'NodesAssignment.assignUnassignNodes',
|
|
defaultMessage: 'Assign/Unassign Selected Nodes'
|
|
},
|
|
assignNodesToRole: {
|
|
id: 'NodesAssignment.assignNodesToRole',
|
|
defaultMessage: 'Assign Nodes to {roleName} Role'
|
|
},
|
|
done: {
|
|
id: 'NodesAssignment.done',
|
|
defaultMessage: 'Done'
|
|
}
|
|
});
|
|
|
|
class NodesAssignment extends React.Component {
|
|
|
|
componentDidMount() {
|
|
this.props.fetchNodes();
|
|
}
|
|
|
|
componentDidUpdate() {
|
|
this.invalidateForm(this.props.formFieldErrors.toJS());
|
|
}
|
|
|
|
invalidateForm(formFieldErrors) {
|
|
this.refs.nodesAssignmentForm.updateInputsWithError(formFieldErrors);
|
|
}
|
|
|
|
getTableActions() {
|
|
return (
|
|
<div className="btn-group">
|
|
<button className="btn btn-primary"
|
|
type="submit"
|
|
disabled={this.props.nodesOperationInProgress}>
|
|
<FormattedMessage {...messages.assignUnassignNodes}/>
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
handleSubmit(formData, resetForm, invalidateForm) {
|
|
const nodesToUpdateIds = _.keys(_.pickBy(formData, value => !!value));
|
|
|
|
let tagNodeIds = [];
|
|
let untagNodeIds = [];
|
|
|
|
_.each(nodesToUpdateIds, (nodeId) => {
|
|
if(this.props.untaggedAvailableNodes.keySeq().includes(nodeId)) {
|
|
tagNodeIds.push(nodeId);
|
|
} else {
|
|
untagNodeIds.push(nodeId);
|
|
}
|
|
});
|
|
|
|
const role = this.props.params.roleIdentifier;
|
|
const planName = this.props.currentPlan.name;
|
|
this.props.assignNodes(tagNodeIds, untagNodeIds, role, planName);
|
|
resetForm();
|
|
}
|
|
|
|
render() {
|
|
const { roleIdentifier } = this.props.params;
|
|
const role = this.props.roles.get(roleIdentifier);
|
|
const roleName = role ? role.title : roleIdentifier;
|
|
|
|
return (
|
|
<Modal dialogClasses="modal-xl">
|
|
<Formsy.Form ref="nodesAssignmentForm"
|
|
role="form"
|
|
className="form"
|
|
onSubmit={this.handleSubmit.bind(this)}>
|
|
<div className="modal-header">
|
|
<Link to="/deployment-plan"
|
|
type="button"
|
|
className="close">
|
|
<span aria-hidden="true" className="pficon pficon-close"/>
|
|
</Link>
|
|
<h4 className="modal-title">
|
|
<FormattedMessage {...messages.assignNodesToRole} values={{ roleName: roleName }}/>
|
|
</h4>
|
|
</div>
|
|
|
|
<div className="modal-body">
|
|
<FormErrorList errors={this.props.formErrors.toJS()}/>
|
|
<NodesTable nodes={this.props.availableNodesByRole.get(roleIdentifier, Map())}
|
|
roles={this.props.roles}
|
|
isFetchingNodes={this.props.isFetchingNodes}
|
|
dataOperationInProgress={this.props.nodesOperationInProgress}
|
|
nodesInProgress={this.props.nodesInProgress}
|
|
tableActions={this.getTableActions.bind(this)}/>
|
|
</div>
|
|
|
|
<div className="modal-footer">
|
|
<Link to="/deployment-plan" type="button" className="btn btn-default" >
|
|
<FormattedMessage {...messages.done}/>
|
|
</Link>
|
|
</div>
|
|
</Formsy.Form>
|
|
</Modal>
|
|
);
|
|
}
|
|
}
|
|
NodesAssignment.propTypes = {
|
|
assignNodes: React.PropTypes.func.isRequired,
|
|
availableNodesByRole: ImmutablePropTypes.map,
|
|
currentPlan: ImmutablePropTypes.record,
|
|
fetchNodes: React.PropTypes.func.isRequired,
|
|
formErrors: ImmutablePropTypes.list.isRequired,
|
|
formFieldErrors: ImmutablePropTypes.map.isRequired,
|
|
isFetchingNodes: React.PropTypes.bool,
|
|
nodesInProgress: ImmutablePropTypes.set,
|
|
nodesOperationInProgress: React.PropTypes.bool,
|
|
params: React.PropTypes.object.isRequired,
|
|
roles: ImmutablePropTypes.map.isRequired,
|
|
untaggedAvailableNodes: ImmutablePropTypes.map
|
|
};
|
|
NodesAssignment.defaultProps = {
|
|
formErrors: List(),
|
|
formFieldErrors: Map()
|
|
};
|
|
|
|
function mapStateToProps(state) {
|
|
return {
|
|
availableNodesByRole: getAvailableNodesByRole(state),
|
|
currentPlan: getCurrentPlan(state),
|
|
isFetchingNodes: state.nodes.get('isFetching'),
|
|
nodesInProgress: state.nodes.get('nodesInProgress'),
|
|
nodesOperationInProgress: getNodesOperationInProgress(state),
|
|
roles: getRoles(state),
|
|
untaggedAvailableNodes: getUntaggedAvailableNodes(state)
|
|
};
|
|
}
|
|
|
|
function mapDispatchToProps(dispatch) {
|
|
return {
|
|
fetchNodes: () => dispatch(NodesActions.fetchNodes()),
|
|
assignNodes: (tagNodeIds, untagNodeIds, role, planName) =>
|
|
dispatch(NodesActions.startNodesAssignment(tagNodeIds, untagNodeIds, role, planName)
|
|
)
|
|
};
|
|
}
|
|
|
|
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(NodesAssignment));
|