foreman-tasks 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/foreman_tasks/tasks_controller.rb +6 -3
  3. data/app/models/foreman_tasks/task/dynflow_task.rb +1 -0
  4. data/db/migrate/20200611090846_add_task_lock_index_on_resource_type_and_task_id.rb +9 -0
  5. data/lib/foreman_tasks/engine.rb +0 -5
  6. data/lib/foreman_tasks/version.rb +1 -1
  7. data/locale/en/LC_MESSAGES/foreman_tasks.mo +0 -0
  8. data/locale/en/foreman_tasks.po +50 -20
  9. data/locale/foreman_tasks.pot +173 -126
  10. data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
  11. data/locale/fr/foreman_tasks.po +817 -0
  12. data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
  13. data/locale/ja/foreman_tasks.po +817 -0
  14. data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
  15. data/locale/zh_CN/foreman_tasks.po +816 -0
  16. data/webpack/ForemanTasks/Components/TaskActions/TaskAction.test.js +2 -2
  17. data/webpack/ForemanTasks/Components/TaskActions/index.js +1 -1
  18. data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +17 -3
  19. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +3 -18
  20. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +8 -1
  21. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +5 -5
  22. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/RunningSteps.test.js.snap +1 -1
  23. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +4 -4
  24. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +35 -5
  25. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +36 -1
  26. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +4 -0
  27. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.fixtures.js +8 -0
  28. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +2 -1
  29. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +18 -2
  30. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +27 -6
  31. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +91 -0
  32. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +9 -4
  33. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardActions.js +1 -1
  34. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardActions.test.js +2 -2
  35. data/webpack/ForemanTasks/Components/TasksTable/TasksBulkActions.js +1 -1
  36. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksBulkActions.test.js +2 -2
  37. data/webpack/__mocks__/foremanReact/{API.js → redux/API.js} +1 -1
  38. metadata +12 -4
@@ -1,5 +1,5 @@
1
1
  import { testActionSnapshotWithFixtures } from '@theforeman/test';
2
- import API from 'foremanReact/API';
2
+ import { API } from 'foremanReact/redux/API';
3
3
  import {
4
4
  cancelTaskRequest,
5
5
  resumeTaskRequest,
@@ -11,7 +11,7 @@ jest.mock('foremanReact/components/common/table', () => ({
11
11
  getTableItemsAction: jest.fn(controller => controller),
12
12
  }));
13
13
 
14
- jest.mock('foremanReact/API');
14
+ jest.mock('foremanReact/redux/API');
15
15
 
16
16
  const task = ['some-id', 'some-name'];
17
17
 
@@ -1,5 +1,5 @@
1
1
  import { sprintf } from 'foremanReact/common/I18n';
2
- import API from 'foremanReact/API';
2
+ import { API } from 'foremanReact/redux/API';
3
3
  import { addToast } from 'foremanReact/redux/actions/toasts';
4
4
  import {
5
5
  TASKS_RESUME_REQUEST,
@@ -3,7 +3,13 @@ import PropTypes from 'prop-types';
3
3
  import { Alert, Button } from 'patternfly-react';
4
4
  import { translate as __ } from 'foremanReact/common/I18n';
5
5
 
6
- const RunningSteps = ({ runningSteps }) => {
6
+ const RunningSteps = ({
7
+ runningSteps,
8
+ id,
9
+ cancelStep,
10
+ taskReload,
11
+ taskProgressToggle,
12
+ }) => {
7
13
  if (!runningSteps.length) return <span>{__('No running steps')}</span>;
8
14
  return (
9
15
  <div>
@@ -13,8 +19,12 @@ const RunningSteps = ({ runningSteps }) => {
13
19
  <p>
14
20
  <Button
15
21
  bsSize="small"
16
- data-method="post"
17
- href={`/foreman_tasks/tasks/${step.id}/cancel_step`}
22
+ onClick={() => {
23
+ if (!taskReload) {
24
+ taskProgressToggle();
25
+ }
26
+ cancelStep(id, step.id);
27
+ }}
18
28
  >
19
29
  {__('Cancel')}
20
30
  </Button>
@@ -46,6 +56,10 @@ const RunningSteps = ({ runningSteps }) => {
46
56
 
47
57
  RunningSteps.propTypes = {
48
58
  runningSteps: PropTypes.array,
59
+ id: PropTypes.string.isRequired,
60
+ cancelStep: PropTypes.func.isRequired,
61
+ taskReload: PropTypes.bool.isRequired,
62
+ taskProgressToggle: PropTypes.func.isRequired,
49
63
  };
50
64
 
51
65
  RunningSteps.defaultProps = {
@@ -11,22 +11,6 @@ import {
11
11
  import { ForceUnlockModal, UnlockModal } from '../../TaskActions/UnlockModals';
12
12
 
13
13
  const Task = props => {
14
- const taskProgressToggle = () => {
15
- const {
16
- timeoutId,
17
- refetchTaskDetails,
18
- id,
19
- loading,
20
- taskReloadStop,
21
- taskReloadStart,
22
- } = props;
23
- if (timeoutId) {
24
- taskReloadStop(timeoutId);
25
- } else {
26
- taskReloadStart(timeoutId, refetchTaskDetails, id, loading);
27
- }
28
- };
29
-
30
14
  const unlockModalActions = useForemanModal({
31
15
  id: UNLOCK_MODAL,
32
16
  });
@@ -49,6 +33,7 @@ const Task = props => {
49
33
  unlockTaskRequest,
50
34
  action,
51
35
  dynflowEnableConsole,
36
+ taskProgressToggle,
52
37
  } = props;
53
38
  const forceUnlock = () => {
54
39
  if (!taskReload) {
@@ -86,6 +71,8 @@ const Task = props => {
86
71
  bsSize="small"
87
72
  href={`/foreman_tasks/dynflow/${externalId}`}
88
73
  disabled={!dynflowEnableConsole}
74
+ rel="noopener noreferrer"
75
+ target="_blank"
89
76
  >
90
77
  {__('Dynflow console')}
91
78
  </Button>
@@ -167,7 +154,6 @@ Task.propTypes = {
167
154
  parentTask: PropTypes.string,
168
155
  taskReload: PropTypes.bool,
169
156
  taskReloadStop: PropTypes.func,
170
- taskReloadStart: PropTypes.func,
171
157
  timeoutId: PropTypes.number,
172
158
  externalId: PropTypes.string,
173
159
  id: PropTypes.string.isRequired,
@@ -186,7 +172,6 @@ Task.defaultProps = {
186
172
  parentTask: '',
187
173
  taskReload: false,
188
174
  taskReloadStop: () => null,
189
- taskReloadStart: () => null,
190
175
  timeoutId: null,
191
176
  externalId: '',
192
177
  cancelTaskRequest: () => null,
@@ -2,9 +2,16 @@ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import RunningSteps from '../RunningSteps';
4
4
 
5
+ const minProps = {
6
+ id: 'task-id1',
7
+ taskReload: true,
8
+ cancelStep: jest.fn(),
9
+ taskProgressToggle: jest.fn(),
10
+ };
5
11
  const fixtures = {
6
- 'render without Props': {},
12
+ 'render with min Props': minProps,
7
13
  'render with Props': {
14
+ ...minProps,
8
15
  executionPlan: {
9
16
  state: 'paused',
10
17
  cancellable: false,
@@ -33,16 +33,16 @@ describe('Task', () => {
33
33
  }));
34
34
  const cancelTaskRequest = jest.fn();
35
35
  const resumeTaskRequest = jest.fn();
36
- const taskReloadStart = jest.fn();
36
+ const taskProgressToggle = jest.fn();
37
37
  const id = 'some-id';
38
38
  const action = 'some-action';
39
39
  const props = {
40
40
  taskReload: false,
41
- taskReloadStart,
42
41
  id,
43
42
  action,
44
43
  cancelTaskRequest,
45
44
  resumeTaskRequest,
45
+ taskProgressToggle,
46
46
  };
47
47
  afterEach(() => {
48
48
  jest.clearAllMocks();
@@ -51,20 +51,20 @@ describe('Task', () => {
51
51
  const component = mount(<Task {...props} />);
52
52
  const reloadButton = component.find('.reload-button').at(0);
53
53
  reloadButton.simulate('click');
54
- expect(taskReloadStart).toBeCalled();
54
+ expect(taskProgressToggle).toBeCalled();
55
55
  });
56
56
  it('resume', () => {
57
57
  const component = shallow(<Task {...props} />);
58
58
  const resumeButton = component.find('.resume-button').at(0);
59
59
  resumeButton.props().onClick();
60
- expect(taskReloadStart).toBeCalled();
60
+ expect(taskProgressToggle).toBeCalled();
61
61
  expect(resumeTaskRequest).toBeCalledWith(id, action);
62
62
  });
63
63
  it('cancel', () => {
64
64
  const component = shallow(<Task {...props} />);
65
65
  const cancelButton = component.find('.cancel-button').at(0);
66
66
  cancelButton.props().onClick();
67
- expect(taskReloadStart).toBeCalled();
67
+ expect(taskProgressToggle).toBeCalled();
68
68
  expect(cancelTaskRequest).toBeCalledWith(id, action);
69
69
  });
70
70
  it('unlock', () => {
@@ -55,7 +55,7 @@ exports[`RunningSteps rendering render with Props 1`] = `
55
55
  </div>
56
56
  `;
57
57
 
58
- exports[`RunningSteps rendering render without Props 1`] = `
58
+ exports[`RunningSteps rendering render with min Props 1`] = `
59
59
  <span>
60
60
  No running steps
61
61
  </span>
@@ -33,7 +33,6 @@ exports[`Task rendering render with some Props 1`] = `
33
33
  bsStyle="default"
34
34
  className="reload-button"
35
35
  disabled={false}
36
- onClick={[Function]}
37
36
  >
38
37
  <span
39
38
  className="glyphicon glyphicon-refresh spin"
@@ -49,6 +48,8 @@ exports[`Task rendering render with some Props 1`] = `
49
48
  className="dynflow-button"
50
49
  disabled={false}
51
50
  href="/foreman_tasks/dynflow/"
51
+ rel="noopener noreferrer"
52
+ target="_blank"
52
53
  >
53
54
  Dynflow console
54
55
  </Button>
@@ -149,7 +150,6 @@ exports[`Task rendering render with some Props 1`] = `
149
150
  startedAt=""
150
151
  state="paused"
151
152
  taskReload={true}
152
- taskReloadStart={[Function]}
153
153
  taskReloadStop={[Function]}
154
154
  timeoutId={null}
155
155
  username=""
@@ -192,7 +192,6 @@ exports[`Task rendering render without Props 1`] = `
192
192
  bsStyle="default"
193
193
  className="reload-button"
194
194
  disabled={false}
195
- onClick={[Function]}
196
195
  >
197
196
  <span
198
197
  className="glyphicon glyphicon-refresh "
@@ -208,6 +207,8 @@ exports[`Task rendering render without Props 1`] = `
208
207
  className="dynflow-button"
209
208
  disabled={true}
210
209
  href="/foreman_tasks/dynflow/"
210
+ rel="noopener noreferrer"
211
+ target="_blank"
211
212
  >
212
213
  Dynflow console
213
214
  </Button>
@@ -284,7 +285,6 @@ exports[`Task rendering render without Props 1`] = `
284
285
  startedAt=""
285
286
  state=""
286
287
  taskReload={false}
287
- taskReloadStart={[Function]}
288
288
  taskReloadStop={[Function]}
289
289
  timeoutId={null}
290
290
  username=""
@@ -20,6 +20,22 @@ class TaskDetails extends Component {
20
20
  componentWillUnmount() {
21
21
  this.props.taskReloadStop(this.props.timeoutId);
22
22
  }
23
+ taskProgressToggle = () => {
24
+ const {
25
+ timeoutId,
26
+ refetchTaskDetails,
27
+ id,
28
+ loading,
29
+ taskReloadStop,
30
+ taskReloadStart,
31
+ } = this.props;
32
+ if (timeoutId) {
33
+ taskReloadStop(timeoutId);
34
+ } else {
35
+ taskReloadStart(timeoutId, refetchTaskDetails, id, loading);
36
+ }
37
+ };
38
+
23
39
  render() {
24
40
  const {
25
41
  externalId,
@@ -32,6 +48,7 @@ class TaskDetails extends Component {
32
48
  failedSteps,
33
49
  runningSteps,
34
50
  locks,
51
+ cancelStep,
35
52
  } = this.props;
36
53
  const id = getTaskID();
37
54
  const resumable = executionPlan ? executionPlan.state === 'paused' : false;
@@ -40,12 +57,23 @@ class TaskDetails extends Component {
40
57
  <div className="task-details-react well">
41
58
  <Tabs defaultActiveKey={1} animation={false} id="task-details-tabs">
42
59
  <Tab eventKey={1} title={__('Task')}>
43
- <Task {...{ ...this.props, cancellable, resumable, id }} />
60
+ <Task
61
+ {...{
62
+ ...this.props,
63
+ cancellable,
64
+ resumable,
65
+ id,
66
+ taskProgressToggle: this.taskProgressToggle,
67
+ }}
68
+ />
44
69
  </Tab>
45
70
  <Tab eventKey={2} title={__('Running Steps')}>
46
71
  <RunningSteps
47
- executionPlan={executionPlan}
48
72
  runningSteps={runningSteps}
73
+ id={id}
74
+ cancelStep={cancelStep}
75
+ taskReload={this.props.taskReload}
76
+ taskProgressToggle={this.taskProgressToggle}
49
77
  />
50
78
  </Tab>
51
79
  <Tab eventKey={3} title={__('Errors')}>
@@ -67,16 +95,18 @@ class TaskDetails extends Component {
67
95
 
68
96
  TaskDetails.propTypes = {
69
97
  label: PropTypes.string,
70
- fetchTaskDetails: PropTypes.func,
98
+ fetchTaskDetails: PropTypes.func.isRequired,
99
+ runningSteps: PropTypes.array,
100
+ cancelStep: PropTypes.func.isRequired,
101
+ taskReload: PropTypes.bool.isRequired,
71
102
  ...Task.propTypes,
72
- ...RunningSteps.propTypes,
73
103
  ...Errors.propTypes,
74
104
  ...Locks.propTypes,
75
105
  ...Raw.propTypes,
76
106
  };
77
107
  TaskDetails.defaultProps = {
78
108
  label: '',
79
- fetchTaskDetails: () => null,
109
+ runningSteps: [],
80
110
  ...Task.defaultProps,
81
111
  ...RunningSteps.defaultProps,
82
112
  ...Errors.defaultProps,
@@ -1,15 +1,25 @@
1
- import API from 'foremanReact/API';
1
+ import { API } from 'foremanReact/redux/API';
2
2
  import {
3
3
  showLoading,
4
4
  hideLoading,
5
5
  } from 'foremanReact/components/Layout/LayoutActions';
6
+ import { addToast } from 'foremanReact/redux/actions/toasts';
7
+ import { translate as __ } from 'foremanReact/common/I18n';
6
8
  import {
7
9
  FOREMAN_TASK_DETAILS_FETCH_TASK_REQUEST,
8
10
  FOREMAN_TASK_DETAILS_FETCH_TASK_SUCCESS,
9
11
  FOREMAN_TASK_DETAILS_FETCH_TASK_FAILURE,
10
12
  FOREMAN_TASK_DETAILS_STOP_POLLING,
11
13
  FOREMAN_TASK_DETAILS_START_POLLING,
14
+ TASK_STEP_CANCEL_REQUEST,
15
+ TASK_STEP_CANCEL_FAILURE,
16
+ TASK_STEP_CANCEL_SUCCESS,
12
17
  } from './TaskDetailsConstants';
18
+ import {
19
+ errorToastData,
20
+ infoToastData,
21
+ successToastData,
22
+ } from '../common/ToastsHelpers';
13
23
 
14
24
  export const taskReloadStop = timeoutId => {
15
25
  if (timeoutId) {
@@ -98,3 +108,28 @@ const requestFailure = error => ({
98
108
  type: FOREMAN_TASK_DETAILS_FETCH_TASK_FAILURE,
99
109
  payload: error,
100
110
  });
111
+
112
+ export const cancelStep = (taskId, stepId) => async dispatch => {
113
+ dispatch({ type: TASK_STEP_CANCEL_REQUEST });
114
+ dispatch(addToast(infoToastData(`${__('Trying to cancel step')} ${stepId}`)));
115
+ try {
116
+ await API.post(
117
+ `/foreman_tasks/tasks/${taskId}/cancel_step?step_id=${stepId}`
118
+ );
119
+ dispatch({ type: TASK_STEP_CANCEL_SUCCESS });
120
+ dispatch(addToast(successToastData(`${stepId} {__('Step Canceled')}`)));
121
+ } catch (error) {
122
+ dispatch({ type: TASK_STEP_CANCEL_FAILURE, payload: error });
123
+ dispatch(
124
+ addToast(
125
+ errorToastData(
126
+ `${__('Could not cancel step.')} ${__(
127
+ 'Error:'
128
+ )} ${stepId} ${error.response &&
129
+ error.response.data &&
130
+ error.response.data.error}`
131
+ )
132
+ )
133
+ );
134
+ }
135
+ };
@@ -11,3 +11,7 @@ export const FOREMAN_TASK_DETAILS_STOP_POLLING =
11
11
  'FOREMAN_TASK_DETAILS_STOP_POLLING';
12
12
  export const FOREMAN_TASK_DETAILS_START_POLLING =
13
13
  'FOREMAN_TASK_DETAILS_START_POLLING';
14
+
15
+ export const TASK_STEP_CANCEL_REQUEST = 'TASK_STEP_CANCEL_REQUEST';
16
+ export const TASK_STEP_CANCEL_FAILURE = 'TASK_STEP_CANCEL_FAILURE';
17
+ export const TASK_STEP_CANCEL_SUCCESS = 'TASK_STEP_CANCEL_SUCCESS';
@@ -0,0 +1,8 @@
1
+ export const minProps = {
2
+ cancelStep: jest.fn(),
3
+ taskReloadStop: jest.fn(),
4
+ taskReloadStart: jest.fn(),
5
+ refetchTaskDetails: jest.fn(),
6
+ fetchTaskDetails: jest.fn(),
7
+ taskProgressToggle: jest.fn(),
8
+ };
@@ -1,9 +1,10 @@
1
1
  import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import TaskDetails from '../TaskDetails';
4
+ import { minProps } from './TaskDetails.fixtures';
4
5
 
5
6
  const fixtures = {
6
- 'render without Props': {},
7
+ 'render with min Props': minProps,
7
8
  };
8
9
 
9
10
  delete window.location;
@@ -1,19 +1,35 @@
1
1
  import { testActionSnapshotWithFixtures } from '@theforeman/test';
2
- import API from 'foremanReact/API';
2
+ import { API } from 'foremanReact/redux/API';
3
3
  import {
4
4
  taskReloadStop,
5
5
  taskReloadStart,
6
6
  fetchTaskDetails,
7
+ cancelStep,
7
8
  } from '../TaskDetailsActions';
8
9
 
9
- jest.mock('foremanReact/API');
10
+ jest.mock('foremanReact/redux/API');
10
11
 
11
12
  API.get.mockImplementation(async () => ({ data: 'some-data' }));
13
+ API.post.mockImplementation(async () => ({ data: 'some-data' }));
12
14
 
13
15
  const fixtures = {
14
16
  'should start reload': () => taskReloadStart(1),
15
17
  'should stop reload': () => taskReloadStop(2),
16
18
  'should fetch-task-details and success': () => fetchTaskDetails(),
19
+ 'should cancelStep and success': () => cancelStep('task-id', 'step-id'),
20
+
21
+ 'should fetch-task-details and fail': () => {
22
+ API.get.mockImplementationOnce(() =>
23
+ Promise.reject(new Error('Network Error'))
24
+ );
25
+ return fetchTaskDetails();
26
+ },
27
+ 'should cancelStep and fail': () => {
28
+ API.post.mockImplementationOnce(() =>
29
+ Promise.reject(new Error('Network Error'))
30
+ );
31
+ return cancelStep('task-id', 'step-id');
32
+ },
17
33
  };
18
34
 
19
35
  describe('TaskDetails - Actions', () =>
@@ -1,6 +1,6 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`TaskDetails rendering render without Props 1`] = `
3
+ exports[`TaskDetails rendering render with min Props 1`] = `
4
4
  <div
5
5
  className="task-details-react well"
6
6
  >
@@ -15,6 +15,7 @@ exports[`TaskDetails rendering render without Props 1`] = `
15
15
  >
16
16
  <Task
17
17
  action=""
18
+ cancelStep={[MockFunction]}
18
19
  cancelTaskRequest={[Function]}
19
20
  cancellable={false}
20
21
  dynflowEnableConsole={false}
@@ -23,7 +24,23 @@ exports[`TaskDetails rendering render without Props 1`] = `
23
24
  executionPlan={Object {}}
24
25
  externalId=""
25
26
  failedSteps={Array []}
26
- fetchTaskDetails={[Function]}
27
+ fetchTaskDetails={
28
+ [MockFunction] {
29
+ "calls": Array [
30
+ Array [
31
+ "a15dd820-32f1-4ced-9ab7-c0fab8234c47",
32
+ null,
33
+ [MockFunction],
34
+ ],
35
+ ],
36
+ "results": Array [
37
+ Object {
38
+ "type": "return",
39
+ "value": undefined,
40
+ },
41
+ ],
42
+ }
43
+ }
27
44
  hasSubTasks={false}
28
45
  help=""
29
46
  id="a15dd820-32f1-4ced-9ab7-c0fab8234c47"
@@ -33,7 +50,7 @@ exports[`TaskDetails rendering render without Props 1`] = `
33
50
  output={Object {}}
34
51
  parentTask=""
35
52
  progress={0}
36
- refetchTaskDetails={[Function]}
53
+ refetchTaskDetails={[MockFunction]}
37
54
  result="error"
38
55
  resumable={false}
39
56
  resumeTaskRequest={[Function]}
@@ -42,9 +59,10 @@ exports[`TaskDetails rendering render without Props 1`] = `
42
59
  startBefore=""
43
60
  startedAt=""
44
61
  state=""
62
+ taskProgressToggle={[Function]}
45
63
  taskReload={false}
46
- taskReloadStart={[Function]}
47
- taskReloadStop={[Function]}
64
+ taskReloadStart={[MockFunction]}
65
+ taskReloadStop={[MockFunction]}
48
66
  timeoutId={null}
49
67
  username=""
50
68
  usernamePath=""
@@ -55,8 +73,11 @@ exports[`TaskDetails rendering render without Props 1`] = `
55
73
  title="Running Steps"
56
74
  >
57
75
  <RunningSteps
58
- executionPlan={Object {}}
76
+ cancelStep={[MockFunction]}
77
+ id="a15dd820-32f1-4ced-9ab7-c0fab8234c47"
59
78
  runningSteps={Array []}
79
+ taskProgressToggle={[Function]}
80
+ taskReload={false}
60
81
  />
61
82
  </Tab>
62
83
  <Tab