Add Organization Edit view

This commit is contained in:
Marliana Lara 2019-02-22 14:53:17 -05:00
parent f1fefbf5f0
commit d2cf2c275b
No known key found for this signature in database
GPG Key ID: 38C73B40DFA809EE
3 changed files with 304 additions and 24 deletions

View File

@ -30,9 +30,10 @@ const paginationStyling = {
class Lookup extends React.Component {
constructor (props) {
super(props);
this.state = {
isModalOpen: false,
lookupSelectedItems: [],
lookupSelectedItems: props.value || [],
results: [],
count: 0,
page: 1,
@ -43,7 +44,6 @@ class Lookup extends React.Component {
};
this.onSetPage = this.onSetPage.bind(this);
this.handleModalToggle = this.handleModalToggle.bind(this);
this.wrapTags = this.wrapTags.bind(this);
this.toggleSelected = this.toggleSelected.bind(this);
this.saveModal = this.saveModal.bind(this);
this.getData = this.getData.bind(this);

View File

@ -119,14 +119,18 @@ class Organization extends Component {
to="/organizations/:id/details"
exact
/>
<Route
path="/organizations/:id/edit"
render={() => (
<OrganizationEdit
match={match}
/>
)}
/>
{organization && (
<Route
path="/organizations/:id/edit"
render={() => (
<OrganizationEdit
api={api}
match={match}
organization={organization}
/>
)}
/>
)}
{organization && (
<Route
path="/organizations/:id/details"

View File

@ -1,17 +1,293 @@
import React from 'react';
import { Trans } from '@lingui/macro';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import { I18n, i18nMark } from '@lingui/react';
import { t } from '@lingui/macro';
import {
Link
} from 'react-router-dom';
import { CardBody } from '@patternfly/react-core';
CardBody,
Form,
FormGroup,
Gallery,
TextInput,
} from '@patternfly/react-core';
const OrganizationEdit = ({ match }) => (
<CardBody>
<h1><Trans>edit view</Trans></h1>
<Link to={`/organizations/${match.params.id}`}>
<Trans>save/cancel and go back to view</Trans>
</Link>
</CardBody>
);
import { ConfigContext } from '../../../../context';
import Lookup from '../../../../components/Lookup';
import FormActionGroup from '../../../../components/FormActionGroup';
import AnsibleSelect from '../../../../components/AnsibleSelect';
export default OrganizationEdit;
class OrganizationEdit extends Component {
constructor (props) {
super(props);
this.getInstanceGroups = this.getInstanceGroups.bind(this);
this.getRelatedInstanceGroups = this.getRelatedInstanceGroups.bind(this);
this.checkValidity = this.checkValidity.bind(this);
this.onFieldChange = this.onFieldChange.bind(this);
this.onLookupSave = this.onLookupSave.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.postInstanceGroups = this.postInstanceGroups.bind(this);
this.onCancel = this.onCancel.bind(this);
this.onSuccess = this.onSuccess.bind(this);
this.state = {
form: {
name: {
value: '',
isValid: true,
validation: {
required: true
},
helperTextInvalid: i18nMark('This field must not be blank')
},
description: {
value: ''
},
instanceGroups: {
value: null,
initialValue: null
},
custom_virtualenv: {
value: '',
defaultValue: '/venv/ansible/'
}
},
error: '',
formIsValid: true
};
}
async componentDidMount () {
const { organization } = this.props;
const { form: formData } = this.state;
formData.name.value = organization.name;
formData.description.value = organization.description;
formData.custom_virtualenv.value = organization.custom_virtualenv;
try {
formData.instanceGroups.value = await this.getRelatedInstanceGroups();
formData.instanceGroups.initialValue = [...formData.instanceGroups.value];
} catch (err) {
this.setState({ error: err });
}
this.setState({ form: formData });
}
onFieldChange (val, evt) {
const targetName = evt.target.name;
const value = val;
const { form: updatedForm } = this.state;
const updatedFormEl = { ...updatedForm[targetName] };
updatedFormEl.value = value;
updatedForm[targetName] = updatedFormEl;
let formIsValid = true;
if (updatedFormEl.validation) {
updatedFormEl.isValid = this.checkValidity(updatedFormEl.value, updatedFormEl.validation);
formIsValid = updatedFormEl.isValid && formIsValid;
}
this.setState({ form: updatedForm, formIsValid });
}
onLookupSave (val, targetName) {
const { form: updatedForm } = this.state;
updatedForm[targetName].value = val;
this.setState({ form: updatedForm });
}
async onSubmit () {
const { api, organization } = this.props;
const { form: { name, description, custom_virtualenv } } = this.state;
const formData = { name, description, custom_virtualenv };
const updatedData = {};
Object.keys(formData)
.forEach(formId => {
updatedData[formId] = formData[formId].value;
});
try {
await api.updateOrganizationDetails(organization.id, updatedData);
await this.postInstanceGroups();
} catch (err) {
this.setState({ error: err });
} finally {
this.onSuccess();
}
}
onCancel () {
const { organization: { id }, history } = this.props;
history.push(`/organizations/${id}`);
}
onSuccess () {
const { organization: { id }, history } = this.props;
history.push(`/organizations/${id}`);
}
async getInstanceGroups (params) {
const { api } = this.props;
const data = await api.getInstanceGroups(params);
return data;
}
async getRelatedInstanceGroups () {
const {
api,
organization: { id }
} = this.props;
const { data } = await api.getOrganizationInstanceGroups(id);
const { results } = data;
return results;
}
checkValidity = (value, validation) => {
let isValid = true;
if (validation.required) {
isValid = value.trim() !== '' && isValid;
}
return isValid;
}
async postInstanceGroups () {
const { api, organization } = this.props;
const { form: { instanceGroups } } = this.state;
const url = organization.related.instance_groups;
const initialInstanceGroups = instanceGroups.initialValue.map(ig => ig.id);
const updatedInstanceGroups = instanceGroups.value.map(ig => ig.id);
const groupsToAssociate = [...updatedInstanceGroups]
.filter(x => !initialInstanceGroups.includes(x));
const groupsToDisassociate = [...initialInstanceGroups]
.filter(x => !updatedInstanceGroups.includes(x));
try {
await Promise.all(groupsToAssociate.map(async id => {
await api.associateInstanceGroup(url, id);
}));
await Promise.all(groupsToDisassociate.map(async id => {
await api.disassociateInstanceGroup(url, id);
}));
} catch (err) {
this.setState({ error: err });
}
}
render () {
const {
form: {
name,
description,
instanceGroups,
custom_virtualenv
},
formIsValid,
error
} = this.state;
const instanceGroupsLookupColumns = [
{ name: i18nMark('Name'), key: 'name', isSortable: true },
{ name: i18nMark('Modified'), key: 'modified', isSortable: false, isNumeric: true },
{ name: i18nMark('Created'), key: 'created', isSortable: false, isNumeric: true }
];
return (
<CardBody>
<Form>
<I18n>
{({ i18n }) => (
<Gallery gutter="md">
<FormGroup
fieldId="edit-org-form-name"
helperTextInvalid={name.helperTextInvalid}
isRequired
isValid={name.isValid}
label={i18n._(t`Name`)}
>
<TextInput
id="edit-org-form-name"
isRequired
isValid={name.isValid}
name="name"
onChange={this.onFieldChange}
type="text"
value={name.value || ''}
/>
</FormGroup>
<FormGroup
fieldId="edit-org-form-description"
label={i18n._(t`Description`)}
>
<TextInput
id="edit-org-form-description"
name="description"
onChange={this.onFieldChange}
type="text"
value={description.value || ''}
/>
</FormGroup>
<FormGroup
fieldId="edit-org-form-instance-groups"
label={i18n._(t`Instance Groups`)}
>
{ instanceGroups.value
&& (
<Lookup
columns={instanceGroupsLookupColumns}
getItems={this.getInstanceGroups}
lookupHeader="Instance Groups"
name="instanceGroups"
onLookupSave={this.onLookupSave}
sortedColumnKey="name"
value={instanceGroups.value}
/>
)
}
</FormGroup>
<ConfigContext.Consumer>
{({ custom_virtualenvs }) => (
custom_virtualenvs && custom_virtualenvs.length > 1 && (
<FormGroup
fieldId="edit-org-custom-virtualenv"
label={i18n._(t`Ansible Environment`)}
>
<AnsibleSelect
data={custom_virtualenvs}
defaultSelected={custom_virtualenv.defaultEnv}
label={i18n._(t`Ansible Environment`)}
name="custom_virtualenv"
onChange={this.onFieldChange}
value={custom_virtualenv.value || ''}
/>
</FormGroup>
)
)}
</ConfigContext.Consumer>
</Gallery>
)}
</I18n>
<FormActionGroup
onCancel={this.onCancel}
onSubmit={this.onSubmit}
submitDisabled={!formIsValid}
/>
{ error ? <div>error</div> : '' }
</Form>
</CardBody>
);
}
}
OrganizationEdit.contextTypes = {
custom_virtualenvs: PropTypes.arrayOf(PropTypes.string)
};
export default withRouter(OrganizationEdit);