mirror of
https://github.com/ansible/awx.git
synced 2026-01-11 10:00:01 -03:30
Merge pull request #9710 from nixocio/ui_issue_6663
Make Org a required field for org admins on WFJT Make Org a required field for org admins on WFJT. See: #6663 Reviewed-by: Alex Corey <Alex.swansboro@gmail.com> Reviewed-by: Tiago Góes <tiago.goes2009@gmail.com>
This commit is contained in:
commit
84ab88b073
@ -1,13 +1,22 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useCallback, useEffect } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import { Card, PageSection } from '@patternfly/react-core';
|
||||
import { CardBody } from '../../../components/Card';
|
||||
|
||||
import { WorkflowJobTemplatesAPI, OrganizationsAPI } from '../../../api';
|
||||
import {
|
||||
WorkflowJobTemplatesAPI,
|
||||
OrganizationsAPI,
|
||||
UsersAPI,
|
||||
} from '../../../api';
|
||||
import WorkflowJobTemplateForm from '../shared/WorkflowJobTemplateForm';
|
||||
import { useConfig } from '../../../contexts/Config';
|
||||
import useRequest from '../../../util/useRequest';
|
||||
import ContentError from '../../../components/ContentError';
|
||||
import ContentLoading from '../../../components/ContentLoading';
|
||||
|
||||
function WorkflowJobTemplateAdd() {
|
||||
const { me = {} } = useConfig();
|
||||
const history = useHistory();
|
||||
const [formSubmitError, setFormSubmitError] = useState(null);
|
||||
|
||||
@ -60,6 +69,33 @@ function WorkflowJobTemplateAdd() {
|
||||
history.push(`/templates`);
|
||||
};
|
||||
|
||||
const {
|
||||
isLoading,
|
||||
request: fetchUserRole,
|
||||
result: { orgAdminResults, isOrgAdmin },
|
||||
error: contentError,
|
||||
} = useRequest(
|
||||
useCallback(async () => {
|
||||
const {
|
||||
data: { results, count },
|
||||
} = await UsersAPI.readAdminOfOrganizations(me?.id);
|
||||
return { isOrgAdmin: count > 0, orgAdminResults: results };
|
||||
}, [me.id]),
|
||||
{ isOrgAdmin: false, orgAdminResults: null }
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
fetchUserRole();
|
||||
}, [fetchUserRole]);
|
||||
|
||||
if (contentError) {
|
||||
return <ContentError error={contentError} />;
|
||||
}
|
||||
|
||||
if (isLoading || !orgAdminResults) {
|
||||
return <ContentLoading />;
|
||||
}
|
||||
|
||||
return (
|
||||
<PageSection>
|
||||
<Card>
|
||||
@ -68,6 +104,7 @@ function WorkflowJobTemplateAdd() {
|
||||
handleCancel={handleCancel}
|
||||
handleSubmit={handleSubmit}
|
||||
submitError={formSubmitError}
|
||||
isOrgAdmin={isOrgAdmin}
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
||||
@ -7,8 +7,12 @@ import {
|
||||
OrganizationsAPI,
|
||||
LabelsAPI,
|
||||
ExecutionEnvironmentsAPI,
|
||||
UsersAPI,
|
||||
} from '../../../api';
|
||||
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
|
||||
import {
|
||||
mountWithContexts,
|
||||
waitForElement,
|
||||
} from '../../../../testUtils/enzymeHelpers';
|
||||
|
||||
import WorkflowJobTemplateAdd from './WorkflowJobTemplateAdd';
|
||||
|
||||
@ -17,6 +21,7 @@ jest.mock('../../../api/models/Organizations');
|
||||
jest.mock('../../../api/models/Labels');
|
||||
jest.mock('../../../api/models/Inventories');
|
||||
jest.mock('../../../api/models/ExecutionEnvironments');
|
||||
jest.mock('../../../api/models/Users');
|
||||
|
||||
describe('<WorkflowJobTemplateAdd/>', () => {
|
||||
let wrapper;
|
||||
@ -40,6 +45,10 @@ describe('<WorkflowJobTemplateAdd/>', () => {
|
||||
data: { results: [{ id: 1, name: 'Foo', image: 'localhost.com' }] },
|
||||
});
|
||||
|
||||
UsersAPI.readAdminOfOrganizations.mockResolvedValue({
|
||||
data: { count: 0, results: [] },
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
history = createMemoryHistory({
|
||||
initialEntries: ['/templates/workflow_job_template/add'],
|
||||
@ -67,6 +76,7 @@ describe('<WorkflowJobTemplateAdd/>', () => {
|
||||
}
|
||||
);
|
||||
});
|
||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||
});
|
||||
});
|
||||
afterEach(async () => {
|
||||
|
||||
@ -1,12 +1,21 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import { CardBody } from '../../../components/Card';
|
||||
import { getAddedAndRemoved } from '../../../util/lists';
|
||||
import { WorkflowJobTemplatesAPI, OrganizationsAPI } from '../../../api';
|
||||
import {
|
||||
WorkflowJobTemplatesAPI,
|
||||
OrganizationsAPI,
|
||||
UsersAPI,
|
||||
} from '../../../api';
|
||||
import { WorkflowJobTemplateForm } from '../shared';
|
||||
import { useConfig } from '../../../contexts/Config';
|
||||
import useRequest from '../../../util/useRequest';
|
||||
import ContentError from '../../../components/ContentError';
|
||||
import ContentLoading from '../../../components/ContentLoading';
|
||||
|
||||
function WorkflowJobTemplateEdit({ template }) {
|
||||
const { me = {} } = useConfig();
|
||||
const history = useHistory();
|
||||
const [formSubmitError, setFormSubmitError] = useState(null);
|
||||
|
||||
@ -69,6 +78,33 @@ function WorkflowJobTemplateEdit({ template }) {
|
||||
history.push(`/templates/workflow_job_template/${template.id}/details`);
|
||||
};
|
||||
|
||||
const {
|
||||
isLoading,
|
||||
request: fetchUserRole,
|
||||
result: { orgAdminResults, isOrgAdmin },
|
||||
error: contentError,
|
||||
} = useRequest(
|
||||
useCallback(async () => {
|
||||
const {
|
||||
data: { results, count },
|
||||
} = await UsersAPI.readAdminOfOrganizations(me?.id);
|
||||
return { isOrgAdmin: count > 0, orgAdminResults: results };
|
||||
}, [me.id]),
|
||||
{ isOrgAdmin: false, orgAdminResults: null }
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
fetchUserRole();
|
||||
}, [fetchUserRole]);
|
||||
|
||||
if (contentError) {
|
||||
return <ContentError error={contentError} />;
|
||||
}
|
||||
|
||||
if (isLoading || !orgAdminResults) {
|
||||
return <ContentLoading />;
|
||||
}
|
||||
|
||||
return (
|
||||
<CardBody>
|
||||
<WorkflowJobTemplateForm
|
||||
@ -76,6 +112,7 @@ function WorkflowJobTemplateEdit({ template }) {
|
||||
handleCancel={handleCancel}
|
||||
template={template}
|
||||
submitError={formSubmitError}
|
||||
isOrgAdmin={isOrgAdmin}
|
||||
/>
|
||||
</CardBody>
|
||||
);
|
||||
|
||||
@ -7,8 +7,12 @@ import {
|
||||
OrganizationsAPI,
|
||||
LabelsAPI,
|
||||
ExecutionEnvironmentsAPI,
|
||||
UsersAPI,
|
||||
} from '../../../api';
|
||||
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
|
||||
import {
|
||||
mountWithContexts,
|
||||
waitForElement,
|
||||
} from '../../../../testUtils/enzymeHelpers';
|
||||
import WorkflowJobTemplateEdit from './WorkflowJobTemplateEdit';
|
||||
|
||||
jest.mock('../../../api/models/WorkflowJobTemplates');
|
||||
@ -16,6 +20,7 @@ jest.mock('../../../api/models/Labels');
|
||||
jest.mock('../../../api/models/Organizations');
|
||||
jest.mock('../../../api/models/Inventories');
|
||||
jest.mock('../../../api/models/ExecutionEnvironments');
|
||||
jest.mock('../../../api/models/Users');
|
||||
|
||||
const mockTemplate = {
|
||||
id: 6,
|
||||
@ -74,6 +79,10 @@ describe('<WorkflowJobTemplateEdit/>', () => {
|
||||
},
|
||||
});
|
||||
|
||||
UsersAPI.readAdminOfOrganizations.mockResolvedValue({
|
||||
data: { count: 1, results: [{ id: 1 }] },
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
history = createMemoryHistory({
|
||||
initialEntries: ['/templates/workflow_job_template/6/edit'],
|
||||
@ -95,6 +104,7 @@ describe('<WorkflowJobTemplateEdit/>', () => {
|
||||
},
|
||||
}
|
||||
);
|
||||
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||
});
|
||||
});
|
||||
|
||||
@ -241,6 +251,7 @@ describe('<WorkflowJobTemplateEdit/>', () => {
|
||||
}
|
||||
);
|
||||
});
|
||||
await waitForElement(newWrapper, 'ContentLoading', el => el.length === 0);
|
||||
OrganizationsAPI.read.mockRejectedValue({
|
||||
response: {
|
||||
config: {
|
||||
|
||||
@ -43,6 +43,7 @@ function WorkflowJobTemplateForm({
|
||||
handleCancel,
|
||||
i18n,
|
||||
submitError,
|
||||
isOrgAdmin,
|
||||
}) {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
const [enableWebhooks, setEnableWebhooks] = useState(
|
||||
@ -55,7 +56,9 @@ function WorkflowJobTemplateForm({
|
||||
);
|
||||
const [labelsField, , labelsHelpers] = useField('labels');
|
||||
const [limitField, limitMeta, limitHelpers] = useField('limit');
|
||||
const [organizationField, organizationMeta] = useField('organization');
|
||||
const [organizationField, organizationMeta, organizationHelpers] = useField(
|
||||
'organization'
|
||||
);
|
||||
const [scmField, , scmHelpers] = useField('scm_branch');
|
||||
const [, webhookServiceMeta, webhookServiceHelpers] = useField(
|
||||
'webhook_service'
|
||||
@ -119,9 +122,14 @@ function WorkflowJobTemplateForm({
|
||||
/>
|
||||
<OrganizationLookup
|
||||
helperTextInvalid={organizationMeta.error}
|
||||
isValid={!organizationMeta.touched || !organizationMeta.error}
|
||||
onBlur={() => organizationHelpers.setTouched()}
|
||||
onChange={onOrganizationChange}
|
||||
value={organizationField.value}
|
||||
isValid={!organizationMeta.error}
|
||||
touched={organizationMeta.touched}
|
||||
error={organizationMeta.error}
|
||||
required={isOrgAdmin}
|
||||
autoPopulate={isOrgAdmin}
|
||||
/>
|
||||
<>
|
||||
<InventoryLookup
|
||||
@ -287,6 +295,7 @@ WorkflowJobTemplateForm.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
handleCancel: PropTypes.func.isRequired,
|
||||
submitError: shape({}),
|
||||
isOrgAdmin: PropTypes.bool,
|
||||
};
|
||||
|
||||
WorkflowJobTemplateForm.defaultProps = {
|
||||
@ -297,6 +306,7 @@ WorkflowJobTemplateForm.defaultProps = {
|
||||
inventory: undefined,
|
||||
project: undefined,
|
||||
},
|
||||
isOrgAdmin: false,
|
||||
};
|
||||
|
||||
const FormikApp = withFormik({
|
||||
|
||||
@ -124,6 +124,40 @@ describe('<WorkflowJobTemplateForm/>', () => {
|
||||
expect(wrapper.length).toBe(1);
|
||||
});
|
||||
|
||||
test('organization is a required field for organization admins', async () => {
|
||||
await act(async () => {
|
||||
wrapper = mountWithContexts(
|
||||
<Route
|
||||
path="/templates/workflow_job_template/:id/edit"
|
||||
component={() => (
|
||||
<WorkflowJobTemplateForm
|
||||
template={mockTemplate}
|
||||
handleCancel={handleCancel}
|
||||
handleSubmit={handleSubmit}
|
||||
isOrgAdmin
|
||||
/>
|
||||
)}
|
||||
/>,
|
||||
{
|
||||
context: {
|
||||
router: {
|
||||
history,
|
||||
route: {
|
||||
location: history.location,
|
||||
match: { params: { id: 6 } },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
wrapper.update();
|
||||
expect(
|
||||
wrapper.find('FormGroup[label="Organization"]').prop('isRequired')
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
test('all the fields render successfully', () => {
|
||||
const fields = [
|
||||
'FormField[name="name"]',
|
||||
@ -140,6 +174,9 @@ describe('<WorkflowJobTemplateForm/>', () => {
|
||||
expect(wrapper.find(`${field}`).length).toBe(1);
|
||||
};
|
||||
fields.map((field, index) => assertField(field, index));
|
||||
expect(
|
||||
wrapper.find('FormGroup[label="Organization"]').prop('isRequired')
|
||||
).toBeFalsy();
|
||||
});
|
||||
|
||||
test('changing inputs should update values', async () => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user