Skip to content

Commit

Permalink
Add details page for Execution Environments (ansible#8172)
Browse files Browse the repository at this point in the history
* Add feature to Add/Edit Execution Environments

Add feature to Add/Edit Execution Environments.

Also, add key for `ExecutionEnvironmentsList`.

See: ansible#7887

* Add details page for execution environments

Add details page for execution environments

See: ansible#8171
  • Loading branch information
nixocio authored and jbradberry committed Sep 21, 2020
1 parent af6f441 commit 51669dc
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ function ExecutionEnvironment({ i18n, setBreadcrumb }) {
/>
</Route>
<Route path="/execution_environments/:id/details">
<ExecutionEnvironmentDetails />
<ExecutionEnvironmentDetails
executionEnvironment={executionEnvironment}
/>
</Route>
</>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,96 @@
import React from 'react';
import { Card, PageSection } from '@patternfly/react-core';
import React, { useCallback } from 'react';
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 (
<PageSection>
<Card>
<div>Execution environments details</div>
</Card>
</PageSection>
<CardBody>
<DetailList>
<Detail
label={i18n._(t`Image`)}
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);
Original file line number Diff line number Diff line change
@@ -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');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function ExecutionEnvironmentFormFields({ i18n }) {
<>
<FormField
id="execution-environment-image"
label={i18n._(t`Image`)}
label={i18n._(t`Image name`)}
name="image"
type="text"
validate={url(i18n)}
Expand All @@ -33,9 +33,9 @@ function ExecutionEnvironmentFormFields({ i18n }) {
type="text"
/>
<CredentialLookup
label={i18n._(t`Registry Credential`)}
label={i18n._(t`Registry credential`)}
onChange={value => credentialHelpers.setValue(value)}
value={credentialField.value || null}
value={credentialField.value}
/>
</>
);
Expand Down

0 comments on commit 51669dc

Please sign in to comment.