@@ -99,7 +99,7 @@ describe('Stats', () => { | |||
const result = shallow( | |||
<Stats onCancelAllPending={stub} onShowFailing={stub} pendingCount={0} /> | |||
); | |||
expect(result.find('.js-cancel-pending').length).toBe(0); | |||
expect(result.find('[data-test="cancel-pending"]').length).toBe(0); | |||
}); | |||
it('should show cancel pending button', () => { | |||
@@ -111,7 +111,7 @@ describe('Stats', () => { | |||
pendingCount={5} | |||
/> | |||
); | |||
expect(result.find('.js-cancel-pending').length).toBe(1); | |||
expect(result.find('[data-test="cancel-pending"]').length).toBe(1); | |||
}); | |||
it('should trigger cancelling pending', () => { | |||
@@ -125,7 +125,7 @@ describe('Stats', () => { | |||
/> | |||
); | |||
expect(spy).not.toBeCalled(); | |||
click(result.find('.js-cancel-pending')); | |||
result.find('[data-test="cancel-pending"]').prop<Function>('onConfirm')(); | |||
expect(spy).toBeCalled(); | |||
}); | |||
}); |
@@ -174,7 +174,7 @@ class BackgroundTasksApp extends React.PureComponent<Props, State> { | |||
handleCancelTask = (task: Task) => { | |||
this.setState({ loading: true }); | |||
cancelTaskAPI(task.id).then(nextTask => { | |||
return cancelTaskAPI(task.id).then(nextTask => { | |||
if (this.mounted) { | |||
this.setState(state => ({ | |||
tasks: updateTask(state.tasks, nextTask), | |||
@@ -196,7 +196,7 @@ class BackgroundTasksApp extends React.PureComponent<Props, State> { | |||
}); | |||
} | |||
handleCancelAllPending() { | |||
handleCancelAllPending = () => { | |||
this.setState({ loading: true }); | |||
cancelAllTasks().then(() => { | |||
@@ -204,7 +204,7 @@ class BackgroundTasksApp extends React.PureComponent<Props, State> { | |||
this.loadTasks(); | |||
} | |||
}, this.stopLoading); | |||
} | |||
}; | |||
render() { | |||
const { component } = this.props; |
@@ -21,6 +21,7 @@ import * as React from 'react'; | |||
import Tooltip from '../../../components/controls/Tooltip'; | |||
import { DeleteButton } from '../../../components/ui/buttons'; | |||
import { translate } from '../../../helpers/l10n'; | |||
import ConfirmButton from '../../../components/controls/ConfirmButton'; | |||
interface Props { | |||
component?: unknown; | |||
@@ -46,16 +47,28 @@ export default class Stats extends React.PureComponent<Props> { | |||
return ( | |||
<span> | |||
<span className="js-pending-count emphasised-measure">{this.props.pendingCount}</span> | |||
| |||
{translate('background_tasks.pending')} | |||
{this.props.isSystemAdmin && ( | |||
<Tooltip overlay={translate('background_tasks.cancel_all_tasks')}> | |||
<DeleteButton | |||
className="js-cancel-pending spacer-left" | |||
onClick={this.props.onCancelAllPending} | |||
/> | |||
</Tooltip> | |||
)} | |||
<span className="display-inline-flex-center little-spacer-left"> | |||
{translate('background_tasks.pending')} | |||
{this.props.isSystemAdmin && ( | |||
<ConfirmButton | |||
cancelButtonText={translate('close')} | |||
confirmButtonText={translate('background_tasks.cancel_all_tasks.submit')} | |||
data-test="cancel-pending" | |||
isDestructive={true} | |||
modalBody={translate('background_tasks.cancel_all_tasks.text')} | |||
modalHeader={translate('background_tasks.cancel_all_tasks')} | |||
onConfirm={this.props.onCancelAllPending}> | |||
{({ onClick }) => ( | |||
<Tooltip overlay={translate('background_tasks.cancel_all_tasks')}> | |||
<DeleteButton | |||
className="js-cancel-pending little-spacer-left" | |||
onClick={onClick} | |||
/> | |||
</Tooltip> | |||
)} | |||
</ConfirmButton> | |||
)} | |||
</span> | |||
</span> | |||
); | |||
} else { | |||
@@ -99,8 +112,7 @@ export default class Stats extends React.PureComponent<Props> { | |||
<Tooltip overlay={translate('background_tasks.failing_count')}> | |||
<span className="js-failures-count emphasised-measure">{this.props.failingCount}</span> | |||
</Tooltip> | |||
| |||
{translate('background_tasks.failures')} | |||
<span className="little-spacer-left">{translate('background_tasks.failures')}</span> | |||
</span> | |||
); | |||
} |
@@ -30,7 +30,7 @@ import { Task as TaskType } from '../../../app/types'; | |||
interface Props { | |||
component?: unknown; | |||
onCancelTask: (task: TaskType) => void; | |||
onCancelTask: (task: TaskType) => Promise<void>; | |||
onFilterTask: (task: TaskType) => void; | |||
task: TaskType; | |||
previousTask?: TaskType; |
@@ -25,6 +25,7 @@ import { translate, translateWithParameters } from '../../../helpers/l10n'; | |||
import ActionsDropdown, { ActionsDropdownItem } from '../../../components/controls/ActionsDropdown'; | |||
import { Task } from '../../../app/types'; | |||
import { lazyLoad } from '../../../components/lazyLoad'; | |||
import ConfirmModal from '../../../components/controls/ConfirmModal'; | |||
const AnalysisWarningsModal = lazyLoad( | |||
() => import('../../../components/common/AnalysisWarningsModal'), | |||
@@ -33,12 +34,13 @@ const AnalysisWarningsModal = lazyLoad( | |||
interface Props { | |||
component?: unknown; | |||
onCancelTask: (task: Task) => void; | |||
onCancelTask: (task: Task) => Promise<void>; | |||
onFilterTask: (task: Task) => void; | |||
task: Task; | |||
} | |||
interface State { | |||
cancelTaskOpen: boolean; | |||
scannerContextOpen: boolean; | |||
stacktraceOpen: boolean; | |||
warningsOpen: boolean; | |||
@@ -46,6 +48,7 @@ interface State { | |||
export default class TaskActions extends React.PureComponent<Props, State> { | |||
state: State = { | |||
cancelTaskOpen: false, | |||
scannerContextOpen: false, | |||
stacktraceOpen: false, | |||
warningsOpen: false | |||
@@ -55,14 +58,22 @@ export default class TaskActions extends React.PureComponent<Props, State> { | |||
this.props.onFilterTask(this.props.task); | |||
}; | |||
handleCancelTask = () => { | |||
return this.props.onCancelTask(this.props.task); | |||
}; | |||
handleCancelClick = () => { | |||
this.props.onCancelTask(this.props.task); | |||
this.setState({ cancelTaskOpen: true }); | |||
}; | |||
handleShowScannerContextClick = () => { | |||
this.setState({ scannerContextOpen: true }); | |||
}; | |||
closeCancelTask = () => { | |||
this.setState({ cancelTaskOpen: false }); | |||
}; | |||
closeScannerContext = () => { | |||
this.setState({ scannerContextOpen: false }); | |||
}; | |||
@@ -140,6 +151,18 @@ export default class TaskActions extends React.PureComponent<Props, State> { | |||
)} | |||
</ActionsDropdown> | |||
{this.state.cancelTaskOpen && ( | |||
<ConfirmModal | |||
cancelButtonText={translate('close')} | |||
confirmButtonText={translate('background_tasks.cancel_task')} | |||
header={translate('background_tasks.cancel_task')} | |||
isDestructive={true} | |||
onClose={this.closeCancelTask} | |||
onConfirm={this.handleCancelTask}> | |||
{translate('background_tasks.cancel_task.text')} | |||
</ConfirmModal> | |||
)} | |||
{this.state.scannerContextOpen && ( | |||
<ScannerContext onClose={this.closeScannerContext} task={task} /> | |||
)} |
@@ -27,7 +27,7 @@ interface Props { | |||
tasks: TaskType[]; | |||
component?: unknown; | |||
loading: boolean; | |||
onCancelTask: (task: TaskType) => void; | |||
onCancelTask: (task: TaskType) => Promise<void>; | |||
onFilterTask: (task: TaskType) => void; | |||
} | |||
@@ -25,6 +25,7 @@ export { ChildrenProps } from './ModalButton'; | |||
interface Props { | |||
children: (props: ChildrenProps) => React.ReactNode; | |||
cancelButtonText?: string; | |||
confirmButtonText: string; | |||
confirmData?: string; | |||
confirmDisable?: boolean; | |||
@@ -42,6 +43,7 @@ export default class ConfirmButton extends React.PureComponent<Props, State> { | |||
renderConfirmModal = ({ onClose }: ModalProps) => { | |||
return ( | |||
<ConfirmModal | |||
cancelButtonText={this.props.cancelButtonText} | |||
confirmButtonText={this.props.confirmButtonText} | |||
confirmData={this.props.confirmData} | |||
confirmDisable={this.props.confirmDisable} |
@@ -25,6 +25,7 @@ import { SubmitButton, ResetButtonLink } from '../ui/buttons'; | |||
interface Props<T> { | |||
children: React.ReactNode; | |||
cancelButtonText?: string; | |||
confirmButtonText: string; | |||
confirmData?: T; | |||
confirmDisable?: boolean; | |||
@@ -57,6 +58,7 @@ export default class ConfirmModal<T = string> extends React.PureComponent<Props< | |||
renderModalContent = ({ onCloseClick, onFormSubmit, submitting }: ChildrenProps) => { | |||
const { children, confirmButtonText, confirmDisable, header, isDestructive } = this.props; | |||
const { cancelButtonText = translate('cancel') } = this.props; | |||
return ( | |||
<form onSubmit={onFormSubmit}> | |||
<header className="modal-head"> | |||
@@ -72,7 +74,7 @@ export default class ConfirmModal<T = string> extends React.PureComponent<Props< | |||
{confirmButtonText} | |||
</SubmitButton> | |||
<ResetButtonLink disabled={submitting} onClick={onCloseClick}> | |||
{translate('cancel')} | |||
{cancelButtonText} | |||
</ResetButtonLink> | |||
</footer> | |||
</form> |
@@ -2315,7 +2315,10 @@ background_tasks.table.duration=Duration | |||
background_tasks.filter_by_component_x=Filter by Component "{0}" | |||
background_tasks.cancel_task=Cancel Task | |||
background_tasks.cancel_task.text=Are you sure you want to cancel this pending task? | |||
background_tasks.cancel_all_tasks=Cancel All Pending Tasks | |||
background_tasks.cancel_all_tasks.text=Are you sure you want to cancel all pending tasks? | |||
background_tasks.cancel_all_tasks.submit=Cancel All | |||
background_tasks.scanner_context=Scanner Context | |||
background_tasks.show_scanner_context=Show Scanner Context | |||
background_tasks.show_stacktrace=Show Error Details |