mirror of
https://github.com/ansible/awx.git
synced 2026-05-15 13:27:40 -02:30
Add details page for Execution Environments (#8172)
* Add feature to Add/Edit Execution Environments Add feature to Add/Edit Execution Environments. Also, add key for `ExecutionEnvironmentsList`. See: https://github.com/ansible/awx/issues/7887 * Add details page for execution environments Add details page for execution environments See: https://github.com/ansible/awx/issues/8171
This commit is contained in:
@@ -110,7 +110,9 @@ function ExecutionEnvironment({ i18n, setBreadcrumb }) {
|
|||||||
/>
|
/>
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/execution_environments/:id/details">
|
<Route path="/execution_environments/:id/details">
|
||||||
<ExecutionEnvironmentDetails />
|
<ExecutionEnvironmentDetails
|
||||||
|
executionEnvironment={executionEnvironment}
|
||||||
|
/>
|
||||||
</Route>
|
</Route>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,14 +1,96 @@
|
|||||||
import React from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { Card, PageSection } from '@patternfly/react-core';
|
import { withI18n } from '@lingui/react';
|
||||||
|
import { t } from '@lingui/macro';
|
||||||
|
import { Link, useHistory } from 'react-router-dom';
|
||||||
|
import { Button, Label } from '@patternfly/react-core';
|
||||||
|
|
||||||
|
import AlertModal from '../../../components/AlertModal';
|
||||||
|
import { CardBody, CardActionsRow } from '../../../components/Card';
|
||||||
|
import DeleteButton from '../../../components/DeleteButton';
|
||||||
|
import {
|
||||||
|
Detail,
|
||||||
|
DetailList,
|
||||||
|
UserDateDetail,
|
||||||
|
} from '../../../components/DetailList';
|
||||||
|
import useRequest, { useDismissableError } from '../../../util/useRequest';
|
||||||
|
import { ExecutionEnvironmentsAPI } from '../../../api';
|
||||||
|
|
||||||
|
function ExecutionEnvironmentDetails({ executionEnvironment, i18n }) {
|
||||||
|
const history = useHistory();
|
||||||
|
const { id, image, description } = executionEnvironment;
|
||||||
|
|
||||||
|
const {
|
||||||
|
request: deleteExecutionEnvironment,
|
||||||
|
isLoading,
|
||||||
|
error: deleteError,
|
||||||
|
} = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
await ExecutionEnvironmentsAPI.destroy(id);
|
||||||
|
history.push(`/execution_environments`);
|
||||||
|
}, [id, history])
|
||||||
|
);
|
||||||
|
|
||||||
|
const { error, dismissError } = useDismissableError(deleteError);
|
||||||
|
|
||||||
function ExecutionEnvironmentDetails() {
|
|
||||||
return (
|
return (
|
||||||
<PageSection>
|
<CardBody>
|
||||||
<Card>
|
<DetailList>
|
||||||
<div>Execution environments details</div>
|
<Detail
|
||||||
</Card>
|
label={i18n._(t`Image`)}
|
||||||
</PageSection>
|
value={image}
|
||||||
|
dataCy="execution-environment-detail-image"
|
||||||
|
/>
|
||||||
|
<Detail label={i18n._(t`Description`)} value={description} />
|
||||||
|
{executionEnvironment.summary_fields.credential && (
|
||||||
|
<Detail
|
||||||
|
label={i18n._(t`Credential`)}
|
||||||
|
value={
|
||||||
|
<Label variant="outline" color="blue">
|
||||||
|
{executionEnvironment.summary_fields.credential.name}
|
||||||
|
</Label>
|
||||||
|
}
|
||||||
|
dataCy="execution-environment-credential"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<UserDateDetail
|
||||||
|
label={i18n._(t`Created`)}
|
||||||
|
date={executionEnvironment.created}
|
||||||
|
user={executionEnvironment.summary_fields.created_by}
|
||||||
|
/>
|
||||||
|
<UserDateDetail
|
||||||
|
label={i18n._(t`Last Modified`)}
|
||||||
|
date={executionEnvironment.modified}
|
||||||
|
user={executionEnvironment.summary_fields.modified_by}
|
||||||
|
/>
|
||||||
|
</DetailList>
|
||||||
|
<CardActionsRow>
|
||||||
|
<Button
|
||||||
|
aria-label={i18n._(t`edit`)}
|
||||||
|
component={Link}
|
||||||
|
to={`/execution_environments/${id}/edit`}
|
||||||
|
>
|
||||||
|
{i18n._(t`Edit`)}
|
||||||
|
</Button>
|
||||||
|
<DeleteButton
|
||||||
|
name={image}
|
||||||
|
modalTitle={i18n._(t`Delete Execution Environment`)}
|
||||||
|
onConfirm={deleteExecutionEnvironment}
|
||||||
|
isDisabled={isLoading}
|
||||||
|
>
|
||||||
|
{i18n._(t`Delete`)}
|
||||||
|
</DeleteButton>
|
||||||
|
</CardActionsRow>
|
||||||
|
|
||||||
|
{error && (
|
||||||
|
<AlertModal
|
||||||
|
isOpen={error}
|
||||||
|
onClose={dismissError}
|
||||||
|
title={i18n._(t`Error`)}
|
||||||
|
variant="error"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</CardBody>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ExecutionEnvironmentDetails;
|
export default withI18n()(ExecutionEnvironmentDetails);
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
|
import { createMemoryHistory } from 'history';
|
||||||
|
|
||||||
|
import { mountWithContexts } from '../../../../testUtils/enzymeHelpers';
|
||||||
|
import { ExecutionEnvironmentsAPI } from '../../../api';
|
||||||
|
|
||||||
|
import ExecutionEnvironmentDetails from './ExecutionEnvironmentDetails';
|
||||||
|
|
||||||
|
jest.mock('../../../api');
|
||||||
|
|
||||||
|
const executionEnvironment = {
|
||||||
|
id: 17,
|
||||||
|
type: 'execution_environment',
|
||||||
|
url: '/api/v2/execution_environments/17/',
|
||||||
|
related: {
|
||||||
|
created_by: '/api/v2/users/1/',
|
||||||
|
modified_by: '/api/v2/users/1/',
|
||||||
|
activity_stream: '/api/v2/execution_environments/17/activity_stream/',
|
||||||
|
unified_job_templates:
|
||||||
|
'/api/v2/execution_environments/17/unified_job_templates/',
|
||||||
|
credential: '/api/v2/credentials/4/',
|
||||||
|
},
|
||||||
|
summary_fields: {
|
||||||
|
credential: {
|
||||||
|
id: 4,
|
||||||
|
name: 'Container Registry',
|
||||||
|
},
|
||||||
|
created_by: {
|
||||||
|
id: 1,
|
||||||
|
username: 'admin',
|
||||||
|
first_name: '',
|
||||||
|
last_name: '',
|
||||||
|
},
|
||||||
|
modified_by: {
|
||||||
|
id: 1,
|
||||||
|
username: 'admin',
|
||||||
|
first_name: '',
|
||||||
|
last_name: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created: '2020-09-17T20:14:15.408782Z',
|
||||||
|
modified: '2020-09-17T20:14:15.408802Z',
|
||||||
|
description: 'Foo',
|
||||||
|
organization: null,
|
||||||
|
image: 'https://localhost:90/12345/ma',
|
||||||
|
managed_by_tower: false,
|
||||||
|
credential: 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('<ExecutionEnvironmentDetails/>', () => {
|
||||||
|
let wrapper;
|
||||||
|
test('should render details properly', async () => {
|
||||||
|
await act(async () => {
|
||||||
|
wrapper = mountWithContexts(
|
||||||
|
<ExecutionEnvironmentDetails
|
||||||
|
executionEnvironment={executionEnvironment}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
wrapper.update();
|
||||||
|
|
||||||
|
expect(wrapper.find('Detail[label="Image"]').prop('value')).toEqual(
|
||||||
|
executionEnvironment.image
|
||||||
|
);
|
||||||
|
expect(wrapper.find('Detail[label="Description"]').prop('value')).toEqual(
|
||||||
|
'Foo'
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
wrapper.find('Detail[label="Credential"]').prop('value').props.children
|
||||||
|
).toEqual(executionEnvironment.summary_fields.credential.name);
|
||||||
|
const dates = wrapper.find('UserDateDetail');
|
||||||
|
expect(dates).toHaveLength(2);
|
||||||
|
expect(dates.at(0).prop('date')).toEqual(executionEnvironment.created);
|
||||||
|
expect(dates.at(1).prop('date')).toEqual(executionEnvironment.modified);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('expected api call is made for delete', async () => {
|
||||||
|
const history = createMemoryHistory({
|
||||||
|
initialEntries: ['/execution_environments/42/details'],
|
||||||
|
});
|
||||||
|
await act(async () => {
|
||||||
|
wrapper = mountWithContexts(
|
||||||
|
<ExecutionEnvironmentDetails
|
||||||
|
executionEnvironment={executionEnvironment}
|
||||||
|
/>,
|
||||||
|
{
|
||||||
|
context: { router: { history } },
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
await act(async () => {
|
||||||
|
wrapper.find('DeleteButton').invoke('onConfirm')();
|
||||||
|
});
|
||||||
|
expect(ExecutionEnvironmentsAPI.destroy).toHaveBeenCalledTimes(1);
|
||||||
|
expect(history.location.pathname).toBe('/execution_environments');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -17,7 +17,7 @@ function ExecutionEnvironmentFormFields({ i18n }) {
|
|||||||
<>
|
<>
|
||||||
<FormField
|
<FormField
|
||||||
id="execution-environment-image"
|
id="execution-environment-image"
|
||||||
label={i18n._(t`Image`)}
|
label={i18n._(t`Image name`)}
|
||||||
name="image"
|
name="image"
|
||||||
type="text"
|
type="text"
|
||||||
validate={url(i18n)}
|
validate={url(i18n)}
|
||||||
@@ -33,9 +33,9 @@ function ExecutionEnvironmentFormFields({ i18n }) {
|
|||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
<CredentialLookup
|
<CredentialLookup
|
||||||
label={i18n._(t`Registry Credential`)}
|
label={i18n._(t`Registry credential`)}
|
||||||
onChange={value => credentialHelpers.setValue(value)}
|
onChange={value => credentialHelpers.setValue(value)}
|
||||||
value={credentialField.value || null}
|
value={credentialField.value}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user