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}