foreman-tasks 2.0.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/js_tests.yml +27 -0
  3. data/.github/workflows/ruby_tests.yml +74 -0
  4. data/.rubocop.yml +12 -4
  5. data/.rubocop_todo.yml +32 -25
  6. data/Gemfile +5 -0
  7. data/app/controllers/foreman_tasks/api/tasks_controller.rb +31 -58
  8. data/app/controllers/foreman_tasks/concerns/parameters/triggering.rb +1 -1
  9. data/app/controllers/foreman_tasks/recurring_logics_controller.rb +7 -0
  10. data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +3 -3
  11. data/app/models/foreman_tasks/recurring_logic.rb +4 -4
  12. data/app/models/foreman_tasks/task.rb +11 -0
  13. data/app/models/foreman_tasks/task/dynflow_task.rb +27 -33
  14. data/app/models/foreman_tasks/task/status_explicator.rb +1 -1
  15. data/app/models/foreman_tasks/triggering.rb +1 -1
  16. data/app/models/setting/foreman_tasks.rb +1 -1
  17. data/app/views/foreman_tasks/api/tasks/index.json.rabl +2 -0
  18. data/app/views/foreman_tasks/recurring_logics/index.html.erb +3 -1
  19. data/config/routes.rb +2 -1
  20. data/db/migrate/20200517215015_rename_bookmarks_controller.rb +2 -2
  21. data/db/seeds.d/30-notification_blueprints.rb +7 -7
  22. data/db/seeds.d/61-foreman_tasks_bookmarks.rb +1 -1
  23. data/lib/foreman_tasks/cleaner.rb +4 -6
  24. data/lib/foreman_tasks/dynflow/configuration.rb +1 -1
  25. data/lib/foreman_tasks/dynflow/persistence.rb +4 -6
  26. data/lib/foreman_tasks/engine.rb +2 -2
  27. data/lib/foreman_tasks/version.rb +1 -1
  28. data/package.json +0 -1
  29. data/test/controllers/api/recurring_logics_controller_test.rb +1 -1
  30. data/test/controllers/api/tasks_controller_test.rb +7 -7
  31. data/test/controllers/tasks_controller_test.rb +6 -6
  32. data/test/core/unit/runner_test.rb +20 -20
  33. data/test/core/unit/task_launcher_test.rb +8 -8
  34. data/test/helpers/foreman_tasks/foreman_tasks_helper_test.rb +7 -7
  35. data/test/helpers/foreman_tasks/tasks_helper_test.rb +3 -3
  36. data/test/lib/actions/middleware/keep_current_request_id_test.rb +3 -3
  37. data/test/support/history_tasks_builder.rb +1 -1
  38. data/test/tasks/generate_task_actions_test.rb +1 -1
  39. data/test/unit/actions/action_with_sub_plans_test.rb +2 -2
  40. data/test/unit/actions/bulk_action_test.rb +6 -6
  41. data/test/unit/actions/proxy_action_test.rb +20 -20
  42. data/test/unit/actions/recurring_action_test.rb +30 -32
  43. data/test/unit/cleaner_test.rb +24 -24
  44. data/test/unit/dashboard_table_filter_test.rb +5 -5
  45. data/test/unit/otp_manager_test.rb +2 -2
  46. data/test/unit/proxy_selector_test.rb +9 -9
  47. data/test/unit/recurring_logic_test.rb +32 -38
  48. data/test/unit/remote_task_test.rb +2 -2
  49. data/test/unit/task_groups_test.rb +4 -4
  50. data/test/unit/task_test.rb +18 -18
  51. data/test/unit/triggering_test.rb +8 -8
  52. data/test/unit/troubleshooting_help_generator_test.rb +6 -6
  53. data/test/unit/ui_notifications_test.rb +11 -11
  54. data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +3 -3
  55. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +8 -157
  56. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskButtons.js +168 -0
  57. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +6 -7
  58. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskSkeleton.js +48 -0
  59. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +1 -1
  60. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +12 -70
  61. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskButtons.test.js +95 -0
  62. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +78 -225
  63. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskButtons.test.js.snap +212 -0
  64. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +8 -4
  65. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +87 -70
  66. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +48 -125
  67. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +3 -16
  68. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +55 -29
  69. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.fixtures.js +2 -2
  70. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +6 -0
  71. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +2 -18
  72. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +77 -27
  73. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +14 -101
  74. data/webpack/ForemanTasks/Components/TaskDetails/index.js +6 -3
  75. data/webpack/ForemanTasks/Components/common/urlHelpers.js +7 -0
  76. data/webpack/ForemanTasks/ForemanTasksReducers.js +0 -2
  77. data/webpack/__mocks__/foremanReact/common/helpers.js +2 -0
  78. data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +10 -0
  79. data/webpack/__mocks__/foremanReact/redux/API/index.js +10 -0
  80. data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware.js +5 -0
  81. metadata +17 -14
  82. data/.travis.yml +0 -7
  83. data/script/travis_run_js_tests.sh +0 -7
  84. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +0 -38
  85. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsReducer.test.js +0 -33
  86. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsReducer.test.js.snap +0 -26
  87. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/integration.test.js.snap +0 -122
  88. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +0 -72
  89. data/webpack/__mocks__/foremanReact/redux/API.js +0 -7
@@ -0,0 +1,212 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Task rendering render with minimal Props 1`] = `
4
+ <Col
5
+ bsClass="col"
6
+ componentClass="div"
7
+ xs={12}
8
+ >
9
+ <Button
10
+ active={false}
11
+ block={false}
12
+ bsClass="btn"
13
+ bsSize="small"
14
+ bsStyle="default"
15
+ className="reload-button"
16
+ disabled={false}
17
+ onClick={[MockFunction]}
18
+ >
19
+ <span
20
+ className="glyphicon glyphicon-refresh "
21
+ />
22
+ Start auto-reloading
23
+ </Button>
24
+ <Button
25
+ active={false}
26
+ block={false}
27
+ bsClass="btn"
28
+ bsSize="small"
29
+ bsStyle="default"
30
+ className="dynflow-button"
31
+ disabled={true}
32
+ href="/foreman_tasks/dynflow/"
33
+ rel="noopener noreferrer"
34
+ target="_blank"
35
+ >
36
+ <span
37
+ data-original-title="dynflow_enable_console Setting is off"
38
+ title="dynflow_enable_console Setting is off"
39
+ >
40
+ Dynflow console
41
+ </span>
42
+ </Button>
43
+ <Button
44
+ active={false}
45
+ block={false}
46
+ bsClass="btn"
47
+ bsSize="small"
48
+ bsStyle="default"
49
+ className="resume-button"
50
+ data-original-title="You do not have permission"
51
+ disabled={true}
52
+ onClick={[Function]}
53
+ title="You do not have permission"
54
+ >
55
+ Resume
56
+ </Button>
57
+ <Button
58
+ active={false}
59
+ block={false}
60
+ bsClass="btn"
61
+ bsSize="small"
62
+ bsStyle="default"
63
+ className="cancel-button"
64
+ data-original-title="You do not have permission"
65
+ disabled={true}
66
+ onClick={[Function]}
67
+ title="You do not have permission"
68
+ >
69
+ Cancel
70
+ </Button>
71
+ <Button
72
+ active={false}
73
+ block={false}
74
+ bsClass="btn"
75
+ bsSize="small"
76
+ bsStyle="default"
77
+ className="unlock-button"
78
+ data-original-title="You do not have permission"
79
+ disabled={true}
80
+ onClick={[MockFunction]}
81
+ title="You do not have permission"
82
+ >
83
+ Unlock
84
+ </Button>
85
+ <Button
86
+ active={false}
87
+ block={false}
88
+ bsClass="btn"
89
+ bsSize="small"
90
+ bsStyle="default"
91
+ className="force-unlock-button"
92
+ data-original-title="You do not have permission"
93
+ disabled={true}
94
+ onClick={[MockFunction]}
95
+ title="You do not have permission"
96
+ >
97
+ Force Unlock
98
+ </Button>
99
+ </Col>
100
+ `;
101
+
102
+ exports[`Task rendering render with some Props 1`] = `
103
+ <Col
104
+ bsClass="col"
105
+ componentClass="div"
106
+ xs={12}
107
+ >
108
+ <Button
109
+ active={false}
110
+ block={false}
111
+ bsClass="btn"
112
+ bsSize="small"
113
+ bsStyle="default"
114
+ className="reload-button"
115
+ disabled={false}
116
+ onClick={[MockFunction]}
117
+ >
118
+ <span
119
+ className="glyphicon glyphicon-refresh spin"
120
+ />
121
+ Stop auto-reloading
122
+ </Button>
123
+ <Button
124
+ active={false}
125
+ block={false}
126
+ bsClass="btn"
127
+ bsSize="small"
128
+ bsStyle="default"
129
+ className="dynflow-button"
130
+ disabled={false}
131
+ href="/foreman_tasks/dynflow/"
132
+ rel="noopener noreferrer"
133
+ target="_blank"
134
+ >
135
+ <span>
136
+ Dynflow console
137
+ </span>
138
+ </Button>
139
+ <Button
140
+ active={false}
141
+ block={false}
142
+ bsClass="btn"
143
+ bsSize="small"
144
+ bsStyle="default"
145
+ className="resume-button"
146
+ disabled={true}
147
+ onClick={[Function]}
148
+ >
149
+ Resume
150
+ </Button>
151
+ <Button
152
+ active={false}
153
+ block={false}
154
+ bsClass="btn"
155
+ bsSize="small"
156
+ bsStyle="default"
157
+ className="cancel-button"
158
+ disabled={true}
159
+ onClick={[Function]}
160
+ >
161
+ Cancel
162
+ </Button>
163
+ <Button
164
+ active={false}
165
+ block={false}
166
+ bsClass="btn"
167
+ bsSize="small"
168
+ bsStyle="default"
169
+ className="parent-button"
170
+ disabled={false}
171
+ href="/foreman_tasks/tasks/parent-id"
172
+ >
173
+ Parent task
174
+ </Button>
175
+ <Button
176
+ active={false}
177
+ block={false}
178
+ bsClass="btn"
179
+ bsSize="small"
180
+ bsStyle="default"
181
+ className="subtask-button"
182
+ disabled={false}
183
+ href="/foreman_tasks/tasks/test/sub_tasks"
184
+ >
185
+ Sub tasks
186
+ </Button>
187
+ <Button
188
+ active={false}
189
+ block={false}
190
+ bsClass="btn"
191
+ bsSize="small"
192
+ bsStyle="default"
193
+ className="unlock-button"
194
+ disabled={false}
195
+ onClick={[MockFunction]}
196
+ >
197
+ Unlock
198
+ </Button>
199
+ <Button
200
+ active={false}
201
+ block={false}
202
+ bsClass="btn"
203
+ bsSize="small"
204
+ bsStyle="default"
205
+ className="force-unlock-button"
206
+ disabled={false}
207
+ onClick={[MockFunction]}
208
+ >
209
+ Force Unlock
210
+ </Button>
211
+ </Col>
212
+ `;
@@ -290,10 +290,14 @@ exports[`TaskInfo rendering render with Props 1`] = `
290
290
  </b>
291
291
  </span>
292
292
  </p>
293
- <p>
294
- A paused task represents a process that has not finished properly. Any task in paused state can lead to potential inconsistency and needs to be resolved.
295
- The recommended approach is to investigate the error messages below and in 'errors' tab, address the primary cause of the issue and resume the task.
296
- </p>
293
+ <p
294
+ dangerouslySetInnerHTML={
295
+ Object {
296
+ "__html": "A paused task represents a process that has not finished properly. Any task in paused state can lead to potential inconsistency and needs to be resolved.
297
+ The recommended approach is to investigate the error messages below and in 'errors' tab, address the primary cause of the issue and resume the task.",
298
+ }
299
+ }
300
+ />
297
301
  </Col>
298
302
  </Row>
299
303
  </Grid>
@@ -1,104 +1,119 @@
1
- import React, { Component } from 'react';
1
+ import React, { useEffect } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { Tab, Tabs } from 'patternfly-react';
4
4
  import { translate as __ } from 'foremanReact/common/I18n';
5
+ import { STATUS } from 'foremanReact/constants';
6
+ import MessageBox from 'foremanReact/components/common/MessageBox';
5
7
  import Task from './Components/Task';
6
8
  import RunningSteps from './Components/RunningSteps';
7
9
  import Errors from './Components/Errors';
8
10
  import Locks from './Components/Locks';
9
11
  import Raw from './Components/Raw';
10
12
  import { getTaskID } from './TasksDetailsHelper';
13
+ import { TaskSkeleton } from './Components/TaskSkeleton';
11
14
 
12
15
  import './TaskDetails.scss';
13
16
 
14
- class TaskDetails extends Component {
15
- componentDidMount() {
16
- const { timeoutId, refetchTaskDetails, fetchTaskDetails } = this.props;
17
+ const TaskDetails = ({
18
+ executionPlan,
19
+ failedSteps,
20
+ runningSteps,
21
+ locks,
22
+ cancelStep,
23
+ taskReloadStart,
24
+ taskReloadStop,
25
+ APIerror,
26
+ ...props
27
+ }) => {
28
+ const id = getTaskID();
29
+ const { taskReload, status, isLoading } = props;
17
30
 
18
- fetchTaskDetails(getTaskID(), timeoutId, refetchTaskDetails);
19
- }
20
- componentWillUnmount() {
21
- this.props.taskReloadStop(this.props.timeoutId);
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);
31
+ useEffect(() => {
32
+ taskReloadStart(id);
33
+ return () => {
34
+ taskReloadStop();
35
+ };
36
+ }, [id, taskReloadStart, taskReloadStop]);
37
+
38
+ const taskProgressToggle = () => {
39
+ if (taskReload) {
40
+ taskReloadStop();
34
41
  } else {
35
- taskReloadStart(timeoutId, refetchTaskDetails, id, loading);
42
+ taskReloadStart(id);
36
43
  }
37
44
  };
38
45
 
39
- render() {
40
- const {
41
- externalId,
42
- startedAt,
43
- endedAt,
44
- label,
45
- input,
46
- output,
47
- executionPlan,
48
- failedSteps,
49
- runningSteps,
50
- locks,
51
- cancelStep,
52
- } = this.props;
53
- const id = getTaskID();
54
- const resumable = executionPlan ? executionPlan.state === 'paused' : false;
55
- const cancellable = executionPlan ? executionPlan.cancellable : false;
46
+ if (status === STATUS.ERROR) {
56
47
  return (
57
- <div className="task-details-react well">
58
- <Tabs defaultActiveKey={1} animation={false} id="task-details-tabs">
59
- <Tab eventKey={1} title={__('Task')}>
48
+ <MessageBox
49
+ key="task-details-error"
50
+ icontype="error-circle-o"
51
+ msg={__(`Could not receive data: ${APIerror && APIerror.message}`)}
52
+ />
53
+ );
54
+ }
55
+ const resumable = executionPlan ? executionPlan.state === 'paused' : false;
56
+ const cancellable = executionPlan ? executionPlan.cancellable : false;
57
+ return (
58
+ <div className="task-details-react well">
59
+ <Tabs defaultActiveKey={1} animation={false} id="task-details-tabs">
60
+ <Tab eventKey={1} title={__('Task')}>
61
+ {isLoading ? (
62
+ <TaskSkeleton />
63
+ ) : (
60
64
  <Task
61
65
  {...{
62
- ...this.props,
66
+ ...props,
63
67
  cancellable,
64
68
  resumable,
65
69
  id,
66
- taskProgressToggle: this.taskProgressToggle,
70
+ status,
71
+ taskProgressToggle,
72
+ taskReloadStart,
67
73
  }}
68
74
  />
69
- </Tab>
70
- <Tab eventKey={2} title={__('Running Steps')}>
71
- <RunningSteps
72
- runningSteps={runningSteps}
73
- id={id}
74
- cancelStep={cancelStep}
75
- taskReload={this.props.taskReload}
76
- taskProgressToggle={this.taskProgressToggle}
77
- />
78
- </Tab>
79
- <Tab eventKey={3} title={__('Errors')}>
80
- <Errors executionPlan={executionPlan} failedSteps={failedSteps} />
81
- </Tab>
82
- <Tab eventKey={4} title={__('Locks')}>
83
- <Locks locks={locks} />
84
- </Tab>
85
- <Tab eventKey={5} title={__('Raw')}>
86
- <Raw
87
- {...{ id, label, startedAt, endedAt, input, output, externalId }}
88
- />
89
- </Tab>
90
- </Tabs>
91
- </div>
92
- );
93
- }
94
- }
75
+ )}
76
+ </Tab>
77
+ <Tab eventKey={2} disabled={isLoading} title={__('Running Steps')}>
78
+ <RunningSteps
79
+ runningSteps={runningSteps}
80
+ id={id}
81
+ cancelStep={cancelStep}
82
+ taskReload={taskReload}
83
+ taskReloadStart={taskReloadStart}
84
+ />
85
+ </Tab>
86
+ <Tab eventKey={3} disabled={isLoading} title={__('Errors')}>
87
+ <Errors executionPlan={executionPlan} failedSteps={failedSteps} />
88
+ </Tab>
89
+ <Tab eventKey={4} disabled={isLoading} title={__('Locks')}>
90
+ <Locks locks={locks} />
91
+ </Tab>
92
+ <Tab eventKey={5} disabled={isLoading} title={__('Raw')}>
93
+ <Raw
94
+ id={id}
95
+ label={props.label}
96
+ startedAt={props.startedAt}
97
+ endedAt={props.endedAt}
98
+ input={props.input}
99
+ output={props.output}
100
+ externalId={props.externalId}
101
+ />
102
+ </Tab>
103
+ </Tabs>
104
+ </div>
105
+ );
106
+ };
95
107
 
96
108
  TaskDetails.propTypes = {
97
109
  label: PropTypes.string,
98
- fetchTaskDetails: PropTypes.func.isRequired,
99
110
  runningSteps: PropTypes.array,
100
111
  cancelStep: PropTypes.func.isRequired,
101
112
  taskReload: PropTypes.bool.isRequired,
113
+ status: PropTypes.oneOf(Object.keys(STATUS)),
114
+ APIerror: PropTypes.object,
115
+ taskReloadStop: PropTypes.func.isRequired,
116
+ taskReloadStart: PropTypes.func.isRequired,
102
117
  ...Task.propTypes,
103
118
  ...Errors.propTypes,
104
119
  ...Locks.propTypes,
@@ -107,6 +122,8 @@ TaskDetails.propTypes = {
107
122
  TaskDetails.defaultProps = {
108
123
  label: '',
109
124
  runningSteps: [],
125
+ APIerror: null,
126
+ status: STATUS.PENDING,
110
127
  ...Task.defaultProps,
111
128
  ...RunningSteps.defaultProps,
112
129
  ...Errors.defaultProps,
@@ -1,139 +1,62 @@
1
- import { API } from 'foremanReact/redux/API';
2
- import {
3
- showLoading,
4
- hideLoading,
5
- } from 'foremanReact/components/Layout/LayoutActions';
1
+ import { post, get } from 'foremanReact/redux/API';
6
2
  import { addToast } from 'foremanReact/redux/actions/toasts';
7
3
  import { translate as __ } from 'foremanReact/common/I18n';
8
4
  import {
9
- FOREMAN_TASK_DETAILS_FETCH_TASK_REQUEST,
10
- FOREMAN_TASK_DETAILS_FETCH_TASK_SUCCESS,
11
- FOREMAN_TASK_DETAILS_FETCH_TASK_FAILURE,
12
- FOREMAN_TASK_DETAILS_STOP_POLLING,
13
- FOREMAN_TASK_DETAILS_START_POLLING,
14
- TASK_STEP_CANCEL_REQUEST,
15
- TASK_STEP_CANCEL_FAILURE,
16
- TASK_STEP_CANCEL_SUCCESS,
17
- } from './TaskDetailsConstants';
5
+ withInterval,
6
+ stopInterval,
7
+ } from 'foremanReact/redux/middlewares/IntervalMiddleware';
8
+ import { foremanTasksApiPath, foremanTasksPath } from '../common/urlHelpers';
9
+ import { TASK_STEP_CANCEL, FOREMAN_TASK_DETAILS } from './TaskDetailsConstants';
18
10
  import {
19
11
  errorToastData,
20
12
  infoToastData,
21
13
  successToastData,
22
14
  } from '../common/ToastsHelpers';
23
15
 
24
- export const taskReloadStop = timeoutId => {
25
- if (timeoutId) {
26
- clearTimeout(timeoutId);
27
- }
28
- return {
29
- type: FOREMAN_TASK_DETAILS_STOP_POLLING,
30
- payload: { timeoutId },
31
- };
32
- };
33
-
34
- export const taskReloadStart = (
35
- timeoutId,
36
- refetchTaskDetails,
37
- id,
38
- loading = false
39
- ) => {
40
- if (!timeoutId) {
41
- timeoutId = setInterval(() => refetchTaskDetails(id, loading), 5000);
42
- }
43
- return {
44
- type: FOREMAN_TASK_DETAILS_START_POLLING,
45
- payload: { timeoutId },
46
- };
47
- };
48
-
49
- export const refetchTaskDetails = (id, loading) => dispatch => {
50
- if (!loading) {
51
- showLoading();
52
- dispatch(startRequest());
53
- reloadTasksDetails(id, dispatch);
54
- }
55
- };
56
-
57
- const reloadTasksDetails = async (id, dispatch) => {
58
- try {
59
- const { data } = await API.get(
60
- `/foreman_tasks/api/tasks/${id}/details?include_permissions`
61
- );
62
- dispatch(requestSuccess(data));
63
- } catch (error) {
64
- dispatch(requestFailure(error));
65
- document.location.reload();
66
- } finally {
67
- hideLoading();
68
- }
16
+ export const taskReloadStop = () => stopInterval(FOREMAN_TASK_DETAILS);
17
+
18
+ export const taskReloadStart = id => dispatch => {
19
+ dispatch(
20
+ withInterval(
21
+ get({
22
+ key: FOREMAN_TASK_DETAILS,
23
+ url: foremanTasksApiPath(`${id}/details?include_permissions`),
24
+ handleSuccess: ({ data }) => {
25
+ if (data.state === 'stopped') {
26
+ dispatch(stopInterval(FOREMAN_TASK_DETAILS));
27
+ }
28
+ },
29
+ handleError: () => {
30
+ dispatch(stopInterval(FOREMAN_TASK_DETAILS));
31
+ },
32
+ }),
33
+ 5000
34
+ )
35
+ );
69
36
  };
70
37
 
71
- export const fetchTaskDetails = (
72
- id,
73
- timeoutId,
74
- refetchTaskDetailsAction
75
- ) => async dispatch => {
76
- showLoading();
77
- dispatch(startRequest());
78
- await getTasksDetails(id, dispatch, timeoutId, refetchTaskDetailsAction);
79
- };
80
-
81
- const getTasksDetails = async (
82
- id,
83
- dispatch,
84
- timeoutId,
85
- refetchTaskDetailsAction
86
- ) => {
87
- try {
88
- const { data } = await API.get(
89
- `/foreman_tasks/api/tasks/${id}/details?include_permissions`
90
- );
91
- dispatch(requestSuccess(data));
92
- if (data.state !== 'stopped') {
93
- dispatch(taskReloadStart(timeoutId, refetchTaskDetailsAction, id));
94
- }
95
- } catch (error) {
96
- dispatch(requestFailure(error));
97
- } finally {
98
- hideLoading();
99
- }
100
- };
101
-
102
- const startRequest = () => ({
103
- type: FOREMAN_TASK_DETAILS_FETCH_TASK_REQUEST,
104
- });
105
-
106
- const requestSuccess = data => ({
107
- type: FOREMAN_TASK_DETAILS_FETCH_TASK_SUCCESS,
108
- payload: data,
109
- });
110
-
111
- const requestFailure = error => ({
112
- type: FOREMAN_TASK_DETAILS_FETCH_TASK_FAILURE,
113
- payload: error,
114
- });
115
-
116
38
  export const cancelStep = (taskId, stepId) => async dispatch => {
117
- dispatch({ type: TASK_STEP_CANCEL_REQUEST });
118
39
  dispatch(addToast(infoToastData(`${__('Trying to cancel step')} ${stepId}`)));
119
- try {
120
- await API.post(
121
- `/foreman_tasks/tasks/${taskId}/cancel_step?step_id=${stepId}`
122
- );
123
- dispatch({ type: TASK_STEP_CANCEL_SUCCESS });
124
- dispatch(addToast(successToastData(`${stepId} {__('Step Canceled')}`)));
125
- } catch (error) {
126
- dispatch({ type: TASK_STEP_CANCEL_FAILURE, payload: error });
127
- dispatch(
128
- addToast(
129
- errorToastData(
130
- `${__('Could not cancel step.')} ${__(
131
- 'Error:'
132
- )} ${stepId} ${error.response &&
133
- error.response.data &&
134
- error.response.data.error}`
135
- )
136
- )
137
- );
138
- }
40
+ dispatch(
41
+ post({
42
+ key: TASK_STEP_CANCEL,
43
+ url: foremanTasksPath(`${taskId}/cancel_step?step_id=${stepId}`),
44
+ handleSuccess: () => {
45
+ dispatch(addToast(successToastData(`${stepId} {__('Step Canceled')}`)));
46
+ },
47
+ handleError: error => {
48
+ dispatch(
49
+ addToast(
50
+ errorToastData(
51
+ `${__('Could not cancel step.')} ${__(
52
+ 'Error:'
53
+ )} ${stepId} ${error.response &&
54
+ error.response.data &&
55
+ error.response.data.error}`
56
+ )
57
+ )
58
+ );
59
+ },
60
+ })
61
+ );
139
62
  };