foreman-tasks 2.0.1 → 3.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/js_tests.yml +31 -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 +54 -63
  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/lib/actions/proxy_action.rb +1 -1
  12. data/app/models/foreman_tasks/recurring_logic.rb +4 -4
  13. data/app/models/foreman_tasks/task.rb +11 -0
  14. data/app/models/foreman_tasks/task/dynflow_task.rb +29 -34
  15. data/app/models/foreman_tasks/task/status_explicator.rb +1 -1
  16. data/app/models/foreman_tasks/triggering.rb +1 -1
  17. data/app/models/setting/foreman_tasks.rb +9 -9
  18. data/app/services/foreman_tasks/dashboard_table_filter.rb +5 -1
  19. data/app/views/foreman_tasks/api/tasks/index.json.rabl +2 -0
  20. data/app/views/foreman_tasks/api/tasks/show.json.rabl +2 -0
  21. data/app/views/foreman_tasks/layouts/react.html.erb +1 -2
  22. data/app/views/foreman_tasks/recurring_logics/index.html.erb +3 -1
  23. data/app/views/foreman_tasks/tasks/dashboard/_latest_tasks_in_error_warning.html.erb +1 -1
  24. data/app/views/foreman_tasks/tasks/dashboard/_tasks_status.html.erb +1 -1
  25. data/app/views/foreman_tasks/tasks/show.html.erb +1 -6
  26. data/config/routes.rb +2 -1
  27. data/db/migrate/20200517215015_rename_bookmarks_controller.rb +2 -2
  28. data/db/migrate/20200611090846_add_task_lock_index_on_resource_type_and_task_id.rb +3 -3
  29. data/db/seeds.d/30-notification_blueprints.rb +7 -7
  30. data/db/seeds.d/61-foreman_tasks_bookmarks.rb +1 -1
  31. data/foreman-tasks.gemspec +1 -0
  32. data/lib/foreman_tasks/cleaner.rb +4 -6
  33. data/lib/foreman_tasks/dynflow/configuration.rb +1 -1
  34. data/lib/foreman_tasks/dynflow/persistence.rb +4 -6
  35. data/lib/foreman_tasks/engine.rb +2 -2
  36. data/lib/foreman_tasks/tasks/cleanup.rake +2 -2
  37. data/lib/foreman_tasks/tasks/dynflow.rake +6 -0
  38. data/lib/foreman_tasks/tasks/export_tasks.rake +1 -1
  39. data/lib/foreman_tasks/version.rb +1 -1
  40. data/package.json +1 -1
  41. data/script/npm_link_foreman_js.sh +26 -0
  42. data/test/controllers/api/recurring_logics_controller_test.rb +1 -1
  43. data/test/controllers/api/tasks_controller_test.rb +17 -7
  44. data/test/controllers/tasks_controller_test.rb +6 -6
  45. data/test/core/unit/runner_test.rb +20 -20
  46. data/test/core/unit/task_launcher_test.rb +8 -8
  47. data/test/helpers/foreman_tasks/foreman_tasks_helper_test.rb +7 -7
  48. data/test/helpers/foreman_tasks/tasks_helper_test.rb +3 -3
  49. data/test/lib/actions/middleware/keep_current_request_id_test.rb +3 -3
  50. data/test/support/history_tasks_builder.rb +1 -1
  51. data/test/tasks/generate_task_actions_test.rb +1 -1
  52. data/test/unit/actions/action_with_sub_plans_test.rb +2 -2
  53. data/test/unit/actions/bulk_action_test.rb +6 -6
  54. data/test/unit/actions/proxy_action_test.rb +20 -20
  55. data/test/unit/actions/recurring_action_test.rb +30 -32
  56. data/test/unit/cleaner_test.rb +24 -24
  57. data/test/unit/dashboard_table_filter_test.rb +5 -5
  58. data/test/unit/otp_manager_test.rb +2 -2
  59. data/test/unit/proxy_selector_test.rb +9 -9
  60. data/test/unit/recurring_logic_test.rb +38 -32
  61. data/test/unit/remote_task_test.rb +2 -2
  62. data/test/unit/task_groups_test.rb +4 -4
  63. data/test/unit/task_test.rb +18 -18
  64. data/test/unit/triggering_test.rb +8 -8
  65. data/test/unit/troubleshooting_help_generator_test.rb +6 -6
  66. data/test/unit/ui_notifications_test.rb +11 -11
  67. data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +3 -3
  68. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +8 -138
  69. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskButtons.js +168 -0
  70. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +6 -7
  71. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskSkeleton.js +48 -0
  72. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +1 -1
  73. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +13 -70
  74. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskButtons.test.js +95 -0
  75. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +78 -208
  76. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskButtons.test.js.snap +212 -0
  77. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +8 -4
  78. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +87 -70
  79. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +13 -14
  80. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +48 -121
  81. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +3 -16
  82. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +57 -28
  83. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.fixtures.js +2 -2
  84. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +6 -0
  85. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +2 -18
  86. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +78 -27
  87. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +14 -101
  88. data/webpack/ForemanTasks/Components/TaskDetails/index.js +8 -3
  89. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.scss +4 -0
  90. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/OtherInfo.js +53 -0
  91. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/OtherInfo.test.js +14 -0
  92. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.js +27 -19
  93. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.scss +14 -0
  94. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.test.js +1 -34
  95. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/{StoppedTasksCardHelper.js → StoppedTasksCardTable.js} +28 -1
  96. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCardTable.test.js +54 -0
  97. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/OtherInfo.test.js.snap +48 -0
  98. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCard.test.js.snap +60 -1367
  99. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCardTable.test.js.snap +960 -0
  100. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/__snapshots__/TasksCardsGrid.test.js.snap +14 -11
  101. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardConstants.js +2 -0
  102. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardSelectors.js +17 -11
  103. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardSelectors.test.js +26 -14
  104. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboard.test.js.snap +14 -11
  105. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboardSelectors.test.js.snap +38 -22
  106. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalSelectors.js +1 -0
  107. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalSelectors.test.js +1 -0
  108. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalSelectors.test.js.snap +2 -0
  109. data/webpack/ForemanTasks/Components/TasksTable/TasksBulkActions.js +24 -7
  110. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +3 -3
  111. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +6 -3
  112. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.scss +0 -10
  113. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +1 -0
  114. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksBulkActions.test.js +13 -0
  115. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +1 -0
  116. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTablePage.test.js +2 -1
  117. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +1 -0
  118. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksBulkActions.test.js.snap +48 -0
  119. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +1 -0
  120. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +39 -7
  121. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionCellFormatter.test.js.snap +1 -0
  122. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionNameCellFormatter.test.js.snap +3 -1
  123. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/selectionCellFormatter.test.js.snap +2 -0
  124. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/actionCellFormatter.test.js +1 -1
  125. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionCellFormatter.test.js +1 -1
  126. data/webpack/ForemanTasks/Components/TasksTable/formatters/actionCellFormatter.js +10 -7
  127. data/webpack/ForemanTasks/Components/TasksTable/formatters/actionNameCellFormatter.js +6 -1
  128. data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionCellFormatter.js +7 -0
  129. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.js +39 -31
  130. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.test.js +17 -8
  131. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ActionButton.test.js.snap +8 -0
  132. data/webpack/ForemanTasks/Components/common/urlHelpers.js +7 -0
  133. data/webpack/ForemanTasks/ForemanTasksReducers.js +0 -2
  134. data/webpack/__mocks__/foremanReact/common/helpers.js +2 -0
  135. data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +10 -0
  136. data/webpack/__mocks__/foremanReact/redux/API/index.js +10 -0
  137. data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware.js +5 -0
  138. metadata +27 -17
  139. data/.travis.yml +0 -5
  140. data/app/assets/stylesheets/foreman_tasks/tasks.scss +0 -9
  141. data/script/travis_run_js_tests.sh +0 -7
  142. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +0 -38
  143. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsReducer.test.js +0 -33
  144. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsReducer.test.js.snap +0 -26
  145. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/integration.test.js.snap +0 -122
  146. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +0 -72
  147. data/webpack/__mocks__/foremanReact/redux/API.js +0 -7
@@ -1,135 +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(`/foreman_tasks/api/tasks/${id}/details`);
60
- dispatch(requestSuccess(data));
61
- } catch (error) {
62
- dispatch(requestFailure(error));
63
- document.location.reload();
64
- } finally {
65
- hideLoading();
66
- }
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
+ );
67
36
  };
68
37
 
69
- export const fetchTaskDetails = (
70
- id,
71
- timeoutId,
72
- refetchTaskDetailsAction
73
- ) => async dispatch => {
74
- showLoading();
75
- dispatch(startRequest());
76
- await getTasksDetails(id, dispatch, timeoutId, refetchTaskDetailsAction);
77
- };
78
-
79
- const getTasksDetails = async (
80
- id,
81
- dispatch,
82
- timeoutId,
83
- refetchTaskDetailsAction
84
- ) => {
85
- try {
86
- const { data } = await API.get(`/foreman_tasks/api/tasks/${id}/details`);
87
- dispatch(requestSuccess(data));
88
- if (data.state !== 'stopped') {
89
- dispatch(taskReloadStart(timeoutId, refetchTaskDetailsAction, id));
90
- }
91
- } catch (error) {
92
- dispatch(requestFailure(error));
93
- } finally {
94
- hideLoading();
95
- }
96
- };
97
-
98
- const startRequest = () => ({
99
- type: FOREMAN_TASK_DETAILS_FETCH_TASK_REQUEST,
100
- });
101
-
102
- const requestSuccess = data => ({
103
- type: FOREMAN_TASK_DETAILS_FETCH_TASK_SUCCESS,
104
- payload: data,
105
- });
106
-
107
- const requestFailure = error => ({
108
- type: FOREMAN_TASK_DETAILS_FETCH_TASK_FAILURE,
109
- payload: error,
110
- });
111
-
112
38
  export const cancelStep = (taskId, stepId) => async dispatch => {
113
- dispatch({ type: TASK_STEP_CANCEL_REQUEST });
114
39
  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
- }
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
+ );
135
62
  };
@@ -1,17 +1,4 @@
1
- export const FOREMAN_TASK_DETAILS_INIT = 'FOREMAN_TASK_DETAILS_INIT';
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 FOREMAN_TASK_DETAILS_FETCH_TASK_REQUEST =
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,79 +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 selectStartAt = state => selectTaskDetails(state).start_at || null;
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
- selectTaskDetails(state).start_before || null;
21
+ selectTaskDetailsResponse(state)?.start_before;
10
22
 
11
23
  export const selectStartedAt = state =>
12
- selectTaskDetails(state).started_at || null;
24
+ selectTaskDetailsResponse(state)?.started_at;
13
25
 
14
- export const selectEndedAt = state => selectTaskDetails(state).ended_at || null;
26
+ export const selectEndedAt = state =>
27
+ selectTaskDetailsResponse(state)?.ended_at;
15
28
 
16
- export const selectInput = state => selectTaskDetails(state).input || [];
29
+ export const selectInput = state =>
30
+ selectTaskDetailsResponse(state).input || [];
17
31
 
18
- export const selectOutput = state => selectTaskDetails(state).output || {};
32
+ export const selectOutput = state =>
33
+ selectTaskDetailsResponse(state).output || {};
19
34
 
20
35
  export const selectResumable = state =>
21
- selectTaskDetails(state).resumable || false;
36
+ selectTaskDetailsResponse(state).resumable || false;
22
37
 
23
38
  export const selectCancellable = state =>
24
- selectTaskDetails(state).cancellable || false;
39
+ selectTaskDetailsResponse(state).cancellable || false;
25
40
 
26
41
  export const selectErrors = state => {
27
- const { humanized } = selectTaskDetails(state);
42
+ const { humanized } = selectTaskDetailsResponse(state);
28
43
  return humanized ? humanized.errors : [];
29
44
  };
30
45
 
31
46
  export const selectProgress = state =>
32
- selectTaskDetails(state).progress
33
- ? parseFloat((selectTaskDetails(state).progress * 100).toFixed(2))
47
+ selectTaskDetailsResponse(state).progress
48
+ ? Math.trunc(selectTaskDetailsResponse(state).progress * 100)
34
49
  : 0;
35
50
 
36
51
  export const selectUsername = state =>
37
- selectTaskDetails(state).username || null;
52
+ selectTaskDetailsResponse(state)?.username;
38
53
 
39
- export const selectLabel = state => selectTaskDetails(state).label || null;
54
+ export const selectLabel = state => selectTaskDetailsResponse(state)?.label;
40
55
 
41
56
  export const selectExecutionPlan = state =>
42
- selectTaskDetails(state).execution_plan || {};
57
+ selectTaskDetailsResponse(state).execution_plan || {};
43
58
 
44
59
  export const selectFailedSteps = state =>
45
- selectTaskDetails(state).failed_steps || [];
60
+ selectTaskDetailsResponse(state).failed_steps || [];
46
61
 
47
62
  export const selectRunningSteps = state =>
48
- selectTaskDetails(state).running_steps || [];
63
+ selectTaskDetailsResponse(state).running_steps || [];
49
64
 
50
- export const selectHelp = state => selectTaskDetails(state).help || null;
65
+ export const selectHelp = state => selectTaskDetailsResponse(state)?.help;
51
66
 
52
67
  export const selectHasSubTasks = state =>
53
- selectTaskDetails(state).has_sub_tasks || false;
68
+ selectTaskDetailsResponse(state).has_sub_tasks || false;
54
69
 
55
- export const selectLocks = state => selectTaskDetails(state).locks || [];
70
+ export const selectLocks = state =>
71
+ selectTaskDetailsResponse(state).locks || [];
56
72
 
57
73
  export const selectUsernamePath = state =>
58
- selectTaskDetails(state).username_path || null;
74
+ selectTaskDetailsResponse(state)?.username_path;
59
75
 
60
- export const selectAction = state => selectTaskDetails(state).action || '';
76
+ export const selectAction = state =>
77
+ selectTaskDetailsResponse(state).action || '';
61
78
 
62
- export const selectState = state => selectTaskDetails(state).state || null;
79
+ export const selectState = state => selectTaskDetailsResponse(state)?.state;
63
80
 
64
- export const selectResult = state => selectTaskDetails(state).result || null;
81
+ export const selectResult = state => selectTaskDetailsResponse(state)?.result;
65
82
 
66
83
  export const selectTimeoutId = state =>
67
- selectTaskDetails(state).timeoutId || null;
84
+ selectTaskDetailsResponse(state)?.timeoutId;
68
85
 
69
86
  export const selectTaskReload = state =>
70
- selectTaskDetails(state).taskReload || false;
87
+ !!selectDoesIntervalExist(state, FOREMAN_TASK_DETAILS);
71
88
 
72
89
  export const selectParentTask = state =>
73
- selectTaskDetails(state).parent_task_id || '';
90
+ selectTaskDetailsResponse(state).parent_task_id || '';
74
91
 
75
92
  export const selectExternalId = state =>
76
- selectTaskDetails(state).external_id || null;
93
+ selectTaskDetailsResponse(state)?.external_id;
77
94
 
78
95
  export const selectDynflowEnableConsole = state =>
79
- selectTaskDetails(state).dynflow_enable_console || false;
96
+ selectTaskDetailsResponse(state).dynflow_enable_console || false;
97
+
98
+ export const selectCanEdit = state =>
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;
@@ -1,8 +1,8 @@
1
1
  export const minProps = {
2
2
  cancelStep: jest.fn(),
3
+ taskReload: false,
3
4
  taskReloadStop: jest.fn(),
4
5
  taskReloadStart: jest.fn(),
5
- refetchTaskDetails: jest.fn(),
6
- fetchTaskDetails: jest.fn(),
7
6
  taskProgressToggle: jest.fn(),
7
+ status: 'RESOLVED',
8
8
  };
@@ -4,6 +4,12 @@ import TaskDetails from '../TaskDetails';
4
4
  import { minProps } from './TaskDetails.fixtures';
5
5
 
6
6
  const fixtures = {
7
+ 'render with loading Props': { ...minProps, isLoading: true },
8
+ 'render with error Props': {
9
+ ...minProps,
10
+ status: 'ERROR',
11
+ APIerror: { message: 'some-error' },
12
+ },
7
13
  'render with min Props': minProps,
8
14
  };
9
15
 
@@ -3,33 +3,17 @@ import { API } from 'foremanReact/redux/API';
3
3
  import {
4
4
  taskReloadStop,
5
5
  taskReloadStart,
6
- fetchTaskDetails,
7
6
  cancelStep,
8
7
  } from '../TaskDetailsActions';
9
8
 
10
9
  jest.mock('foremanReact/redux/API');
11
10
 
12
- API.get.mockImplementation(async () => ({ data: 'some-data' }));
13
11
  API.post.mockImplementation(async () => ({ data: 'some-data' }));
14
12
 
15
13
  const fixtures = {
16
14
  'should start reload': () => taskReloadStart(1),
17
- 'should stop reload': () => taskReloadStop(2),
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
- },
15
+ 'should stop reload': () => taskReloadStop(),
16
+ 'should cancelStep': () => cancelStep('task-id', 'step-id'),
33
17
  };
34
18
 
35
19
  describe('TaskDetails - Actions', () =>
@@ -1,5 +1,79 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
+ exports[`TaskDetails rendering render with error Props 1`] = `
4
+ <MessageBox
5
+ icontype="error-circle-o"
6
+ key="task-details-error"
7
+ msg="Could not receive data: some-error"
8
+ />
9
+ `;
10
+
11
+ exports[`TaskDetails rendering render with loading Props 1`] = `
12
+ <div
13
+ className="task-details-react well"
14
+ >
15
+ <ForwardRef
16
+ animation={false}
17
+ defaultActiveKey={1}
18
+ id="task-details-tabs"
19
+ >
20
+ <Tab
21
+ eventKey={1}
22
+ title="Task"
23
+ >
24
+ <TaskSkeleton />
25
+ </Tab>
26
+ <Tab
27
+ disabled={true}
28
+ eventKey={2}
29
+ title="Running Steps"
30
+ >
31
+ <RunningSteps
32
+ cancelStep={[MockFunction]}
33
+ id="a15dd820-32f1-4ced-9ab7-c0fab8234c47"
34
+ runningSteps={Array []}
35
+ taskReload={false}
36
+ taskReloadStart={[MockFunction]}
37
+ />
38
+ </Tab>
39
+ <Tab
40
+ disabled={true}
41
+ eventKey={3}
42
+ title="Errors"
43
+ >
44
+ <Errors
45
+ executionPlan={Object {}}
46
+ failedSteps={Array []}
47
+ />
48
+ </Tab>
49
+ <Tab
50
+ disabled={true}
51
+ eventKey={4}
52
+ title="Locks"
53
+ >
54
+ <Locks
55
+ locks={Array []}
56
+ />
57
+ </Tab>
58
+ <Tab
59
+ disabled={true}
60
+ eventKey={5}
61
+ title="Raw"
62
+ >
63
+ <Raw
64
+ endedAt=""
65
+ externalId=""
66
+ id="a15dd820-32f1-4ced-9ab7-c0fab8234c47"
67
+ input={Array []}
68
+ label=""
69
+ output={Object {}}
70
+ startedAt=""
71
+ />
72
+ </Tab>
73
+ </ForwardRef>
74
+ </div>
75
+ `;
76
+
3
77
  exports[`TaskDetails rendering render with min Props 1`] = `
4
78
  <div
5
79
  className="task-details-react well"
@@ -15,55 +89,32 @@ exports[`TaskDetails rendering render with min Props 1`] = `
15
89
  >
16
90
  <Task
17
91
  action=""
18
- cancelStep={[MockFunction]}
92
+ canEdit={false}
19
93
  cancelTaskRequest={[Function]}
20
94
  cancellable={false}
21
95
  dynflowEnableConsole={false}
22
96
  endedAt=""
23
- error={Array []}
24
- executionPlan={Object {}}
97
+ errors={Array []}
25
98
  externalId=""
26
- failedSteps={Array []}
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
- }
44
99
  hasSubTasks={false}
45
100
  help=""
46
101
  id="a15dd820-32f1-4ced-9ab7-c0fab8234c47"
47
102
  input={Array []}
48
103
  label=""
49
- locks={Array []}
50
104
  output={Object {}}
51
105
  parentTask=""
52
106
  progress={0}
53
- refetchTaskDetails={[MockFunction]}
54
107
  result="error"
55
108
  resumable={false}
56
109
  resumeTaskRequest={[Function]}
57
- runningSteps={Array []}
58
110
  startAt=""
59
111
  startBefore=""
60
112
  startedAt=""
61
113
  state=""
114
+ status="RESOLVED"
62
115
  taskProgressToggle={[Function]}
63
116
  taskReload={false}
64
117
  taskReloadStart={[MockFunction]}
65
- taskReloadStop={[MockFunction]}
66
- timeoutId={null}
67
118
  username=""
68
119
  usernamePath=""
69
120
  />
@@ -76,8 +127,8 @@ exports[`TaskDetails rendering render with min Props 1`] = `
76
127
  cancelStep={[MockFunction]}
77
128
  id="a15dd820-32f1-4ced-9ab7-c0fab8234c47"
78
129
  runningSteps={Array []}
79
- taskProgressToggle={[Function]}
80
130
  taskReload={false}
131
+ taskReloadStart={[MockFunction]}
81
132
  />
82
133
  </Tab>
83
134
  <Tab