foreman-tasks 1.1.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (189) 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/README.md +2 -0
  8. data/app/controllers/foreman_tasks/api/tasks_controller.rb +63 -58
  9. data/app/controllers/foreman_tasks/concerns/parameters/triggering.rb +1 -1
  10. data/app/controllers/foreman_tasks/recurring_logics_controller.rb +7 -0
  11. data/app/controllers/foreman_tasks/tasks_controller.rb +9 -14
  12. data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +3 -3
  13. data/app/lib/actions/proxy_action.rb +1 -1
  14. data/app/models/foreman_tasks/recurring_logic.rb +1 -1
  15. data/app/models/foreman_tasks/task.rb +15 -0
  16. data/app/models/foreman_tasks/task/dynflow_task.rb +29 -33
  17. data/app/models/foreman_tasks/task/status_explicator.rb +1 -1
  18. data/app/models/foreman_tasks/triggering.rb +1 -1
  19. data/app/models/setting/foreman_tasks.rb +2 -2
  20. data/app/services/ui_notifications/tasks/task_bulk_stop.rb +36 -0
  21. data/app/views/foreman_tasks/api/tasks/details.json.rabl +0 -1
  22. data/app/views/foreman_tasks/api/tasks/index.json.rabl +2 -0
  23. data/app/views/foreman_tasks/api/tasks/show.json.rabl +2 -0
  24. data/app/views/foreman_tasks/recurring_logics/index.html.erb +3 -1
  25. data/config/routes.rb +3 -1
  26. data/db/migrate/20200517215015_rename_bookmarks_controller.rb +35 -0
  27. data/db/migrate/20200519093217_drop_dynflow_allow_dangerous_actions_setting.foreman_tasks.rb +5 -0
  28. data/db/migrate/20200611090846_add_task_lock_index_on_resource_type_and_task_id.rb +1 -1
  29. data/db/seeds.d/30-notification_blueprints.rb +14 -7
  30. data/db/seeds.d/61-foreman_tasks_bookmarks.rb +1 -1
  31. data/lib/foreman_tasks/cleaner.rb +4 -6
  32. data/lib/foreman_tasks/dynflow/configuration.rb +1 -1
  33. data/lib/foreman_tasks/dynflow/persistence.rb +4 -6
  34. data/lib/foreman_tasks/engine.rb +3 -8
  35. data/lib/foreman_tasks/version.rb +1 -1
  36. data/locale/action_names.rb +1 -1
  37. data/locale/en/LC_MESSAGES/foreman_tasks.mo +0 -0
  38. data/locale/en/foreman_tasks.po +270 -54
  39. data/locale/foreman_tasks.pot +630 -292
  40. data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
  41. data/locale/fr/foreman_tasks.po +817 -0
  42. data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
  43. data/locale/ja/foreman_tasks.po +817 -0
  44. data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
  45. data/locale/zh_CN/foreman_tasks.po +816 -0
  46. data/package.json +1 -1
  47. data/script/npm_link_foreman_js.sh +26 -0
  48. data/test/controllers/api/recurring_logics_controller_test.rb +1 -1
  49. data/test/controllers/api/tasks_controller_test.rb +7 -7
  50. data/test/controllers/tasks_controller_test.rb +6 -6
  51. data/test/core/unit/runner_test.rb +20 -20
  52. data/test/core/unit/task_launcher_test.rb +8 -8
  53. data/test/helpers/foreman_tasks/foreman_tasks_helper_test.rb +7 -7
  54. data/test/helpers/foreman_tasks/tasks_helper_test.rb +3 -3
  55. data/test/lib/actions/middleware/keep_current_request_id_test.rb +3 -3
  56. data/test/support/history_tasks_builder.rb +1 -1
  57. data/test/tasks/generate_task_actions_test.rb +1 -1
  58. data/test/unit/actions/action_with_sub_plans_test.rb +2 -2
  59. data/test/unit/actions/bulk_action_test.rb +6 -6
  60. data/test/unit/actions/proxy_action_test.rb +20 -20
  61. data/test/unit/actions/recurring_action_test.rb +30 -32
  62. data/test/unit/cleaner_test.rb +24 -24
  63. data/test/unit/dashboard_table_filter_test.rb +5 -5
  64. data/test/unit/otp_manager_test.rb +2 -2
  65. data/test/unit/proxy_selector_test.rb +9 -9
  66. data/test/unit/recurring_logic_test.rb +32 -32
  67. data/test/unit/remote_task_test.rb +2 -2
  68. data/test/unit/task_groups_test.rb +4 -4
  69. data/test/unit/task_test.rb +18 -18
  70. data/test/unit/triggering_test.rb +8 -8
  71. data/test/unit/troubleshooting_help_generator_test.rb +6 -6
  72. data/test/unit/ui_notifications_test.rb +11 -11
  73. data/webpack/ForemanTasks/Components/TaskActions/TaskAction.test.js +60 -0
  74. data/webpack/ForemanTasks/Components/{TasksTable/TasksTableActionHelpers.js → TaskActions/TaskActionHelpers.js} +21 -6
  75. data/webpack/ForemanTasks/Components/{TasksTable/__tests__/TasksTableActionHelpers.test.js → TaskActions/TaskActionHelpers.test.js} +2 -2
  76. data/webpack/ForemanTasks/Components/TaskActions/TaskActionsConstants.js +16 -0
  77. data/webpack/ForemanTasks/Components/TaskActions/UnlockModals.js +60 -0
  78. data/webpack/ForemanTasks/Components/TaskActions/UnlockModals.test.js +14 -0
  79. data/webpack/ForemanTasks/Components/TaskActions/__snapshots__/TaskAction.test.js.snap +233 -0
  80. data/webpack/ForemanTasks/Components/TaskActions/__snapshots__/UnlockModals.test.js.snap +25 -0
  81. data/webpack/ForemanTasks/Components/TaskActions/index.js +115 -0
  82. data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +17 -3
  83. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +38 -205
  84. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskButtons.js +168 -0
  85. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +6 -7
  86. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskSkeleton.js +48 -0
  87. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +8 -1
  88. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +14 -7
  89. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskButtons.test.js +95 -0
  90. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskInfo.test.js +0 -1
  91. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/RunningSteps.test.js.snap +1 -1
  92. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +90 -189
  93. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskButtons.test.js.snap +212 -0
  94. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +8 -4
  95. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +100 -53
  96. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +3 -14
  97. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +57 -110
  98. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +3 -17
  99. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +57 -37
  100. data/webpack/ForemanTasks/Components/TaskDetails/TasksDetailsHelper.js +6 -1
  101. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.fixtures.js +8 -0
  102. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +13 -1
  103. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +6 -6
  104. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +86 -19
  105. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +25 -21
  106. data/webpack/ForemanTasks/Components/TaskDetails/index.js +12 -11
  107. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardActions.js +1 -1
  108. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardActions.test.js +2 -2
  109. data/webpack/ForemanTasks/Components/TasksTable/Components/ActionSelectButton.js +14 -1
  110. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModal.js +83 -0
  111. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalActions.js +106 -0
  112. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalReducer.js +38 -0
  113. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalSelectors.js +46 -0
  114. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModal.test.js +36 -0
  115. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalActions.test.js +205 -0
  116. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalReducer.test.js +27 -0
  117. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalSelectors.test.js +55 -0
  118. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModal.test.js.snap +41 -0
  119. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalReducer.test.js.snap +19 -0
  120. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalSelectors.test.js.snap +32 -0
  121. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/index.js +29 -0
  122. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ActionSelectButton.test.js +1 -0
  123. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ActionSelectButton.test.js.snap +11 -0
  124. data/webpack/ForemanTasks/Components/TasksTable/TasksBulkActions.js +135 -35
  125. data/webpack/ForemanTasks/Components/TasksTable/TasksTable.js +13 -9
  126. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +26 -66
  127. data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +10 -12
  128. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +30 -96
  129. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSchema.js +2 -2
  130. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +8 -4
  131. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksBulkActions.test.js +50 -2
  132. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +3 -12
  133. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableActions.test.js +22 -26
  134. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTablePage.test.js +2 -1
  135. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +3 -14
  136. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksBulkActions.test.js.snap +155 -0
  137. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +3 -14
  138. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableActions.test.js.snap +17 -124
  139. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +63 -133
  140. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionCellFormatter.test.js.snap +1 -0
  141. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/selectionCellFormatter.test.js.snap +2 -0
  142. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/actionCellFormatter.test.js +1 -1
  143. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionCellFormatter.test.js +1 -1
  144. data/webpack/ForemanTasks/Components/TasksTable/formatters/actionCellFormatter.js +10 -7
  145. data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionCellFormatter.js +7 -0
  146. data/webpack/ForemanTasks/Components/TasksTable/index.js +2 -2
  147. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.js +55 -19
  148. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.test.js +75 -19
  149. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ActionButton.test.js.snap +88 -21
  150. data/webpack/ForemanTasks/Components/common/ClickConfirmation/ClickConfirmation.scss +9 -0
  151. data/webpack/ForemanTasks/Components/common/ClickConfirmation/ClickConfirmation.test.js +44 -0
  152. data/webpack/ForemanTasks/Components/common/ClickConfirmation/__snapshots__/ClickConfirmation.test.js.snap +52 -0
  153. data/webpack/ForemanTasks/Components/common/ClickConfirmation/index.js +59 -66
  154. data/webpack/ForemanTasks/Components/common/{ToastTypesConstants.js → ToastsHelpers/ToastTypesConstants.js} +0 -0
  155. data/webpack/ForemanTasks/Components/common/ToastsHelpers/index.js +15 -0
  156. data/webpack/ForemanTasks/Components/common/urlHelpers.js +7 -0
  157. data/webpack/ForemanTasks/ForemanTasksReducers.js +2 -2
  158. data/webpack/ForemanTasks/Routes/ForemanTasksRoutes.test.js +2 -1
  159. data/webpack/__mocks__/foremanReact/common/helpers.js +2 -0
  160. data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalHooks.js +2 -2
  161. data/webpack/__mocks__/foremanReact/components/ForemanModal/index.js +17 -3
  162. data/webpack/__mocks__/foremanReact/components/common/ActionButtons/ActionButtons.js +3 -0
  163. data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +10 -0
  164. data/webpack/__mocks__/foremanReact/redux/API/index.js +10 -0
  165. data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware.js +5 -0
  166. metadata +51 -28
  167. data/.travis.yml +0 -5
  168. data/script/travis_run_js_tests.sh +0 -7
  169. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +0 -44
  170. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsReducer.test.js +0 -33
  171. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsReducer.test.js.snap +0 -26
  172. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/integration.test.js.snap +0 -122
  173. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +0 -63
  174. data/webpack/ForemanTasks/Components/TasksTable/Components/CancelConfirm.js +0 -53
  175. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmationModals.js +0 -56
  176. data/webpack/ForemanTasks/Components/TasksTable/Components/ResumeConfirm.js +0 -52
  177. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/CancelConfirm.test.js +0 -26
  178. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ConfirmationModals.test.js +0 -24
  179. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ResumeConfirm.test.js +0 -26
  180. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/CancelConfirm.test.js.snap +0 -65
  181. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ConfirmationModals.test.js.snap +0 -30
  182. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ResumeConfirm.test.js.snap +0 -63
  183. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.js +0 -23
  184. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.test.js +0 -26
  185. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.js +0 -23
  186. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.test.js +0 -27
  187. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/CancelButton.test.js.snap +0 -15
  188. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ResumeButton.test.js.snap +0 -15
  189. data/webpack/__mocks__/foremanReact/API.js +0 -7
@@ -8,6 +8,8 @@ import Pagination from 'foremanReact/components/Pagination/PaginationWrapper';
8
8
  import { getURIQuery } from 'foremanReact/common/helpers';
9
9
  import createTasksTableSchema from './TasksTableSchema';
10
10
  import { updateURlQuery } from './TasksTableHelpers';
11
+ import { RESUME_MODAL, CANCEL_MODAL } from './TasksTableConstants';
12
+ import { FORCE_UNLOCK_MODAL } from '../TaskActions/TaskActionsConstants';
11
13
 
12
14
  const TasksTable = ({
13
15
  getTableItems,
@@ -23,7 +25,7 @@ const TasksTable = ({
23
25
  selectRow,
24
26
  unselectRow,
25
27
  openClickedModal,
26
- modalProps,
28
+ openModal,
27
29
  allRowsSelected,
28
30
  }) => {
29
31
  const { search, pathname } = history.location;
@@ -97,14 +99,21 @@ const TasksTable = ({
97
99
  openClickedModal({
98
100
  taskId,
99
101
  taskName,
100
- setModalOpen: modalProps.cancelModal.setModalOpen,
102
+ setModalOpen: () => openModal(CANCEL_MODAL),
101
103
  });
102
104
  },
103
105
  resumeTask: (taskId, taskName) => {
104
106
  openClickedModal({
105
107
  taskId,
106
108
  taskName,
107
- setModalOpen: modalProps.resumeModal.setModalOpen,
109
+ setModalOpen: () => openModal(RESUME_MODAL),
110
+ });
111
+ },
112
+ forceCancelTask: (taskId, taskName) => {
113
+ openClickedModal({
114
+ taskId,
115
+ taskName,
116
+ setModalOpen: () => openModal(FORCE_UNLOCK_MODAL),
108
117
  });
109
118
  },
110
119
  };
@@ -151,12 +160,7 @@ TasksTable.propTypes = {
151
160
  unselectAllRows: PropTypes.func.isRequired,
152
161
  selectRow: PropTypes.func.isRequired,
153
162
  unselectRow: PropTypes.func.isRequired,
154
- modalProps: PropTypes.shape({
155
- cancelSelectedModal: PropTypes.object,
156
- resumeSelectedModal: PropTypes.object,
157
- cancelModal: PropTypes.object,
158
- resumeModal: PropTypes.object,
159
- }).isRequired,
163
+ openModal: PropTypes.func.isRequired,
160
164
  allRowsSelected: PropTypes.bool,
161
165
  };
162
166
 
@@ -1,8 +1,6 @@
1
1
  import { getURIQuery } from 'foremanReact/common/helpers';
2
2
  import { getTableItemsAction } from 'foremanReact/components/common/table';
3
- import API from 'foremanReact/API';
4
- import { addToast } from 'foremanReact/redux/actions/toasts';
5
- import { sprintf } from 'foremanReact/common/I18n';
3
+
6
4
  import {
7
5
  TASKS_TABLE_ID,
8
6
  SELECT_ROWS,
@@ -11,26 +9,20 @@ import {
11
9
  UNSELECT_ROWS,
12
10
  UPDATE_CLICKED,
13
11
  OPEN_SELECT_ALL,
14
- TASKS_RESUME_REQUEST,
15
- TASKS_RESUME_SUCCESS,
16
- TASKS_RESUME_FAILURE,
17
- TASKS_CANCEL_REQUEST,
18
- TASKS_CANCEL_SUCCESS,
19
- TASKS_CANCEL_FAILURE,
12
+ UPDATE_MODAL,
20
13
  } from './TasksTableConstants';
21
- import { TOAST_TYPES } from '../common/ToastTypesConstants';
22
14
  import { getApiPathname } from './TasksTableHelpers';
23
15
  import { fetchTasksSummary } from '../TasksDashboard/TasksDashboardActions';
24
16
  import {
25
- resumeToastInfo,
26
- cancelToastInfo,
27
- toastDispatch,
28
- } from './TasksTableActionHelpers';
17
+ cancelTaskRequest,
18
+ resumeTaskRequest,
19
+ forceCancelTaskRequest,
20
+ } from '../TaskActions';
29
21
 
30
22
  export const getTableItems = url =>
31
23
  getTableItemsAction(TASKS_TABLE_ID, getURIQuery(url), getApiPathname(url));
32
24
 
33
- export const reloadPage = (url, parentTaskID, dispatch) => {
25
+ export const reloadPage = (url, parentTaskID) => dispatch => {
34
26
  dispatch(getTableItems(url));
35
27
  dispatch(fetchTasksSummary(getURIQuery(url).time, parentTaskID));
36
28
  };
@@ -42,35 +34,7 @@ export const cancelTask = ({
42
34
  parentTaskID,
43
35
  }) => async dispatch => {
44
36
  await dispatch(cancelTaskRequest(taskId, taskName));
45
- reloadPage(url, parentTaskID, dispatch);
46
- };
47
-
48
- export const cancelTaskRequest = (id, name) => async dispatch => {
49
- dispatch(
50
- addToast({
51
- type: TOAST_TYPES.INFO,
52
- message: sprintf('Trying to cancel %s task', name),
53
- })
54
- );
55
- dispatch({ type: TASKS_CANCEL_REQUEST });
56
- try {
57
- await API.post(`/foreman_tasks/tasks/${id}/cancel`);
58
- dispatch({ type: TASKS_CANCEL_SUCCESS });
59
- toastDispatch({
60
- type: 'cancelled',
61
- name,
62
- toastInfo: cancelToastInfo,
63
- dispatch,
64
- });
65
- } catch ({ response }) {
66
- dispatch({ type: TASKS_CANCEL_FAILURE, payload: response });
67
- toastDispatch({
68
- type: 'skipped',
69
- name,
70
- toastInfo: cancelToastInfo,
71
- dispatch,
72
- });
73
- }
37
+ reloadPage(url, parentTaskID)(dispatch);
74
38
  };
75
39
 
76
40
  export const resumeTask = ({
@@ -80,30 +44,18 @@ export const resumeTask = ({
80
44
  parentTaskID,
81
45
  }) => async dispatch => {
82
46
  await dispatch(resumeTaskRequest(taskId, taskName));
83
- reloadPage(url, parentTaskID, dispatch);
47
+ reloadPage(url, parentTaskID)(dispatch);
84
48
  };
85
49
 
86
- export const resumeTaskRequest = (id, name) => async dispatch => {
87
- dispatch({ type: TASKS_RESUME_REQUEST });
88
- try {
89
- await API.post(`/foreman_tasks/tasks/${id}/resume`);
90
-
91
- dispatch({ type: TASKS_RESUME_SUCCESS });
92
- toastDispatch({
93
- type: 'resumed',
94
- name,
95
- toastInfo: resumeToastInfo,
96
- dispatch,
97
- });
98
- } catch ({ response }) {
99
- dispatch({ type: TASKS_RESUME_FAILURE, payload: response });
100
- toastDispatch({
101
- type: 'failed',
102
- name,
103
- toastInfo: resumeToastInfo,
104
- dispatch,
105
- });
106
- }
50
+ export const forceCancelTask = ({
51
+ taskId,
52
+ taskName,
53
+ url,
54
+ parentTaskID,
55
+ }) => async dispatch => {
56
+ await dispatch(forceCancelTaskRequest(taskId, taskName));
57
+ dispatch(getTableItems(url));
58
+ dispatch(fetchTasksSummary(getURIQuery(url).time, parentTaskID));
107
59
  };
108
60
 
109
61
  export const selectPage = results => dispatch => {
@@ -141,3 +93,11 @@ export const openClickedModal = ({ taskId, taskName, setModalOpen }) => {
141
93
  payload: { clicked: { taskId, taskName } },
142
94
  };
143
95
  };
96
+
97
+ export const openModalAction = (modalID, setModalOpen) => {
98
+ setModalOpen();
99
+ return {
100
+ type: UPDATE_MODAL,
101
+ payload: { modalID },
102
+ };
103
+ };
@@ -8,23 +8,21 @@ export const UNSELECT_ALL_ROWS = 'UNSELECT_ALL_ROWS';
8
8
  export const SELECT_ALL_ROWS = 'SELECT_ALL_ROWS';
9
9
  export const OPEN_SELECT_ALL = 'OPEN_SELECT_ALL';
10
10
 
11
- export const TASKS_RESUME_REQUEST = 'TASKS_RESUME_REQUEST';
12
- export const TASKS_RESUME_SUCCESS = 'TASKS_RESUME_SUCCESS';
13
- export const TASKS_RESUME_FAILURE = 'TASKS_RESUME_FAILURE';
14
- export const TASKS_CANCEL_REQUEST = 'TASKS_CANCEL_REQUEST';
15
- export const TASKS_CANCEL_SUCCESS = 'TASKS_CANCEL_SUCCESS';
16
- export const TASKS_CANCEL_FAILURE = 'TASKS_CANCEL_FAILURE';
17
-
18
11
  export const BULK_CANCEL_PATH = 'bulk_cancel';
19
12
  export const BULK_RESUME_PATH = 'bulk_resume';
13
+ export const BULK_FORCE_CANCEL_PATH = 'bulk_stop';
14
+
15
+ export const CANCEL_MODAL = 'cancelConfirmModal';
16
+ export const RESUME_MODAL = 'resumeConfirmModal';
17
+ export const CANCEL_SELECTED_MODAL = 'cancelSelectedConfirmModal';
18
+ export const RESUME_SELECTED_MODAL = 'resumeSelectedConfirmModal';
19
+ export const CONFIRM_MODAL = 'ConfirmModal';
20
+ export const FORCE_UNLOCK_SELECTED_MODAL = 'forceUnlockSelectedConfirmModal';
20
21
 
21
- export const CANCEL_CONFIRM_MODAL_ID = 'cancelConfirmModal';
22
- export const RESUME_CONFIRM_MODAL_ID = 'resumeConfirmModal';
23
- export const CANCEL_SELECTED_CONFIRM_MODAL_ID = 'cancelSelectedConfirmModal';
24
- export const RESUME_SELECTED_CONFIRM_MODAL_ID = 'resumeSelectedConfirmModal';
25
22
  export const UPDATE_CLICKED = 'UPDATE_CLICKED';
23
+ export const UPDATE_MODAL = 'UPDATE_MODAL';
26
24
 
27
25
  export const TASKS_SEARCH_PROPS = {
28
26
  ...getControllerSearchProps('tasks'),
29
- controller: 'foreman_tasks/tasks',
27
+ controller: 'foreman_tasks_tasks',
30
28
  };
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { getURIsearch } from 'foremanReact/common/urlHelpers';
4
- import { Spinner } from 'patternfly-react';
4
+ import { Spinner, Button, Icon } from 'patternfly-react';
5
5
  import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
6
6
  import { translate as __ } from 'foremanReact/common/I18n';
7
7
  import { getURIQuery } from 'foremanReact/common/helpers';
@@ -11,13 +11,13 @@ import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanMod
11
11
  import TasksDashboard from '../TasksDashboard';
12
12
  import TasksTable from './TasksTable';
13
13
  import { resolveSearchQuery, getCSVurl } from './TasksTableHelpers';
14
- import { ConfirmationModals } from './Components/ConfirmationModals';
14
+ import ConfirmModal from './Components/ConfirmModal/';
15
15
  import {
16
16
  TASKS_SEARCH_PROPS,
17
- CANCEL_SELECTED_CONFIRM_MODAL_ID,
18
- RESUME_SELECTED_CONFIRM_MODAL_ID,
19
- RESUME_CONFIRM_MODAL_ID,
20
- CANCEL_CONFIRM_MODAL_ID,
17
+ CANCEL_SELECTED_MODAL,
18
+ RESUME_SELECTED_MODAL,
19
+ FORCE_UNLOCK_SELECTED_MODAL,
20
+ CONFIRM_MODAL,
21
21
  } from './TasksTableConstants';
22
22
  import { ActionSelectButton } from './Components/ActionSelectButton';
23
23
  import './TasksTablePage.scss';
@@ -26,10 +26,11 @@ import { SelectAllAlert } from './Components/SelectAllAlert';
26
26
  const TasksTablePage = ({
27
27
  getBreadcrumbs,
28
28
  history,
29
- clicked,
30
29
  createHeader,
31
30
  selectAllRows,
32
31
  showSelectAll,
32
+ modalID,
33
+ openModalAction,
33
34
  ...props
34
35
  }) => {
35
36
  const url = history.location.pathname + history.location.search;
@@ -38,83 +39,20 @@ const TasksTablePage = ({
38
39
  resolveSearchQuery(searchQuery, history);
39
40
  };
40
41
 
41
- const getSelectedTasks = () => {
42
- const selectedIDs = props.results.filter(item =>
43
- props.selectedRows.includes(item.id)
44
- );
45
- return selectedIDs.map(item => ({
46
- name: item.action,
47
- id: item.id,
48
- isCancellable: item.availableActions.cancellable,
49
- isResumable: item.availableActions.resumable,
50
- }));
51
- };
52
-
53
- const modalProps = {
54
- cancelSelectedModal: useForemanModal({
55
- id: CANCEL_SELECTED_CONFIRM_MODAL_ID,
56
- }),
57
- resumeSelectedModal: useForemanModal({
58
- id: RESUME_SELECTED_CONFIRM_MODAL_ID,
59
- }),
60
- cancelModal: useForemanModal({ id: CANCEL_CONFIRM_MODAL_ID }),
61
- resumeModal: useForemanModal({ id: RESUME_CONFIRM_MODAL_ID }),
62
- };
42
+ const { setModalOpen, setModalClosed } = useForemanModal({
43
+ id: CONFIRM_MODAL,
44
+ });
63
45
 
64
- const {
65
- bulkCancelById,
66
- bulkCancelBySearch,
67
- bulkResumeById,
68
- bulkResumeBySearch,
69
- cancelTask,
70
- resumeTask,
71
- parentTaskID,
72
- } = props;
73
- const tasksActions = {
74
- cancelSelectedTasks: () => {
75
- props.allRowsSelected
76
- ? bulkCancelBySearch({ query: uriQuery, parentTaskID })
77
- : bulkCancelById({
78
- selected: getSelectedTasks(),
79
- url,
80
- parentTaskID,
81
- });
82
- },
83
- cancelTask: () => {
84
- cancelTask({
85
- taskId: clicked.taskId,
86
- taskName: clicked.taskName,
87
- url,
88
- parentTaskID,
89
- });
90
- },
91
- resumeSelectedTasks: () => {
92
- props.allRowsSelected
93
- ? bulkResumeBySearch({ query: uriQuery, parentTaskID })
94
- : bulkResumeById({
95
- selected: getSelectedTasks(),
96
- url,
97
- parentTaskID,
98
- });
99
- },
100
- resumeTask: () => {
101
- resumeTask({
102
- taskId: clicked.taskId,
103
- taskName: clicked.taskName,
104
- url,
105
- parentTaskID,
106
- });
107
- },
108
- };
46
+ const openModal = id => openModalAction(id, setModalOpen);
109
47
 
110
48
  return (
111
49
  <div className="tasks-table-wrapper">
112
- <ConfirmationModals
113
- tasksActions={tasksActions}
114
- selectedRowsLen={
115
- props.allRowsSelected ? props.itemCount : props.selectedRows.length
116
- }
117
- modalProps={modalProps}
50
+ <ConfirmModal
51
+ id={CONFIRM_MODAL}
52
+ url={url}
53
+ parentTaskID={props.parentTaskID}
54
+ uriQuery={uriQuery}
55
+ setModalClosed={setModalClosed}
118
56
  />
119
57
  <PageLayout
120
58
  searchable
@@ -125,15 +63,19 @@ const TasksTablePage = ({
125
63
  toastNotifications="foreman-tasks-cancel"
126
64
  toolbarButtons={
127
65
  <React.Fragment>
128
- {props.status === STATUS.PENDING && <Spinner size="lg" loading />}
66
+ <Button onClick={() => props.reloadPage(url, props.parentTaskID)}>
67
+ <Icon type="fa" name="refresh" /> {__('Refresh Data')}
68
+ </Button>
69
+ {props.status === STATUS.PENDING && <Spinner size="md" loading />}
129
70
  <ExportButton
130
71
  url={getCSVurl(url, uriQuery)}
131
72
  title={__('Export All')}
132
73
  />
133
74
  <ActionSelectButton
134
75
  disabled={!(props.selectedRows.length || props.allRowsSelected)}
135
- onCancel={modalProps.cancelSelectedModal.setModalOpen}
136
- onResume={modalProps.resumeSelectedModal.setModalOpen}
76
+ onCancel={() => openModal(CANCEL_SELECTED_MODAL)}
77
+ onResume={() => openModal(RESUME_SELECTED_MODAL)}
78
+ onForceCancel={() => openModal(FORCE_UNLOCK_SELECTED_MODAL)}
137
79
  />
138
80
  </React.Fragment>
139
81
  }
@@ -152,7 +94,7 @@ const TasksTablePage = ({
152
94
  allRowsSelected={props.allRowsSelected}
153
95
  />
154
96
  )}
155
- <TasksTable history={history} {...props} modalProps={modalProps} />
97
+ <TasksTable history={history} {...props} openModal={openModal} />
156
98
  </React.Fragment>
157
99
  </PageLayout>
158
100
  </div>
@@ -172,22 +114,14 @@ TasksTablePage.propTypes = {
172
114
  actionName: PropTypes.string,
173
115
  status: PropTypes.oneOf(Object.keys(STATUS)),
174
116
  history: PropTypes.object.isRequired,
175
- cancelTask: PropTypes.func.isRequired,
176
- resumeTask: PropTypes.func.isRequired,
177
- bulkCancelById: PropTypes.func.isRequired,
178
- bulkCancelBySearch: PropTypes.func.isRequired,
179
- bulkResumeById: PropTypes.func.isRequired,
180
- bulkResumeBySearch: PropTypes.func.isRequired,
181
117
  selectedRows: PropTypes.arrayOf(PropTypes.string),
182
118
  parentTaskID: PropTypes.string,
183
119
  createHeader: PropTypes.func,
184
- clicked: PropTypes.shape({
185
- taskId: PropTypes.string,
186
- taskName: PropTypes.string,
187
- parentTaskID: PropTypes.string,
188
- }),
120
+ modalID: PropTypes.string,
121
+ openModalAction: PropTypes.func.isRequired,
189
122
  showSelectAll: PropTypes.bool,
190
123
  unselectAllRows: PropTypes.func.isRequired,
124
+ reloadPage: PropTypes.func.isRequired,
191
125
  };
192
126
 
193
127
  TasksTablePage.defaultProps = {
@@ -200,9 +134,9 @@ TasksTablePage.defaultProps = {
200
134
  status: STATUS.PENDING,
201
135
  selectedRows: [],
202
136
  parentTaskID: null,
203
- clicked: {},
204
137
  createHeader: () => __('Tasks'),
205
138
  showSelectAll: false,
139
+ modalID: '',
206
140
  };
207
141
 
208
142
  export default TasksTablePage;
@@ -67,7 +67,7 @@ const createTasksTableSchema = (
67
67
  sortableColumn('started_at', __('Started at'), 3, sortController, [
68
68
  dateCellFormmatter,
69
69
  ]),
70
- sortableColumn('duration', __('Duration'), 3, sortController, [
70
+ sortableColumn('duration', __('Duration'), 2, sortController, [
71
71
  durationCellFormmatter,
72
72
  ]),
73
73
  column(
@@ -76,7 +76,7 @@ const createTasksTableSchema = (
76
76
  headFormat,
77
77
  [actionCellFormatter(taskActions)],
78
78
  {
79
- className: 'col-md-1',
79
+ className: 'col-md-2',
80
80
  }
81
81
  ),
82
82
  ];
@@ -24,9 +24,6 @@ export const selectActionName = state =>
24
24
  export const selectSelectedRows = state =>
25
25
  selectTasksTableQuery(state).selectedRows || [];
26
26
 
27
- export const selectClicked = state =>
28
- selectTasksTableQuery(state).clicked || {};
29
-
30
27
  export const selectResults = createSelector(
31
28
  selectTasksTableContent,
32
29
  ({ results }) =>
@@ -38,7 +35,11 @@ export const selectResults = createSelector(
38
35
  username: result.username || '',
39
36
  state: result.state + (result.frozen ? ` ${__('Disabled')}` : ''),
40
37
  duration: getDuration(result.started_at, result.ended_at),
41
- availableActions: result.available_actions,
38
+ availableActions: {
39
+ ...result.available_actions,
40
+ stoppable: result.state !== 'stopped',
41
+ },
42
+ canEdit: result.can_edit,
42
43
  }))
43
44
  );
44
45
 
@@ -54,3 +55,6 @@ export const selectAllRowsSelected = state =>
54
55
 
55
56
  export const selectShowSelectAll = state =>
56
57
  selectTasksTableQuery(state).showSelectAll;
58
+
59
+ export const selectModalID = state =>
60
+ selectTasksTableQuery(state).modalID || '';