foreman-tasks 1.1.2 → 2.0.2

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 (132) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/README.md +2 -0
  4. data/app/controllers/foreman_tasks/api/tasks_controller.rb +33 -1
  5. data/app/controllers/foreman_tasks/tasks_controller.rb +9 -14
  6. data/app/lib/actions/proxy_action.rb +1 -1
  7. data/app/models/foreman_tasks/task.rb +4 -0
  8. data/app/models/foreman_tasks/task/dynflow_task.rb +3 -1
  9. data/app/models/setting/foreman_tasks.rb +1 -1
  10. data/app/services/ui_notifications/tasks/task_bulk_stop.rb +36 -0
  11. data/app/views/foreman_tasks/api/tasks/details.json.rabl +0 -1
  12. data/app/views/foreman_tasks/api/tasks/show.json.rabl +2 -0
  13. data/config/routes.rb +1 -0
  14. data/db/migrate/20200517215015_rename_bookmarks_controller.rb +35 -0
  15. data/db/migrate/20200519093217_drop_dynflow_allow_dangerous_actions_setting.foreman_tasks.rb +5 -0
  16. data/db/migrate/20200611090846_add_task_lock_index_on_resource_type_and_task_id.rb +3 -3
  17. data/db/seeds.d/30-notification_blueprints.rb +7 -0
  18. data/lib/foreman_tasks/engine.rb +2 -7
  19. data/lib/foreman_tasks/version.rb +1 -1
  20. data/locale/action_names.rb +1 -1
  21. data/locale/en/LC_MESSAGES/foreman_tasks.mo +0 -0
  22. data/locale/en/foreman_tasks.po +270 -54
  23. data/locale/foreman_tasks.pot +630 -292
  24. data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
  25. data/locale/fr/foreman_tasks.po +817 -0
  26. data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
  27. data/locale/ja/foreman_tasks.po +817 -0
  28. data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
  29. data/locale/zh_CN/foreman_tasks.po +816 -0
  30. data/package.json +1 -0
  31. data/script/npm_link_foreman_js.sh +26 -0
  32. data/webpack/ForemanTasks/Components/TaskActions/TaskAction.test.js +60 -0
  33. data/webpack/ForemanTasks/Components/{TasksTable/TasksTableActionHelpers.js → TaskActions/TaskActionHelpers.js} +21 -6
  34. data/webpack/ForemanTasks/Components/{TasksTable/__tests__/TasksTableActionHelpers.test.js → TaskActions/TaskActionHelpers.test.js} +2 -2
  35. data/webpack/ForemanTasks/Components/TaskActions/TaskActionsConstants.js +16 -0
  36. data/webpack/ForemanTasks/Components/TaskActions/UnlockModals.js +60 -0
  37. data/webpack/ForemanTasks/Components/TaskActions/UnlockModals.test.js +14 -0
  38. data/webpack/ForemanTasks/Components/TaskActions/__snapshots__/TaskAction.test.js.snap +233 -0
  39. data/webpack/ForemanTasks/Components/TaskActions/__snapshots__/UnlockModals.test.js.snap +25 -0
  40. data/webpack/ForemanTasks/Components/TaskActions/index.js +115 -0
  41. data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +17 -3
  42. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +149 -167
  43. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +8 -1
  44. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +68 -3
  45. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskInfo.test.js +0 -1
  46. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/RunningSteps.test.js.snap +1 -1
  47. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +124 -76
  48. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +35 -5
  49. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +3 -14
  50. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +40 -16
  51. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +3 -4
  52. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +0 -6
  53. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +4 -10
  54. data/webpack/ForemanTasks/Components/TaskDetails/TasksDetailsHelper.js +6 -1
  55. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.fixtures.js +8 -0
  56. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +7 -1
  57. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +18 -2
  58. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +30 -13
  59. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +91 -0
  60. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +13 -4
  61. data/webpack/ForemanTasks/Components/TaskDetails/index.js +6 -8
  62. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardActions.js +1 -1
  63. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardActions.test.js +2 -2
  64. data/webpack/ForemanTasks/Components/TasksTable/Components/ActionSelectButton.js +14 -1
  65. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModal.js +83 -0
  66. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalActions.js +106 -0
  67. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalReducer.js +38 -0
  68. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalSelectors.js +46 -0
  69. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModal.test.js +36 -0
  70. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalActions.test.js +205 -0
  71. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalReducer.test.js +27 -0
  72. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalSelectors.test.js +55 -0
  73. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModal.test.js.snap +41 -0
  74. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalReducer.test.js.snap +19 -0
  75. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalSelectors.test.js.snap +32 -0
  76. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/index.js +29 -0
  77. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ActionSelectButton.test.js +1 -0
  78. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ActionSelectButton.test.js.snap +11 -0
  79. data/webpack/ForemanTasks/Components/TasksTable/TasksBulkActions.js +135 -35
  80. data/webpack/ForemanTasks/Components/TasksTable/TasksTable.js +13 -9
  81. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +26 -66
  82. data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +10 -12
  83. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +30 -96
  84. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSchema.js +2 -2
  85. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +8 -4
  86. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksBulkActions.test.js +50 -2
  87. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +3 -12
  88. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableActions.test.js +22 -26
  89. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTablePage.test.js +2 -1
  90. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +3 -14
  91. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksBulkActions.test.js.snap +155 -0
  92. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +3 -14
  93. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableActions.test.js.snap +17 -124
  94. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +63 -133
  95. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionCellFormatter.test.js.snap +1 -0
  96. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/selectionCellFormatter.test.js.snap +2 -0
  97. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/actionCellFormatter.test.js +1 -1
  98. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionCellFormatter.test.js +1 -1
  99. data/webpack/ForemanTasks/Components/TasksTable/formatters/actionCellFormatter.js +10 -7
  100. data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionCellFormatter.js +7 -0
  101. data/webpack/ForemanTasks/Components/TasksTable/index.js +2 -2
  102. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.js +55 -19
  103. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.test.js +75 -19
  104. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ActionButton.test.js.snap +88 -21
  105. data/webpack/ForemanTasks/Components/common/ClickConfirmation/ClickConfirmation.scss +9 -0
  106. data/webpack/ForemanTasks/Components/common/ClickConfirmation/ClickConfirmation.test.js +44 -0
  107. data/webpack/ForemanTasks/Components/common/ClickConfirmation/__snapshots__/ClickConfirmation.test.js.snap +52 -0
  108. data/webpack/ForemanTasks/Components/common/ClickConfirmation/index.js +59 -66
  109. data/webpack/ForemanTasks/Components/common/{ToastTypesConstants.js → ToastsHelpers/ToastTypesConstants.js} +0 -0
  110. data/webpack/ForemanTasks/Components/common/ToastsHelpers/index.js +15 -0
  111. data/webpack/ForemanTasks/ForemanTasksReducers.js +2 -0
  112. data/webpack/ForemanTasks/Routes/ForemanTasksRoutes.test.js +2 -1
  113. data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalHooks.js +2 -2
  114. data/webpack/__mocks__/foremanReact/components/ForemanModal/index.js +17 -3
  115. data/webpack/__mocks__/foremanReact/components/common/ActionButtons/ActionButtons.js +3 -0
  116. data/webpack/__mocks__/foremanReact/{API.js → redux/API.js} +1 -1
  117. metadata +41 -21
  118. data/webpack/ForemanTasks/Components/TasksTable/Components/CancelConfirm.js +0 -53
  119. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmationModals.js +0 -56
  120. data/webpack/ForemanTasks/Components/TasksTable/Components/ResumeConfirm.js +0 -52
  121. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/CancelConfirm.test.js +0 -26
  122. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ConfirmationModals.test.js +0 -24
  123. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ResumeConfirm.test.js +0 -26
  124. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/CancelConfirm.test.js.snap +0 -65
  125. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ConfirmationModals.test.js.snap +0 -30
  126. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ResumeConfirm.test.js.snap +0 -63
  127. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.js +0 -23
  128. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.test.js +0 -26
  129. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.js +0 -23
  130. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.test.js +0 -27
  131. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/CancelButton.test.js.snap +0 -15
  132. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ResumeButton.test.js.snap +0 -15
@@ -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 || '';