foreman-tasks 2.0.3 → 3.0.4
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.
- checksums.yaml +4 -4
- data/.github/workflows/js_tests.yml +31 -0
- data/.github/workflows/ruby_tests.yml +74 -0
- data/.rubocop.yml +12 -4
- data/.rubocop_todo.yml +32 -25
- data/Gemfile +5 -0
- data/app/controllers/foreman_tasks/api/tasks_controller.rb +50 -63
- data/app/controllers/foreman_tasks/concerns/parameters/triggering.rb +1 -1
- data/app/controllers/foreman_tasks/recurring_logics_controller.rb +7 -0
- data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +3 -3
- data/app/models/foreman_tasks/recurring_logic.rb +1 -1
- data/app/models/foreman_tasks/task.rb +11 -0
- data/app/models/foreman_tasks/task/dynflow_task.rb +27 -33
- data/app/models/foreman_tasks/task/search.rb +1 -1
- data/app/models/foreman_tasks/task/status_explicator.rb +1 -1
- data/app/models/foreman_tasks/triggering.rb +1 -1
- data/app/models/setting/foreman_tasks.rb +9 -9
- data/app/services/foreman_tasks/dashboard_table_filter.rb +5 -1
- data/app/views/foreman_tasks/api/tasks/index.json.rabl +2 -0
- data/app/views/foreman_tasks/layouts/react.html.erb +1 -2
- data/app/views/foreman_tasks/recurring_logics/index.html.erb +3 -1
- data/app/views/foreman_tasks/tasks/dashboard/_latest_tasks_in_error_warning.html.erb +1 -1
- data/app/views/foreman_tasks/tasks/dashboard/_tasks_status.html.erb +1 -1
- data/app/views/foreman_tasks/tasks/show.html.erb +1 -6
- data/config/routes.rb +2 -1
- data/db/migrate/20200517215015_rename_bookmarks_controller.rb +2 -2
- data/db/seeds.d/30-notification_blueprints.rb +7 -7
- data/db/seeds.d/61-foreman_tasks_bookmarks.rb +1 -1
- data/foreman-tasks.gemspec +1 -0
- data/lib/foreman_tasks/cleaner.rb +4 -6
- data/lib/foreman_tasks/dynflow/configuration.rb +1 -1
- data/lib/foreman_tasks/dynflow/persistence.rb +4 -6
- data/lib/foreman_tasks/engine.rb +2 -2
- data/lib/foreman_tasks/version.rb +1 -1
- data/package.json +0 -1
- data/test/controllers/api/recurring_logics_controller_test.rb +1 -1
- data/test/controllers/api/tasks_controller_test.rb +17 -7
- data/test/controllers/tasks_controller_test.rb +6 -6
- data/test/core/unit/runner_test.rb +20 -20
- data/test/core/unit/task_launcher_test.rb +8 -8
- data/test/helpers/foreman_tasks/foreman_tasks_helper_test.rb +7 -7
- data/test/helpers/foreman_tasks/tasks_helper_test.rb +3 -3
- data/test/lib/actions/middleware/keep_current_request_id_test.rb +3 -3
- data/test/support/history_tasks_builder.rb +1 -1
- data/test/tasks/generate_task_actions_test.rb +1 -1
- data/test/unit/actions/action_with_sub_plans_test.rb +2 -2
- data/test/unit/actions/bulk_action_test.rb +6 -6
- data/test/unit/actions/proxy_action_test.rb +20 -20
- data/test/unit/actions/recurring_action_test.rb +30 -32
- data/test/unit/cleaner_test.rb +24 -24
- data/test/unit/dashboard_table_filter_test.rb +5 -5
- data/test/unit/otp_manager_test.rb +2 -2
- data/test/unit/proxy_selector_test.rb +9 -9
- data/test/unit/recurring_logic_test.rb +32 -32
- data/test/unit/remote_task_test.rb +2 -2
- data/test/unit/task_groups_test.rb +4 -4
- data/test/unit/task_test.rb +26 -18
- data/test/unit/triggering_test.rb +8 -8
- data/test/unit/troubleshooting_help_generator_test.rb +6 -6
- data/test/unit/ui_notifications_test.rb +11 -11
- data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +3 -3
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +8 -157
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskButtons.js +168 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +6 -7
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskSkeleton.js +48 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +1 -1
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +12 -70
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskButtons.test.js +95 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +78 -225
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskButtons.test.js.snap +212 -0
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +8 -4
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +87 -70
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +10 -0
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +48 -125
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +3 -16
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +55 -29
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.fixtures.js +2 -2
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +6 -0
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +2 -18
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +77 -27
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +14 -101
- data/webpack/ForemanTasks/Components/TaskDetails/index.js +6 -3
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.scss +4 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/OtherInfo.js +53 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/OtherInfo.test.js +14 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.js +27 -19
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.scss +14 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.test.js +1 -34
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/{StoppedTasksCardHelper.js → StoppedTasksCardTable.js} +28 -1
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCardTable.test.js +54 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/OtherInfo.test.js.snap +48 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCard.test.js.snap +60 -1367
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCardTable.test.js.snap +960 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/__snapshots__/TasksCardsGrid.test.js.snap +14 -11
- data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardConstants.js +2 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardSelectors.js +17 -11
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardSelectors.test.js +26 -14
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboard.test.js.snap +14 -11
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboardSelectors.test.js.snap +38 -22
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableHelpers.js +0 -8
- data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +13 -4
- data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.scss +0 -10
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +0 -2
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionNameCellFormatter.test.js.snap +3 -1
- data/webpack/ForemanTasks/Components/TasksTable/formatters/actionNameCellFormatter.js +6 -1
- data/webpack/ForemanTasks/Components/common/urlHelpers.js +7 -0
- data/webpack/ForemanTasks/ForemanTasksReducers.js +0 -2
- data/webpack/__mocks__/foremanReact/common/helpers.js +2 -0
- data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +10 -0
- data/webpack/__mocks__/foremanReact/redux/API/index.js +10 -0
- data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware.js +5 -0
- metadata +21 -13
- data/.travis.yml +0 -7
- data/app/assets/stylesheets/foreman_tasks/tasks.scss +0 -9
- data/script/travis_run_js_tests.sh +0 -7
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +0 -38
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsReducer.test.js +0 -33
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsReducer.test.js.snap +0 -26
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/integration.test.js.snap +0 -122
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +0 -72
- data/webpack/__mocks__/foremanReact/redux/API.js +0 -7
|
@@ -290,10 +290,14 @@ exports[`TaskInfo rendering render with Props 1`] = `
|
|
|
290
290
|
</b>
|
|
291
291
|
</span>
|
|
292
292
|
</p>
|
|
293
|
-
<p
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
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, {
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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(
|
|
42
|
+
taskReloadStart(id);
|
|
36
43
|
}
|
|
37
44
|
};
|
|
38
45
|
|
|
39
|
-
|
|
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
|
-
<
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
...
|
|
66
|
+
...props,
|
|
63
67
|
cancellable,
|
|
64
68
|
resumable,
|
|
65
69
|
id,
|
|
66
|
-
|
|
70
|
+
status,
|
|
71
|
+
taskProgressToggle,
|
|
72
|
+
taskReloadStart,
|
|
67
73
|
}}
|
|
68
74
|
/>
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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 {
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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 =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
};
|
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const FOREMAN_TASK_DETAILS = 'FOREMAN_TASK_DETAILS';
|
|
2
|
+
export const FOREMAN_TASK_DETAILS_SUCCESS = 'FOREMAN_TASK_DETAILS_SUCCESS';
|
|
2
3
|
|
|
3
|
-
export const
|
|
4
|
-
'FOREMAN_TASK_DETAILS_FETCH_TASK_REQUEST';
|
|
5
|
-
export const FOREMAN_TASK_DETAILS_FETCH_TASK_SUCCESS =
|
|
6
|
-
'FOREMAN_TASK_DETAILS_FETCH_TASK_SUCCESS';
|
|
7
|
-
export const FOREMAN_TASK_DETAILS_FETCH_TASK_FAILURE =
|
|
8
|
-
'FOREMAN_TASK_DETAILS_FETCH_TASK_FAILURE';
|
|
9
|
-
|
|
10
|
-
export const FOREMAN_TASK_DETAILS_STOP_POLLING =
|
|
11
|
-
'FOREMAN_TASK_DETAILS_STOP_POLLING';
|
|
12
|
-
export const FOREMAN_TASK_DETAILS_START_POLLING =
|
|
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';
|
|
4
|
+
export const TASK_STEP_CANCEL = 'TASK_STEP_CANCEL';
|
|
@@ -1,82 +1,108 @@
|
|
|
1
|
+
/* eslint-disable camelcase */
|
|
2
|
+
import {
|
|
3
|
+
selectAPIResponse,
|
|
4
|
+
selectAPIByKey,
|
|
5
|
+
} from 'foremanReact/redux/API/APISelectors';
|
|
6
|
+
import { selectDoesIntervalExist } from 'foremanReact/redux/middlewares/IntervalMiddleware/IntervalSelectors';
|
|
7
|
+
import { STATUS } from 'foremanReact/constants';
|
|
1
8
|
import { selectForemanTasks } from '../../ForemanTasksSelectors';
|
|
9
|
+
import { FOREMAN_TASK_DETAILS } from './TaskDetailsConstants';
|
|
2
10
|
|
|
3
11
|
export const selectTaskDetails = state =>
|
|
4
12
|
selectForemanTasks(state).taskDetails || {};
|
|
5
13
|
|
|
6
|
-
export const
|
|
14
|
+
export const selectTaskDetailsResponse = state =>
|
|
15
|
+
selectAPIResponse(state, FOREMAN_TASK_DETAILS);
|
|
16
|
+
|
|
17
|
+
export const selectStartAt = state =>
|
|
18
|
+
selectTaskDetailsResponse(state)?.start_at;
|
|
7
19
|
|
|
8
20
|
export const selectStartBefore = state =>
|
|
9
|
-
|
|
21
|
+
selectTaskDetailsResponse(state)?.start_before;
|
|
10
22
|
|
|
11
23
|
export const selectStartedAt = state =>
|
|
12
|
-
|
|
24
|
+
selectTaskDetailsResponse(state)?.started_at;
|
|
13
25
|
|
|
14
|
-
export const selectEndedAt = state =>
|
|
26
|
+
export const selectEndedAt = state =>
|
|
27
|
+
selectTaskDetailsResponse(state)?.ended_at;
|
|
15
28
|
|
|
16
|
-
export const selectInput = state =>
|
|
29
|
+
export const selectInput = state =>
|
|
30
|
+
selectTaskDetailsResponse(state).input || [];
|
|
17
31
|
|
|
18
|
-
export const selectOutput = state =>
|
|
32
|
+
export const selectOutput = state =>
|
|
33
|
+
selectTaskDetailsResponse(state).output || {};
|
|
19
34
|
|
|
20
35
|
export const selectResumable = state =>
|
|
21
|
-
|
|
36
|
+
selectTaskDetailsResponse(state).resumable || false;
|
|
22
37
|
|
|
23
38
|
export const selectCancellable = state =>
|
|
24
|
-
|
|
39
|
+
selectTaskDetailsResponse(state).cancellable || false;
|
|
25
40
|
|
|
26
41
|
export const selectErrors = state => {
|
|
27
|
-
const { humanized } =
|
|
42
|
+
const { humanized } = selectTaskDetailsResponse(state);
|
|
28
43
|
return humanized ? humanized.errors : [];
|
|
29
44
|
};
|
|
30
45
|
|
|
31
46
|
export const selectProgress = state =>
|
|
32
|
-
|
|
33
|
-
? Math.trunc(
|
|
47
|
+
selectTaskDetailsResponse(state).progress
|
|
48
|
+
? Math.trunc(selectTaskDetailsResponse(state).progress * 100)
|
|
34
49
|
: 0;
|
|
35
50
|
|
|
36
51
|
export const selectUsername = state =>
|
|
37
|
-
|
|
52
|
+
selectTaskDetailsResponse(state)?.username;
|
|
38
53
|
|
|
39
|
-
export const selectLabel = state =>
|
|
54
|
+
export const selectLabel = state => selectTaskDetailsResponse(state)?.label;
|
|
40
55
|
|
|
41
56
|
export const selectExecutionPlan = state =>
|
|
42
|
-
|
|
57
|
+
selectTaskDetailsResponse(state).execution_plan || {};
|
|
43
58
|
|
|
44
59
|
export const selectFailedSteps = state =>
|
|
45
|
-
|
|
60
|
+
selectTaskDetailsResponse(state).failed_steps || [];
|
|
46
61
|
|
|
47
62
|
export const selectRunningSteps = state =>
|
|
48
|
-
|
|
63
|
+
selectTaskDetailsResponse(state).running_steps || [];
|
|
49
64
|
|
|
50
|
-
export const selectHelp = state =>
|
|
65
|
+
export const selectHelp = state => selectTaskDetailsResponse(state)?.help;
|
|
51
66
|
|
|
52
67
|
export const selectHasSubTasks = state =>
|
|
53
|
-
|
|
68
|
+
selectTaskDetailsResponse(state).has_sub_tasks || false;
|
|
54
69
|
|
|
55
|
-
export const selectLocks = state =>
|
|
70
|
+
export const selectLocks = state =>
|
|
71
|
+
selectTaskDetailsResponse(state).locks || [];
|
|
56
72
|
|
|
57
73
|
export const selectUsernamePath = state =>
|
|
58
|
-
|
|
74
|
+
selectTaskDetailsResponse(state)?.username_path;
|
|
59
75
|
|
|
60
|
-
export const selectAction = state =>
|
|
76
|
+
export const selectAction = state =>
|
|
77
|
+
selectTaskDetailsResponse(state).action || '';
|
|
61
78
|
|
|
62
|
-
export const selectState = state =>
|
|
79
|
+
export const selectState = state => selectTaskDetailsResponse(state)?.state;
|
|
63
80
|
|
|
64
|
-
export const selectResult = state =>
|
|
81
|
+
export const selectResult = state => selectTaskDetailsResponse(state)?.result;
|
|
65
82
|
|
|
66
83
|
export const selectTimeoutId = state =>
|
|
67
|
-
|
|
84
|
+
selectTaskDetailsResponse(state)?.timeoutId;
|
|
68
85
|
|
|
69
86
|
export const selectTaskReload = state =>
|
|
70
|
-
|
|
87
|
+
!!selectDoesIntervalExist(state, FOREMAN_TASK_DETAILS);
|
|
71
88
|
|
|
72
89
|
export const selectParentTask = state =>
|
|
73
|
-
|
|
90
|
+
selectTaskDetailsResponse(state).parent_task_id || '';
|
|
74
91
|
|
|
75
92
|
export const selectExternalId = state =>
|
|
76
|
-
|
|
93
|
+
selectTaskDetailsResponse(state)?.external_id;
|
|
77
94
|
|
|
78
95
|
export const selectDynflowEnableConsole = state =>
|
|
79
|
-
|
|
96
|
+
selectTaskDetailsResponse(state).dynflow_enable_console || false;
|
|
80
97
|
|
|
81
98
|
export const selectCanEdit = state =>
|
|
82
|
-
|
|
99
|
+
selectTaskDetailsResponse(state).can_edit || false;
|
|
100
|
+
|
|
101
|
+
export const selectStatus = state => selectTaskDetailsResponse(state).status;
|
|
102
|
+
|
|
103
|
+
export const selectAPIError = state =>
|
|
104
|
+
selectTaskDetailsResponse(state)?.APIerror;
|
|
105
|
+
|
|
106
|
+
export const selectIsLoading = state =>
|
|
107
|
+
!!selectAPIByKey(state, FOREMAN_TASK_DETAILS).response &&
|
|
108
|
+
selectStatus(state) === STATUS.PENDING;
|