mirror of
https://github.com/ansible/awx.git
synced 2026-03-13 23:17:32 -02:30
Add Project Edit form and refactor how the form handles credentials
This commit is contained in:
@@ -1,10 +1,62 @@
|
||||
import React, { Component } from 'react';
|
||||
import { CardBody } from '@patternfly/react-core';
|
||||
import React, { useState } from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
import styled from 'styled-components';
|
||||
import {
|
||||
Card as _Card,
|
||||
CardBody,
|
||||
CardHeader,
|
||||
Tooltip,
|
||||
} from '@patternfly/react-core';
|
||||
import CardCloseButton from '@components/CardCloseButton';
|
||||
import ProjectForm from '../shared/ProjectForm';
|
||||
import { ProjectsAPI } from '@api';
|
||||
|
||||
class ProjectEdit extends Component {
|
||||
render() {
|
||||
return <CardBody>Coming soon :)</CardBody>;
|
||||
}
|
||||
const Card = styled(_Card)`
|
||||
--pf-c-card--child--PaddingLeft: 0;
|
||||
--pf-c-card--child--PaddingRight: 0;
|
||||
`;
|
||||
|
||||
function ProjectEdit({ project, history, i18n }) {
|
||||
const [formSubmitError, setFormSubmitError] = useState(null);
|
||||
|
||||
const handleSubmit = async values => {
|
||||
try {
|
||||
const {
|
||||
data: { id },
|
||||
} = await ProjectsAPI.update(project.id, values);
|
||||
history.push(`/projects/${id}/details`);
|
||||
} catch (error) {
|
||||
setFormSubmitError(error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
history.push(`/projects/${project.id}/details`);
|
||||
};
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader css="text-align: right">
|
||||
<Tooltip content={i18n._(t`Close`)} position="top">
|
||||
<CardCloseButton onClick={handleCancel} />
|
||||
</Tooltip>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<ProjectForm
|
||||
project={project}
|
||||
handleCancel={handleCancel}
|
||||
handleSubmit={handleSubmit}
|
||||
/>
|
||||
</CardBody>
|
||||
{formSubmitError ? (
|
||||
<div className="formSubmitError">formSubmitError</div>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default ProjectEdit;
|
||||
export default withI18n()(withRouter(ProjectEdit));
|
||||
|
||||
@@ -30,19 +30,19 @@ const ScmTypeFormRow = styled(FormRow)`
|
||||
padding: 24px;
|
||||
`;
|
||||
|
||||
function ProjectForm(props) {
|
||||
const { project, handleCancel, handleSubmit, i18n } = props;
|
||||
function ProjectForm({ project, ...props }) {
|
||||
const { i18n, handleCancel, handleSubmit } = props;
|
||||
const { summary_fields = {} } = project;
|
||||
const [contentError, setContentError] = useState(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [organization, setOrganization] = useState(null);
|
||||
const [organization, setOrganization] = useState(
|
||||
summary_fields.organization || null
|
||||
);
|
||||
const [scmSubFormState, setScmSubFormState] = useState(null);
|
||||
const [scmTypeOptions, setScmTypeOptions] = useState(null);
|
||||
const [scmCredential, setScmCredential] = useState({
|
||||
typeId: null,
|
||||
value: null,
|
||||
});
|
||||
const [insightsCredential, setInsightsCredential] = useState({
|
||||
typeId: null,
|
||||
value: null,
|
||||
const [credentials, setCredentials] = useState({
|
||||
scm: { typeId: null, value: null },
|
||||
insights: { typeId: null, value: null },
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -74,9 +74,32 @@ function ProjectForm(props) {
|
||||
ProjectsAPI.readOptions(),
|
||||
]);
|
||||
|
||||
setScmCredential({ typeId: scmCredentialType.id });
|
||||
setInsightsCredential({ typeId: insightsCredentialType.id });
|
||||
setScmTypeOptions(choices);
|
||||
|
||||
const { credential } = summary_fields;
|
||||
if (!credential) {
|
||||
setCredentials({
|
||||
scm: { typeId: scmCredentialType.id },
|
||||
insights: { typeId: insightsCredentialType.id },
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const { credential_type_id } = credential;
|
||||
setCredentials({
|
||||
scm: {
|
||||
typeId: scmCredentialType.id,
|
||||
value:
|
||||
credential_type_id === scmCredentialType.id ? credential : null,
|
||||
},
|
||||
insights: {
|
||||
typeId: insightsCredentialType.id,
|
||||
value:
|
||||
credential_type_id === insightsCredentialType.id
|
||||
? credential
|
||||
: null,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
setContentError(error);
|
||||
} finally {
|
||||
@@ -87,22 +110,50 @@ function ProjectForm(props) {
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
const resetScmTypeFields = form => {
|
||||
const scmFormFields = [
|
||||
'scm_url',
|
||||
'scm_branch',
|
||||
'scm_refspec',
|
||||
'credential',
|
||||
'scm_clean',
|
||||
'scm_delete_on_update',
|
||||
'scm_update_on_launch',
|
||||
'allow_override',
|
||||
'scm_update_cache_timeout',
|
||||
];
|
||||
const scmFormFields = {
|
||||
scm_url: '',
|
||||
scm_branch: '',
|
||||
scm_refspec: '',
|
||||
credential: '',
|
||||
scm_clean: false,
|
||||
scm_delete_on_update: false,
|
||||
scm_update_on_launch: false,
|
||||
allow_override: false,
|
||||
scm_update_cache_timeout: 0,
|
||||
};
|
||||
|
||||
scmFormFields.forEach(field => {
|
||||
form.setFieldValue(field, form.initialValues[field]);
|
||||
form.setFieldTouched(field, false);
|
||||
const saveSubFormState = form => {
|
||||
const updatedScmFormFields = { ...scmFormFields };
|
||||
|
||||
Object.keys(updatedScmFormFields).forEach(label => {
|
||||
updatedScmFormFields[label] = form.values[label];
|
||||
});
|
||||
|
||||
setScmSubFormState(updatedScmFormFields);
|
||||
};
|
||||
|
||||
const resetScmTypeFields = (value, form) => {
|
||||
if (form.values.scm_type === form.initialValues.scm_type) {
|
||||
saveSubFormState(form);
|
||||
}
|
||||
|
||||
Object.keys(scmFormFields).forEach(label => {
|
||||
if (value === form.initialValues.scm_type) {
|
||||
form.setFieldValue(label, scmSubFormState[label]);
|
||||
} else {
|
||||
form.setFieldValue(label, scmFormFields[label]);
|
||||
}
|
||||
form.setFieldTouched(label, false);
|
||||
});
|
||||
};
|
||||
|
||||
const handleCredentialSelection = (type, value) => {
|
||||
setCredentials({
|
||||
...credentials,
|
||||
[type]: {
|
||||
...credentials[type],
|
||||
value,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -213,7 +264,7 @@ function ProjectForm(props) {
|
||||
]}
|
||||
onChange={(event, value) => {
|
||||
form.setFieldValue('scm_type', value);
|
||||
resetScmTypeFields(form);
|
||||
resetScmTypeFields(value, form);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
@@ -226,29 +277,29 @@ function ProjectForm(props) {
|
||||
{
|
||||
git: (
|
||||
<GitSubForm
|
||||
setScmCredential={setScmCredential}
|
||||
scmCredential={scmCredential}
|
||||
credential={credentials.scm}
|
||||
onCredentialSelection={handleCredentialSelection}
|
||||
scmUpdateOnLaunch={formik.values.scm_update_on_launch}
|
||||
/>
|
||||
),
|
||||
hg: (
|
||||
<HgSubForm
|
||||
setScmCredential={setScmCredential}
|
||||
scmCredential={scmCredential}
|
||||
credential={credentials.scm}
|
||||
onCredentialSelection={handleCredentialSelection}
|
||||
scmUpdateOnLaunch={formik.values.scm_update_on_launch}
|
||||
/>
|
||||
),
|
||||
svn: (
|
||||
<SvnSubForm
|
||||
setScmCredential={setScmCredential}
|
||||
scmCredential={scmCredential}
|
||||
credential={credentials.scm}
|
||||
onCredentialSelection={handleCredentialSelection}
|
||||
scmUpdateOnLaunch={formik.values.scm_update_on_launch}
|
||||
/>
|
||||
),
|
||||
insights: (
|
||||
<InsightsSubForm
|
||||
setInsightsCredential={setInsightsCredential}
|
||||
insightsCredential={insightsCredential}
|
||||
credential={credentials.insights}
|
||||
onCredentialSelection={handleCredentialSelection}
|
||||
scmUpdateOnLaunch={formik.values.scm_update_on_launch}
|
||||
/>
|
||||
),
|
||||
|
||||
@@ -11,8 +11,8 @@ import {
|
||||
|
||||
const GitSubForm = ({
|
||||
i18n,
|
||||
scmCredential,
|
||||
setScmCredential,
|
||||
credential,
|
||||
onCredentialSelection,
|
||||
scmUpdateOnLaunch,
|
||||
}) => (
|
||||
<>
|
||||
@@ -74,8 +74,8 @@ const GitSubForm = ({
|
||||
}
|
||||
/>
|
||||
<ScmCredentialFormField
|
||||
setScmCredential={setScmCredential}
|
||||
scmCredential={scmCredential}
|
||||
credential={credential}
|
||||
onCredentialSelection={onCredentialSelection}
|
||||
/>
|
||||
<ScmTypeOptions scmUpdateOnLaunch={scmUpdateOnLaunch} />
|
||||
</>
|
||||
|
||||
@@ -10,8 +10,8 @@ import {
|
||||
|
||||
const HgSubForm = ({
|
||||
i18n,
|
||||
scmCredential,
|
||||
setScmCredential,
|
||||
credential,
|
||||
onCredentialSelection,
|
||||
scmUpdateOnLaunch,
|
||||
}) => (
|
||||
<>
|
||||
@@ -34,8 +34,8 @@ const HgSubForm = ({
|
||||
/>
|
||||
<BranchFormField i18n={i18n} label={i18n._(t`SCM Branch/Tag/Revision`)} />
|
||||
<ScmCredentialFormField
|
||||
setScmCredential={setScmCredential}
|
||||
scmCredential={scmCredential}
|
||||
credential={credential}
|
||||
onCredentialSelection={onCredentialSelection}
|
||||
/>
|
||||
<ScmTypeOptions scmUpdateOnLaunch={scmUpdateOnLaunch} />
|
||||
</>
|
||||
|
||||
@@ -8,8 +8,8 @@ import { ScmTypeOptions } from './SharedFields';
|
||||
|
||||
const InsightsSubForm = ({
|
||||
i18n,
|
||||
setInsightsCredential,
|
||||
insightsCredential,
|
||||
credential,
|
||||
onCredentialSelection,
|
||||
scmUpdateOnLaunch,
|
||||
}) => (
|
||||
<>
|
||||
@@ -18,19 +18,16 @@ const InsightsSubForm = ({
|
||||
validate={required(i18n._(t`Select a value for this field`), i18n)}
|
||||
render={({ form }) => (
|
||||
<CredentialLookup
|
||||
credentialTypeId={insightsCredential.typeId}
|
||||
credentialTypeId={credential.typeId}
|
||||
label={i18n._(t`Insights Credential`)}
|
||||
helperTextInvalid={form.errors.credential}
|
||||
isValid={!form.touched.credential || !form.errors.credential}
|
||||
onBlur={() => form.setFieldTouched('credential')}
|
||||
onChange={credential => {
|
||||
form.setFieldValue('credential', credential.id);
|
||||
setInsightsCredential({
|
||||
...insightsCredential,
|
||||
value: credential,
|
||||
});
|
||||
onChange={value => {
|
||||
onCredentialSelection('insights', value);
|
||||
form.setFieldValue('credential', value.id);
|
||||
}}
|
||||
value={insightsCredential.value}
|
||||
value={credential.value}
|
||||
required
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -41,20 +41,17 @@ export const BranchFormField = withI18n()(({ i18n, label }) => (
|
||||
));
|
||||
|
||||
export const ScmCredentialFormField = withI18n()(
|
||||
({ i18n, setScmCredential, scmCredential }) => (
|
||||
({ i18n, credential, onCredentialSelection }) => (
|
||||
<Field
|
||||
name="credential"
|
||||
render={({ form }) => (
|
||||
<CredentialLookup
|
||||
credentialTypeId={scmCredential.typeId}
|
||||
credentialTypeId={credential.typeId}
|
||||
label={i18n._(t`SCM Credential`)}
|
||||
value={scmCredential.value}
|
||||
onChange={credential => {
|
||||
form.setFieldValue('credential', credential.id);
|
||||
setScmCredential({
|
||||
...scmCredential,
|
||||
value: credential,
|
||||
});
|
||||
value={credential.value}
|
||||
onChange={value => {
|
||||
onCredentialSelection('scm', value);
|
||||
form.setFieldValue('credential', value.id);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -10,8 +10,8 @@ import {
|
||||
|
||||
const SvnSubForm = ({
|
||||
i18n,
|
||||
scmCredential,
|
||||
setScmCredential,
|
||||
credential,
|
||||
onCredentialSelection,
|
||||
scmUpdateOnLaunch,
|
||||
}) => (
|
||||
<>
|
||||
@@ -30,8 +30,8 @@ const SvnSubForm = ({
|
||||
/>
|
||||
<BranchFormField i18n={i18n} label={i18n._(t`Revision #`)} />
|
||||
<ScmCredentialFormField
|
||||
setScmCredential={setScmCredential}
|
||||
scmCredential={scmCredential}
|
||||
credential={credential}
|
||||
onCredentialSelection={onCredentialSelection}
|
||||
/>
|
||||
<ScmTypeOptions scmUpdateOnLaunch={scmUpdateOnLaunch} />
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user