mirror of
https://github.com/ansible/awx.git
synced 2024-10-31 15:21:13 +03:00
Merge pull request #4251 from AlexSCorey/JTLaunchButton
Add Launch Button to Job Template Details Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
This commit is contained in:
commit
557ec27303
@ -1,9 +1,6 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { number } from 'prop-types';
|
||||
import { Button, Tooltip } from '@patternfly/react-core';
|
||||
import { RocketIcon } from '@patternfly/react-icons';
|
||||
import styled from 'styled-components';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { t } from '@lingui/macro';
|
||||
|
||||
@ -11,15 +8,6 @@ import AlertModal from '@components/AlertModal';
|
||||
import ErrorDetail from '@components/ErrorDetail';
|
||||
import { JobTemplatesAPI } from '@api';
|
||||
|
||||
const StyledLaunchButton = styled(Button)`
|
||||
padding: 5px 8px;
|
||||
|
||||
&:hover {
|
||||
background-color: #0066cc;
|
||||
color: white;
|
||||
}
|
||||
`;
|
||||
|
||||
class LaunchButton extends React.Component {
|
||||
static propTypes = {
|
||||
templateId: number.isRequired,
|
||||
@ -65,20 +53,10 @@ class LaunchButton extends React.Component {
|
||||
|
||||
render() {
|
||||
const { launchError, promptError } = this.state;
|
||||
const { i18n } = this.props;
|
||||
const { i18n, children } = this.props;
|
||||
return (
|
||||
<Fragment>
|
||||
<Tooltip content={i18n._(t`Launch Job`)} position="top">
|
||||
<div>
|
||||
<StyledLaunchButton
|
||||
variant="plain"
|
||||
aria-label={i18n._(t`Launch`)}
|
||||
onClick={this.handleLaunch}
|
||||
>
|
||||
<RocketIcon />
|
||||
</StyledLaunchButton>
|
||||
</div>
|
||||
</Tooltip>
|
||||
{children(this.handleLaunch)}
|
||||
<AlertModal
|
||||
isOpen={launchError}
|
||||
variant="danger"
|
||||
|
@ -13,9 +13,14 @@ describe('LaunchButton', () => {
|
||||
can_start_without_user_input: true,
|
||||
},
|
||||
});
|
||||
const children = handleLaunch => (
|
||||
<button type="submit" onClick={handleLaunch} />
|
||||
);
|
||||
|
||||
test('renders the expected content', () => {
|
||||
const wrapper = mountWithContexts(<LaunchButton templateId={1} />);
|
||||
const wrapper = mountWithContexts(
|
||||
<LaunchButton templateId={1}>{children}</LaunchButton>
|
||||
);
|
||||
expect(wrapper).toHaveLength(1);
|
||||
});
|
||||
test('redirects to details after successful launch', async done => {
|
||||
@ -27,15 +32,18 @@ describe('LaunchButton', () => {
|
||||
id: 9000,
|
||||
},
|
||||
});
|
||||
const wrapper = mountWithContexts(<LaunchButton templateId={1} />, {
|
||||
context: {
|
||||
router: { history },
|
||||
},
|
||||
});
|
||||
const launchButton = wrapper.find('LaunchButton__StyledLaunchButton');
|
||||
launchButton.simulate('click');
|
||||
await sleep(0);
|
||||
const wrapper = mountWithContexts(
|
||||
<LaunchButton templateId={1}>{children}</LaunchButton>,
|
||||
{
|
||||
context: {
|
||||
router: { history },
|
||||
},
|
||||
}
|
||||
);
|
||||
const button = wrapper.find('button');
|
||||
button.prop('onClick')();
|
||||
expect(JobTemplatesAPI.readLaunch).toHaveBeenCalledWith(1);
|
||||
await sleep(0);
|
||||
expect(JobTemplatesAPI.launch).toHaveBeenCalledWith(1);
|
||||
expect(history.push).toHaveBeenCalledWith('/jobs/9000/details');
|
||||
done();
|
||||
@ -53,9 +61,11 @@ describe('LaunchButton', () => {
|
||||
},
|
||||
})
|
||||
);
|
||||
const wrapper = mountWithContexts(<LaunchButton templateId={1} />);
|
||||
const launchButton = wrapper.find('LaunchButton__StyledLaunchButton');
|
||||
launchButton.simulate('click');
|
||||
const wrapper = mountWithContexts(
|
||||
<LaunchButton templateId={1}>{children}</LaunchButton>
|
||||
);
|
||||
const button = wrapper.find('button');
|
||||
button.prop('onClick')();
|
||||
await waitForElement(
|
||||
wrapper,
|
||||
'Modal.at-c-alertModal--danger',
|
||||
|
@ -13,6 +13,7 @@ import styled from 'styled-components';
|
||||
import { t } from '@lingui/macro';
|
||||
|
||||
import ContentError from '@components/ContentError';
|
||||
import LaunchButton from '@components/LaunchButton';
|
||||
import ContentLoading from '@components/ContentLoading';
|
||||
import { ChipGroup, Chip } from '@components/Chip';
|
||||
import { DetailList, Detail } from '@components/DetailList';
|
||||
@ -83,9 +84,11 @@ class JobTemplateDetail extends Component {
|
||||
verbosity,
|
||||
},
|
||||
hasTemplateLoading,
|
||||
template,
|
||||
i18n,
|
||||
match,
|
||||
} = this.props;
|
||||
const canLaunch = summary_fields.user_capabilities.start;
|
||||
const { instanceGroups, hasContentLoading, contentError } = this.state;
|
||||
const verbosityOptions = [
|
||||
{ verbosity: 0, details: i18n._(t`0 (Normal)`) },
|
||||
@ -286,14 +289,25 @@ class JobTemplateDetail extends Component {
|
||||
{i18n._(t`Edit`)}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
variant="secondary"
|
||||
component={Link}
|
||||
to="/templates"
|
||||
aria-label={i18n._(t`Launch`)}
|
||||
>
|
||||
{i18n._(t`Launch`)}
|
||||
</Button>
|
||||
{canLaunch && (
|
||||
<LaunchButton
|
||||
variant="secondary"
|
||||
component={Link}
|
||||
to="/templates"
|
||||
templateId={template.id}
|
||||
aria-label={i18n._(t`Launch`)}
|
||||
>
|
||||
{handleLaunch => (
|
||||
<Button
|
||||
variant="secondary"
|
||||
type="submit"
|
||||
onClick={handleLaunch}
|
||||
>
|
||||
{i18n._(t`Launch`)}
|
||||
</Button>
|
||||
)}
|
||||
</LaunchButton>
|
||||
)}
|
||||
<Button
|
||||
variant="secondary"
|
||||
component={Link}
|
||||
|
@ -5,16 +5,30 @@ import {
|
||||
DataListItemRow,
|
||||
DataListItemCells,
|
||||
DataListCheck,
|
||||
Tooltip,
|
||||
Button as PFButton,
|
||||
} from '@patternfly/react-core';
|
||||
import { t } from '@lingui/macro';
|
||||
import { withI18n } from '@lingui/react';
|
||||
import { RocketIcon } from '@patternfly/react-icons';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import DataListCell from '@components/DataListCell';
|
||||
import LaunchButton from '@components/LaunchButton';
|
||||
import VerticalSeparator from '@components/VerticalSeparator';
|
||||
import { toTitleCase } from '@util/strings';
|
||||
|
||||
const StyledButton = styled(PFButton)`
|
||||
padding: 5px 8px;
|
||||
border: none;
|
||||
&:hover {
|
||||
background-color: #0066cc;
|
||||
color: white;
|
||||
}
|
||||
`;
|
||||
class TemplateListItem extends Component {
|
||||
render() {
|
||||
const { template, isSelected, onSelect } = this.props;
|
||||
const { i18n, template, isSelected, onSelect } = this.props;
|
||||
const canLaunch = template.summary_fields.user_capabilities.start;
|
||||
|
||||
return (
|
||||
@ -44,7 +58,19 @@ class TemplateListItem extends Component {
|
||||
</DataListCell>,
|
||||
<DataListCell lastcolumn="true" key="launch">
|
||||
{canLaunch && template.type === 'job_template' && (
|
||||
<LaunchButton templateId={template.id} />
|
||||
<Tooltip content={i18n._(t`Launch`)} position="top">
|
||||
<LaunchButton
|
||||
component={Link}
|
||||
to="/templates"
|
||||
templateId={template.id}
|
||||
>
|
||||
{handleLaunch => (
|
||||
<StyledButton variant="plain" onClick={handleLaunch}>
|
||||
<RocketIcon />
|
||||
</StyledButton>
|
||||
)}
|
||||
</LaunchButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
</DataListCell>,
|
||||
]}
|
||||
@ -55,4 +81,4 @@ class TemplateListItem extends Component {
|
||||
}
|
||||
}
|
||||
export { TemplateListItem as _TemplateListItem };
|
||||
export default TemplateListItem;
|
||||
export default withI18n()(TemplateListItem);
|
||||
|
Loading…
Reference in New Issue
Block a user