diff --git a/awx/ui_next/src/components/JobList/JobListCancelButton.jsx b/awx/ui_next/src/components/JobList/JobListCancelButton.jsx
index 684d088c96..be70f47ae9 100644
--- a/awx/ui_next/src/components/JobList/JobListCancelButton.jsx
+++ b/awx/ui_next/src/components/JobList/JobListCancelButton.jsx
@@ -7,8 +7,15 @@ import { KebabifiedContext } from '../../contexts/Kebabified';
import AlertModal from '../AlertModal';
import { Job } from '../../types';
-function cannotCancel(job) {
- return !job.summary_fields.user_capabilities.start;
+function cannotCancelBecausePermissions(job) {
+ return (
+ !job.summary_fields.user_capabilities.start &&
+ ['pending', 'waiting', 'running'].includes(job.status)
+ );
+}
+
+function cannotCancelBecauseNotRunning(job) {
+ return !['pending', 'waiting', 'running'].includes(job.status);
}
function JobListCancelButton({ i18n, jobsToCancel, onCancel }) {
@@ -33,20 +40,40 @@ function JobListCancelButton({ i18n, jobsToCancel, onCancel }) {
}, [isKebabified, isModalOpen, onKebabModalChange]);
const renderTooltip = () => {
- const jobsUnableToCancel = jobsToCancel
- .filter(cannotCancel)
+ const cannotCancelPermissions = jobsToCancel
+ .filter(cannotCancelBecausePermissions)
.map(job => job.name);
- const numJobsUnableToCancel = jobsUnableToCancel.length;
+ const cannotCancelNotRunning = jobsToCancel
+ .filter(cannotCancelBecauseNotRunning)
+ .map(job => job.name);
+ const numJobsUnableToCancel = cannotCancelPermissions.concat(
+ cannotCancelNotRunning
+ ).length;
if (numJobsUnableToCancel > 0) {
return (
- {i18n._(
- '{numJobsUnableToCancel, plural, one {You do not have permission to cancel the following job:} other {You do not have permission to cancel the following jobs:}}',
- {
- numJobsUnableToCancel,
- }
+ {cannotCancelPermissions.length > 0 && (
+ <>
+ {i18n._(
+ '{numJobsUnableToCancel, plural, one {You do not have permission to cancel the following job:} other {You do not have permission to cancel the following jobs:}}',
+ {
+ numJobsUnableToCancel: cannotCancelPermissions.length,
+ }
+ )}
+ {' '.concat(cannotCancelPermissions.join(', '))}
+ >
+ )}
+ {cannotCancelNotRunning.length > 0 && (
+ <>
+ {i18n._(
+ '{numJobsUnableToCancel, plural, one {You cannot cancel the following job because it is not running:} other {You cannot cancel the following jobs because they are not running:}}',
+ {
+ numJobsUnableToCancel: cannotCancelNotRunning.length,
+ }
+ )}
+ {' '.concat(cannotCancelNotRunning.join(', '))}
+ >
)}
- {' '.concat(jobsUnableToCancel.join(', '))}
);
}
@@ -62,7 +89,9 @@ function JobListCancelButton({ i18n, jobsToCancel, onCancel }) {
};
const isDisabled =
- jobsToCancel.length === 0 || jobsToCancel.some(cannotCancel);
+ jobsToCancel.length === 0 ||
+ jobsToCancel.some(cannotCancelBecausePermissions) ||
+ jobsToCancel.some(cannotCancelBecauseNotRunning);
const cancelJobText = i18n._(
'{zeroOrOneJobSelected, plural, one {Cancel job} other {Cancel jobs}}',
diff --git a/awx/ui_next/src/components/JobList/JobListCancelButton.test.jsx b/awx/ui_next/src/components/JobList/JobListCancelButton.test.jsx
index 43bdbe1352..b38992fcf5 100644
--- a/awx/ui_next/src/components/JobList/JobListCancelButton.test.jsx
+++ b/awx/ui_next/src/components/JobList/JobListCancelButton.test.jsx
@@ -30,6 +30,29 @@ describe('', () => {
start: false,
},
},
+ status: 'running',
+ },
+ ]}
+ />
+ );
+ expect(wrapper.find('JobListCancelButton button').props().disabled).toBe(
+ true
+ );
+ });
+ test('should be disabled when selected job is not running', () => {
+ wrapper = mountWithContexts(
+
@@ -51,6 +74,7 @@ describe('', () => {
start: true,
},
},
+ status: 'running',
},
]}
/>
@@ -73,6 +97,7 @@ describe('', () => {
start: true,
},
},
+ status: 'running',
},
]}
onCancel={onCancel}