mirror of
https://github.com/ansible/awx.git
synced 2026-02-27 15:58:45 -03:30
Merge pull request #9278 from AlexSCorey/PreLingUI-Upgrade-3
Fixes final files in preparation for lingui upgrade Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { Fragment, useState } from 'react';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { withRouter } from 'react-router-dom';
|
||||||
import { number, shape } from 'prop-types';
|
import { number, shape } from 'prop-types';
|
||||||
import { withI18n } from '@lingui/react';
|
import { withI18n } from '@lingui/react';
|
||||||
@@ -32,40 +32,12 @@ function canLaunchWithoutPrompt(launchData) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class LaunchButton extends React.Component {
|
function LaunchButton({ resource, i18n, children, history }) {
|
||||||
static propTypes = {
|
const [showLaunchPrompt, setShowLaunchPrompt] = useState(false);
|
||||||
resource: shape({
|
const [launchConfig, setLaunchConfig] = useState(null);
|
||||||
id: number.isRequired,
|
const [surveyConfig, setSurveyConfig] = useState(null);
|
||||||
}).isRequired,
|
const [error, setError] = useState(null);
|
||||||
};
|
const handleLaunch = async () => {
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
showLaunchPrompt: false,
|
|
||||||
launchConfig: null,
|
|
||||||
launchError: false,
|
|
||||||
surveyConfig: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.handleLaunch = this.handleLaunch.bind(this);
|
|
||||||
this.launchWithParams = this.launchWithParams.bind(this);
|
|
||||||
this.handleRelaunch = this.handleRelaunch.bind(this);
|
|
||||||
this.handleLaunchErrorClose = this.handleLaunchErrorClose.bind(this);
|
|
||||||
this.handlePromptErrorClose = this.handlePromptErrorClose.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleLaunchErrorClose() {
|
|
||||||
this.setState({ launchError: null });
|
|
||||||
}
|
|
||||||
|
|
||||||
handlePromptErrorClose() {
|
|
||||||
this.setState({ showLaunchPrompt: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
async handleLaunch() {
|
|
||||||
const { resource } = this.props;
|
|
||||||
const readLaunch =
|
const readLaunch =
|
||||||
resource.type === 'workflow_job_template'
|
resource.type === 'workflow_job_template'
|
||||||
? WorkflowJobTemplatesAPI.readLaunch(resource.id)
|
? WorkflowJobTemplatesAPI.readLaunch(resource.id)
|
||||||
@@ -75,33 +47,27 @@ class LaunchButton extends React.Component {
|
|||||||
? WorkflowJobTemplatesAPI.readSurvey(resource.id)
|
? WorkflowJobTemplatesAPI.readSurvey(resource.id)
|
||||||
: JobTemplatesAPI.readSurvey(resource.id);
|
: JobTemplatesAPI.readSurvey(resource.id);
|
||||||
try {
|
try {
|
||||||
const { data: launchConfig } = await readLaunch;
|
const { data: launch } = await readLaunch;
|
||||||
|
setLaunchConfig(launch);
|
||||||
|
|
||||||
let surveyConfig = null;
|
if (launch.survey_enabled) {
|
||||||
|
|
||||||
if (launchConfig.survey_enabled) {
|
|
||||||
const { data } = await readSurvey;
|
const { data } = await readSurvey;
|
||||||
|
|
||||||
surveyConfig = data;
|
setSurveyConfig(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canLaunchWithoutPrompt(launchConfig)) {
|
if (canLaunchWithoutPrompt(launch)) {
|
||||||
this.launchWithParams({});
|
launchWithParams({});
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
setShowLaunchPrompt(true);
|
||||||
showLaunchPrompt: true,
|
|
||||||
launchConfig,
|
|
||||||
surveyConfig,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.setState({ launchError: err });
|
setError(err);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
async launchWithParams(params) {
|
const launchWithParams = async params => {
|
||||||
try {
|
try {
|
||||||
const { history, resource } = this.props;
|
|
||||||
let jobPromise;
|
let jobPromise;
|
||||||
|
|
||||||
if (resource.type === 'job_template') {
|
if (resource.type === 'job_template') {
|
||||||
@@ -117,13 +83,11 @@ class LaunchButton extends React.Component {
|
|||||||
const { data: job } = await jobPromise;
|
const { data: job } = await jobPromise;
|
||||||
history.push(`/jobs/${job.id}/output`);
|
history.push(`/jobs/${job.id}/output`);
|
||||||
} catch (launchError) {
|
} catch (launchError) {
|
||||||
this.setState({ launchError });
|
setError(launchError);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
async handleRelaunch() {
|
|
||||||
const { history, resource } = this.props;
|
|
||||||
|
|
||||||
|
const handleRelaunch = async () => {
|
||||||
let readRelaunch;
|
let readRelaunch;
|
||||||
let relaunch;
|
let relaunch;
|
||||||
|
|
||||||
@@ -145,6 +109,7 @@ class LaunchButton extends React.Component {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const { data: relaunchConfig } = await readRelaunch;
|
const { data: relaunchConfig } = await readRelaunch;
|
||||||
|
setLaunchConfig(relaunchConfig);
|
||||||
if (
|
if (
|
||||||
!relaunchConfig.passwords_needed_to_start ||
|
!relaunchConfig.passwords_needed_to_start ||
|
||||||
relaunchConfig.passwords_needed_to_start.length === 0
|
relaunchConfig.passwords_needed_to_start.length === 0
|
||||||
@@ -165,53 +130,47 @@ class LaunchButton extends React.Component {
|
|||||||
const { data: job } = await relaunch;
|
const { data: job } = await relaunch;
|
||||||
history.push(`/jobs/${job.id}/output`);
|
history.push(`/jobs/${job.id}/output`);
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
setShowLaunchPrompt(true);
|
||||||
showLaunchPrompt: true,
|
|
||||||
launchConfig: relaunchConfig,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.setState({ launchError: err });
|
setError(err);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
return (
|
||||||
const {
|
<Fragment>
|
||||||
launchError,
|
{children({
|
||||||
showLaunchPrompt,
|
handleLaunch,
|
||||||
launchConfig,
|
handleRelaunch,
|
||||||
surveyConfig,
|
})}
|
||||||
} = this.state;
|
{error && (
|
||||||
const { resource, i18n, children } = this.props;
|
<AlertModal
|
||||||
return (
|
isOpen={error}
|
||||||
<Fragment>
|
variant="error"
|
||||||
{children({
|
title={i18n._(t`Error!`)}
|
||||||
handleLaunch: this.handleLaunch,
|
onClose={() => setError(null)}
|
||||||
handleRelaunch: this.handleRelaunch,
|
>
|
||||||
})}
|
{i18n._(t`Failed to launch job.`)}
|
||||||
{launchError && (
|
<ErrorDetail error={error} />
|
||||||
<AlertModal
|
</AlertModal>
|
||||||
isOpen={launchError}
|
)}
|
||||||
variant="error"
|
{showLaunchPrompt && (
|
||||||
title={i18n._(t`Error!`)}
|
<LaunchPrompt
|
||||||
onClose={this.handleLaunchErrorClose}
|
launchConfig={launchConfig}
|
||||||
>
|
surveyConfig={surveyConfig}
|
||||||
{i18n._(t`Failed to launch job.`)}
|
resource={resource}
|
||||||
<ErrorDetail error={launchError} />
|
onLaunch={launchWithParams}
|
||||||
</AlertModal>
|
onCancel={() => setShowLaunchPrompt(false)}
|
||||||
)}
|
/>
|
||||||
{showLaunchPrompt && (
|
)}
|
||||||
<LaunchPrompt
|
</Fragment>
|
||||||
launchConfig={launchConfig}
|
);
|
||||||
surveyConfig={surveyConfig}
|
|
||||||
resource={resource}
|
|
||||||
onLaunch={this.launchWithParams}
|
|
||||||
onCancel={() => this.setState({ showLaunchPrompt: false })}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LaunchButton.propTypes = {
|
||||||
|
resource: shape({
|
||||||
|
id: number.isRequired,
|
||||||
|
}).isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
export default withI18n()(withRouter(LaunchButton));
|
export default withI18n()(withRouter(LaunchButton));
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { createMemoryHistory } from 'history';
|
import { createMemoryHistory } from 'history';
|
||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
|
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
|
||||||
import { sleep } from '../../../testUtils/testUtils';
|
import { sleep } from '../../../testUtils/testUtils';
|
||||||
|
|
||||||
@@ -69,7 +70,7 @@ describe('LaunchButton', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
const button = wrapper.find('button');
|
const button = wrapper.find('button');
|
||||||
button.prop('onClick')();
|
await act(() => button.prop('onClick')());
|
||||||
expect(JobTemplatesAPI.readLaunch).toHaveBeenCalledWith(1);
|
expect(JobTemplatesAPI.readLaunch).toHaveBeenCalledWith(1);
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
expect(JobTemplatesAPI.launch).toHaveBeenCalledWith(1, {});
|
expect(JobTemplatesAPI.launch).toHaveBeenCalledWith(1, {});
|
||||||
@@ -106,7 +107,7 @@ describe('LaunchButton', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
const button = wrapper.find('button');
|
const button = wrapper.find('button');
|
||||||
button.prop('onClick')();
|
await act(() => button.prop('onClick')());
|
||||||
expect(WorkflowJobTemplatesAPI.readLaunch).toHaveBeenCalledWith(1);
|
expect(WorkflowJobTemplatesAPI.readLaunch).toHaveBeenCalledWith(1);
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
expect(WorkflowJobTemplatesAPI.launch).toHaveBeenCalledWith(1, {});
|
expect(WorkflowJobTemplatesAPI.launch).toHaveBeenCalledWith(1, {});
|
||||||
@@ -143,7 +144,7 @@ describe('LaunchButton', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
const button = wrapper.find('button');
|
const button = wrapper.find('button');
|
||||||
button.prop('onClick')();
|
await act(() => button.prop('onClick')());
|
||||||
expect(JobsAPI.readRelaunch).toHaveBeenCalledWith(1);
|
expect(JobsAPI.readRelaunch).toHaveBeenCalledWith(1);
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
expect(JobsAPI.relaunch).toHaveBeenCalledWith(1);
|
expect(JobsAPI.relaunch).toHaveBeenCalledWith(1);
|
||||||
@@ -180,7 +181,7 @@ describe('LaunchButton', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
const button = wrapper.find('button');
|
const button = wrapper.find('button');
|
||||||
button.prop('onClick')();
|
await act(() => button.prop('onClick')());
|
||||||
expect(WorkflowJobsAPI.readRelaunch).toHaveBeenCalledWith(1);
|
expect(WorkflowJobsAPI.readRelaunch).toHaveBeenCalledWith(1);
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
expect(WorkflowJobsAPI.relaunch).toHaveBeenCalledWith(1);
|
expect(WorkflowJobsAPI.relaunch).toHaveBeenCalledWith(1);
|
||||||
@@ -218,7 +219,7 @@ describe('LaunchButton', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
const button = wrapper.find('button');
|
const button = wrapper.find('button');
|
||||||
button.prop('onClick')();
|
await act(() => button.prop('onClick')());
|
||||||
expect(ProjectsAPI.readLaunchUpdate).toHaveBeenCalledWith(5);
|
expect(ProjectsAPI.readLaunchUpdate).toHaveBeenCalledWith(5);
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
expect(ProjectsAPI.launchUpdate).toHaveBeenCalledWith(5);
|
expect(ProjectsAPI.launchUpdate).toHaveBeenCalledWith(5);
|
||||||
@@ -256,7 +257,7 @@ describe('LaunchButton', () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
const button = wrapper.find('button');
|
const button = wrapper.find('button');
|
||||||
button.prop('onClick')();
|
await act(() => button.prop('onClick')());
|
||||||
expect(InventorySourcesAPI.readLaunchUpdate).toHaveBeenCalledWith(5);
|
expect(InventorySourcesAPI.readLaunchUpdate).toHaveBeenCalledWith(5);
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
expect(InventorySourcesAPI.launchUpdate).toHaveBeenCalledWith(5);
|
expect(InventorySourcesAPI.launchUpdate).toHaveBeenCalledWith(5);
|
||||||
@@ -280,7 +281,7 @@ describe('LaunchButton', () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
expect(wrapper.find('Modal').length).toBe(0);
|
expect(wrapper.find('Modal').length).toBe(0);
|
||||||
wrapper.find('button').prop('onClick')();
|
await act(() => wrapper.find('button').prop('onClick')());
|
||||||
await sleep(0);
|
await sleep(0);
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
expect(wrapper.find('Modal').length).toBe(1);
|
expect(wrapper.find('Modal').length).toBe(1);
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ function Lookup(props) {
|
|||||||
</ChipGroup>
|
</ChipGroup>
|
||||||
</ChipHolder>
|
</ChipHolder>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
variant="large"
|
variant="large"
|
||||||
title={i18n._(t`Select ${header || i18n._(t`Items`)}`)}
|
title={i18n._(t`Select ${header || i18n._(t`Items`)}`)}
|
||||||
@@ -138,7 +139,12 @@ function Lookup(props) {
|
|||||||
>
|
>
|
||||||
{i18n._(t`Select`)}
|
{i18n._(t`Select`)}
|
||||||
</Button>,
|
</Button>,
|
||||||
<Button key="cancel" variant="link" onClick={closeModal}>
|
<Button
|
||||||
|
key="cancel"
|
||||||
|
variant="link"
|
||||||
|
onClick={closeModal}
|
||||||
|
aria-label={i18n._(t`Cancel lookup`)}
|
||||||
|
>
|
||||||
{i18n._(t`Cancel`)}
|
{i18n._(t`Cancel`)}
|
||||||
</Button>,
|
</Button>,
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { withRouter } from 'react-router-dom';
|
||||||
import { withI18n } from '@lingui/react';
|
import { I18n } from '@lingui/react';
|
||||||
import { t } from '@lingui/macro';
|
import { t } from '@lingui/macro';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import {
|
import {
|
||||||
@@ -578,7 +578,7 @@ class JobOutput extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { job, i18n } = this.props;
|
const { job } = this.props;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
contentError,
|
contentError,
|
||||||
@@ -666,64 +666,72 @@ class JobOutput extends Component {
|
|||||||
</CardBody>
|
</CardBody>
|
||||||
{showCancelPrompt &&
|
{showCancelPrompt &&
|
||||||
['pending', 'waiting', 'running'].includes(jobStatus) && (
|
['pending', 'waiting', 'running'].includes(jobStatus) && (
|
||||||
<AlertModal
|
<I18n>
|
||||||
isOpen={showCancelPrompt}
|
{({ i18n }) => (
|
||||||
variant="danger"
|
<AlertModal
|
||||||
onClose={this.handleCancelClose}
|
isOpen={showCancelPrompt}
|
||||||
title={i18n._(t`Cancel Job`)}
|
|
||||||
label={i18n._(t`Cancel Job`)}
|
|
||||||
actions={[
|
|
||||||
<Button
|
|
||||||
id="cancel-job-confirm-button"
|
|
||||||
key="delete"
|
|
||||||
variant="danger"
|
variant="danger"
|
||||||
isDisabled={cancelInProgress}
|
onClose={this.handleCancelClose}
|
||||||
aria-label={i18n._(t`Cancel job`)}
|
title={i18n._(t`Cancel Job`)}
|
||||||
onClick={this.handleCancelConfirm}
|
label={i18n._(t`Cancel Job`)}
|
||||||
|
actions={[
|
||||||
|
<Button
|
||||||
|
id="cancel-job-confirm-button"
|
||||||
|
key="delete"
|
||||||
|
variant="danger"
|
||||||
|
isDisabled={cancelInProgress}
|
||||||
|
aria-label={i18n._(t`Cancel job`)}
|
||||||
|
onClick={this.handleCancelConfirm}
|
||||||
|
>
|
||||||
|
{i18n._(t`Cancel job`)}
|
||||||
|
</Button>,
|
||||||
|
<Button
|
||||||
|
id="cancel-job-return-button"
|
||||||
|
key="cancel"
|
||||||
|
variant="secondary"
|
||||||
|
aria-label={i18n._(t`Return`)}
|
||||||
|
onClick={this.handleCancelClose}
|
||||||
|
>
|
||||||
|
{i18n._(t`Return`)}
|
||||||
|
</Button>,
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
{i18n._(t`Cancel job`)}
|
{i18n._(
|
||||||
</Button>,
|
t`Are you sure you want to submit the request to cancel this job?`
|
||||||
<Button
|
)}
|
||||||
id="cancel-job-return-button"
|
</AlertModal>
|
||||||
key="cancel"
|
|
||||||
variant="secondary"
|
|
||||||
aria-label={i18n._(t`Return`)}
|
|
||||||
onClick={this.handleCancelClose}
|
|
||||||
>
|
|
||||||
{i18n._(t`Return`)}
|
|
||||||
</Button>,
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
{i18n._(
|
|
||||||
t`Are you sure you want to submit the request to cancel this job?`
|
|
||||||
)}
|
)}
|
||||||
</AlertModal>
|
</I18n>
|
||||||
)}
|
)}
|
||||||
{cancelError && (
|
{cancelError && (
|
||||||
<>
|
<I18n>
|
||||||
<AlertModal
|
{({ i18n }) => (
|
||||||
isOpen={cancelError}
|
<AlertModal
|
||||||
variant="danger"
|
isOpen={cancelError}
|
||||||
onClose={() => this.setState({ cancelError: null })}
|
variant="danger"
|
||||||
title={i18n._(t`Job Cancel Error`)}
|
onClose={() => this.setState({ cancelError: null })}
|
||||||
label={i18n._(t`Job Cancel Error`)}
|
title={i18n._(t`Job Cancel Error`)}
|
||||||
>
|
label={i18n._(t`Job Cancel Error`)}
|
||||||
<ErrorDetail error={cancelError} />
|
>
|
||||||
</AlertModal>
|
<ErrorDetail error={cancelError} />
|
||||||
</>
|
</AlertModal>
|
||||||
|
)}
|
||||||
|
</I18n>
|
||||||
)}
|
)}
|
||||||
{deletionError && (
|
{deletionError && (
|
||||||
<>
|
<I18n>
|
||||||
<AlertModal
|
{({ i18n }) => (
|
||||||
isOpen={deletionError}
|
<AlertModal
|
||||||
variant="danger"
|
isOpen={deletionError}
|
||||||
onClose={() => this.setState({ deletionError: null })}
|
variant="danger"
|
||||||
title={i18n._(t`Job Delete Error`)}
|
onClose={() => this.setState({ deletionError: null })}
|
||||||
label={i18n._(t`Job Delete Error`)}
|
title={i18n._(t`Job Delete Error`)}
|
||||||
>
|
label={i18n._(t`Job Delete Error`)}
|
||||||
<ErrorDetail error={deletionError} />
|
>
|
||||||
</AlertModal>
|
<ErrorDetail error={deletionError} />
|
||||||
</>
|
</AlertModal>
|
||||||
|
)}
|
||||||
|
</I18n>
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
@@ -731,4 +739,4 @@ class JobOutput extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export { JobOutput as _JobOutput };
|
export { JobOutput as _JobOutput };
|
||||||
export default withI18n()(withRouter(JobOutput));
|
export default withRouter(JobOutput);
|
||||||
|
|||||||
Reference in New Issue
Block a user