foreman-tasks 12.0.0 → 12.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby_tests.yml +1 -0
  3. data/app/assets/javascripts/foreman-tasks/locale/de/foreman_tasks.js +58 -22
  4. data/app/assets/javascripts/foreman-tasks/locale/en/foreman_tasks.js +56 -20
  5. data/app/assets/javascripts/foreman-tasks/locale/es/foreman_tasks.js +59 -23
  6. data/app/assets/javascripts/foreman-tasks/locale/fr/foreman_tasks.js +61 -25
  7. data/app/assets/javascripts/foreman-tasks/locale/ja/foreman_tasks.js +61 -25
  8. data/app/assets/javascripts/foreman-tasks/locale/ka/foreman_tasks.js +60 -24
  9. data/app/assets/javascripts/foreman-tasks/locale/ko/foreman_tasks.js +61 -25
  10. data/app/assets/javascripts/foreman-tasks/locale/pt_BR/foreman_tasks.js +59 -23
  11. data/app/assets/javascripts/foreman-tasks/locale/ru/foreman_tasks.js +58 -22
  12. data/app/assets/javascripts/foreman-tasks/locale/zh_CN/foreman_tasks.js +61 -25
  13. data/app/assets/javascripts/foreman-tasks/locale/zh_TW/foreman_tasks.js +57 -21
  14. data/app/controllers/foreman_tasks/api/tasks_controller.rb +4 -19
  15. data/app/controllers/foreman_tasks/tasks_controller.rb +4 -5
  16. data/app/models/foreman_tasks/task.rb +1 -1
  17. data/app/views/foreman_tasks/api/tasks/dependency_summary.json.rabl +1 -3
  18. data/app/views/foreman_tasks/api/tasks/show.json.rabl +4 -1
  19. data/config/routes.rb +3 -3
  20. data/foreman-tasks.gemspec +3 -1
  21. data/lib/foreman_tasks/engine.rb +1 -1
  22. data/lib/foreman_tasks/tasks/export_tasks.rake +1 -1
  23. data/lib/foreman_tasks/version.rb +1 -1
  24. data/locale/de/LC_MESSAGES/foreman_tasks.mo +0 -0
  25. data/locale/de/foreman_tasks.po +59 -23
  26. data/locale/en/LC_MESSAGES/foreman_tasks.mo +0 -0
  27. data/locale/en/foreman_tasks.po +56 -20
  28. data/locale/es/LC_MESSAGES/foreman_tasks.mo +0 -0
  29. data/locale/es/foreman_tasks.po +59 -23
  30. data/locale/foreman_tasks.pot +173 -100
  31. data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
  32. data/locale/fr/foreman_tasks.po +61 -25
  33. data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
  34. data/locale/ja/foreman_tasks.po +61 -25
  35. data/locale/ka/LC_MESSAGES/foreman_tasks.mo +0 -0
  36. data/locale/ka/foreman_tasks.po +60 -24
  37. data/locale/ko/LC_MESSAGES/foreman_tasks.mo +0 -0
  38. data/locale/ko/foreman_tasks.po +61 -25
  39. data/locale/pt_BR/LC_MESSAGES/foreman_tasks.mo +0 -0
  40. data/locale/pt_BR/foreman_tasks.po +59 -23
  41. data/locale/ru/LC_MESSAGES/foreman_tasks.mo +0 -0
  42. data/locale/ru/foreman_tasks.po +58 -22
  43. data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
  44. data/locale/zh_CN/foreman_tasks.po +61 -25
  45. data/locale/zh_TW/LC_MESSAGES/foreman_tasks.mo +0 -0
  46. data/locale/zh_TW/foreman_tasks.po +57 -21
  47. data/test/controllers/api/tasks_controller_test.rb +29 -3
  48. data/test/controllers/tasks_controller_test.rb +46 -2
  49. data/webpack/ForemanTasks/Components/TaskActions/TaskAction.test.js +8 -0
  50. data/webpack/ForemanTasks/Components/TaskActions/TaskActionHelpers.js +8 -2
  51. data/webpack/ForemanTasks/Components/TaskActions/TaskActionHelpers.test.js +25 -33
  52. data/webpack/ForemanTasks/Components/TaskActions/index.js +24 -3
  53. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +6 -6
  54. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +9 -0
  55. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +16 -11
  56. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/TasksTimeRow.js +2 -3
  57. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksTimeRow/__snapshots__/TasksTimeRow.test.js.snap +4 -8
  58. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboard.js +2 -4
  59. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboard.scss +0 -3
  60. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboard.test.js.snap +2 -5
  61. data/webpack/ForemanTasks/Components/{common/ActionButtons/ActionButton.js → TasksTable/Components/CellActionButton.js} +36 -21
  62. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/index.test.js +32 -29
  63. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/createBulkTaskModal.js +14 -18
  64. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/createTaskModal.js +13 -15
  65. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/index.js +7 -7
  66. data/webpack/ForemanTasks/Components/TasksTable/TasksBulkActions.js +16 -23
  67. data/webpack/ForemanTasks/Components/TasksTable/TasksColumns.js +56 -0
  68. data/webpack/ForemanTasks/Components/TasksTable/TasksIndexPage.js +277 -3
  69. data/webpack/ForemanTasks/Components/TasksTable/TasksModals.js +96 -0
  70. data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +10 -18
  71. data/webpack/ForemanTasks/Components/TasksTable/TasksTableHelpers.js +3 -3
  72. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksBulkActions.test.js +130 -63
  73. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksIndexPage.test.js +315 -8
  74. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +214 -41
  75. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableHelpers.test.js +20 -12
  76. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksBulkActions.test.js.snap +18 -35
  77. data/webpack/ForemanTasks/ForemanTasksReducers.js +0 -4
  78. data/webpack/Routes/routes.js +22 -0
  79. data/webpack/Routes/routes.test.js +95 -0
  80. data/webpack/global_index.js +10 -0
  81. data/webpack/index.js +0 -18
  82. data/webpack/test_setup.js +1 -0
  83. metadata +15 -89
  84. data/app/controllers/foreman_tasks/react_controller.rb +0 -17
  85. data/app/views/foreman_tasks/layouts/react.html.erb +0 -13
  86. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalSelectors.js +0 -30
  87. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalSelectors.test.js +0 -66
  88. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalSelectors.test.js.snap +0 -33
  89. data/webpack/ForemanTasks/Components/TasksTable/Components/SelectAllAlert.js +0 -49
  90. data/webpack/ForemanTasks/Components/TasksTable/Components/TableSelectionCell.js +0 -32
  91. data/webpack/ForemanTasks/Components/TasksTable/Components/TableSelectionHeaderCell.js +0 -38
  92. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/SelectAllAlert.test.js +0 -29
  93. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/TableSelectionCell.test.js +0 -15
  94. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/TableSelectionHeaderCell.test.js +0 -15
  95. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/SelectAllAlert.test.js.snap +0 -81
  96. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/TableSelectionCell.test.js.snap +0 -14
  97. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/TableSelectionHeaderCell.test.js.snap +0 -15
  98. data/webpack/ForemanTasks/Components/TasksTable/SubTasksPage.js +0 -40
  99. data/webpack/ForemanTasks/Components/TasksTable/TasksTable.js +0 -163
  100. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +0 -108
  101. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +0 -234
  102. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.scss +0 -20
  103. data/webpack/ForemanTasks/Components/TasksTable/TasksTableReducer.js +0 -68
  104. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSchema.js +0 -85
  105. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +0 -63
  106. data/webpack/ForemanTasks/Components/TasksTable/__tests__/SubTasksPage.test.js +0 -20
  107. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.test.js +0 -9
  108. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableActions.test.js +0 -65
  109. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTablePage.test.js +0 -35
  110. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableReducer.test.js +0 -87
  111. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +0 -48
  112. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +0 -39
  113. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTable.test.js.snap +0 -52
  114. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableActions.test.js.snap +0 -40
  115. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +0 -368
  116. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableReducer.test.js.snap +0 -116
  117. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionCellFormatter.test.js.snap +0 -15
  118. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionNameCellFormatter.test.js.snap +0 -10
  119. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/dateCellFormmatter.test.js.snap +0 -9
  120. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/durationCellFormmatter.test.js.snap +0 -18
  121. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/selectionCellFormatter.test.js.snap +0 -12
  122. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/selectionHeaderCellFormatter.test.js.snap +0 -11
  123. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/actionCellFormatter.test.js +0 -11
  124. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/actionNameCellFormatter.test.js +0 -8
  125. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/dateCellFormmatter.test.js +0 -7
  126. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/durationCellFormmatter.test.js +0 -12
  127. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionCellFormatter.test.js +0 -12
  128. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionHeaderCellFormatter.test.js +0 -12
  129. data/webpack/ForemanTasks/Components/TasksTable/formatters/actionCellFormatter.js +0 -19
  130. data/webpack/ForemanTasks/Components/TasksTable/formatters/actionNameCellFormatter.js +0 -9
  131. data/webpack/ForemanTasks/Components/TasksTable/formatters/dateCellFormmatter.js +0 -7
  132. data/webpack/ForemanTasks/Components/TasksTable/formatters/durationCellFormmatter.js +0 -7
  133. data/webpack/ForemanTasks/Components/TasksTable/formatters/index.js +0 -7
  134. data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionCellFormatter.js +0 -17
  135. data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionHeaderCellFormatter.js +0 -11
  136. data/webpack/ForemanTasks/Components/TasksTable/index.js +0 -42
  137. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.test.js +0 -101
  138. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ActionButton.test.js.snap +0 -95
  139. data/webpack/ForemanTasks/ForemanTasks.js +0 -11
  140. data/webpack/ForemanTasks/ForemanTasks.test.js +0 -10
  141. data/webpack/ForemanTasks/Routes/ForemanTasksRouter.js +0 -14
  142. data/webpack/ForemanTasks/Routes/ForemanTasksRouter.test.js +0 -26
  143. data/webpack/ForemanTasks/Routes/ForemanTasksRoutes.js +0 -23
  144. data/webpack/ForemanTasks/Routes/ForemanTasksRoutes.test.js +0 -16
  145. data/webpack/ForemanTasks/Routes/__snapshots__/ForemanTasksRouter.test.js.snap +0 -16
  146. data/webpack/ForemanTasks/Routes/__snapshots__/ForemanTasksRoutes.test.js.snap +0 -37
  147. data/webpack/ForemanTasks/__snapshots__/ForemanTasks.test.js.snap +0 -7
  148. data/webpack/ForemanTasks/index.js +0 -1
  149. data/webpack/__mocks__/foremanReact/common/I18n.js +0 -7
  150. data/webpack/__mocks__/foremanReact/common/helpers.js +0 -6
  151. data/webpack/__mocks__/foremanReact/common/urlHelpers.js +0 -1
  152. data/webpack/__mocks__/foremanReact/components/Layout/LayoutActions.js +0 -2
  153. data/webpack/__mocks__/foremanReact/components/Pagination/index.js +0 -2
  154. data/webpack/__mocks__/foremanReact/components/ToastsList/index.js +0 -8
  155. data/webpack/__mocks__/foremanReact/components/common/ActionButtons/ActionButtons.js +0 -3
  156. data/webpack/__mocks__/foremanReact/components/common/MessageBox.js +0 -4
  157. data/webpack/__mocks__/foremanReact/components/common/dates/LongDateTime.js +0 -5
  158. data/webpack/__mocks__/foremanReact/components/common/dates/RelativeDateTime.js +0 -3
  159. data/webpack/__mocks__/foremanReact/components/common/table/actionsHelpers/actionTypeCreator.js +0 -7
  160. data/webpack/__mocks__/foremanReact/components/common/table.js +0 -5
  161. data/webpack/__mocks__/foremanReact/constants.js +0 -24
  162. data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +0 -10
  163. data/webpack/__mocks__/foremanReact/redux/API/index.js +0 -10
  164. data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware.js +0 -5
  165. data/webpack/__mocks__/foremanReact/routes/common/PageLayout/PageLayout.js +0 -10
  166. data/webpack/__mocks__/foremanReact/routes/common/PageLayout/components/ExportButton/ExportButton.js +0 -5
@@ -17,9 +17,7 @@ import {
17
17
  TASKS_FORCE_CANCEL_SUCCESS,
18
18
  TASKS_FORCE_CANCEL_FAILURE,
19
19
  } from '../TaskActions/TaskActionsConstants';
20
- import { reloadPage } from './TasksTableActions';
21
20
  import {
22
- convertDashboardQuery,
23
21
  resumeToastInfo,
24
22
  cancelToastInfo,
25
23
  toastDispatch,
@@ -41,11 +39,11 @@ export const bulkByIdRequest = (resumeTasks, path) => {
41
39
  export const bulkBySearchRequest = ({ query, parentTaskID, path }) => {
42
40
  const url = `/foreman_tasks/api/tasks/${path}`;
43
41
  if (parentTaskID) {
44
- query.search = query.search
45
- ? ` ${query.search} and parent_task_id=${parentTaskID}`
42
+ query = query
43
+ ? ` ${query} and parent_task_id=${parentTaskID}`
46
44
  : `parent_task_id=${parentTaskID}`;
47
45
  }
48
- const searchParam = { search: convertDashboardQuery(query) };
46
+ const searchParam = { search: query };
49
47
  return API.post(url, searchParam);
50
48
  };
51
49
 
@@ -58,12 +56,11 @@ const handleErrorResume = (error, dispatch) => {
58
56
  );
59
57
  };
60
58
 
61
- export const bulkResumeById = ({
62
- selected,
63
- url,
64
- parentTaskID,
65
- }) => async dispatch => {
66
- const resumeTasks = selected.filter(task => task.isResumable && task.canEdit);
59
+ export const bulkResumeById = ({ selected, reloadPage }) => async dispatch => {
60
+ const resumeTasks = selected.filter(
61
+ // eslint-disable-next-line camelcase
62
+ task => task?.available_actions?.resumable && task.can_edit
63
+ );
67
64
  if (resumeTasks.length < selected.length)
68
65
  dispatch(
69
66
  addToast(
@@ -87,7 +84,7 @@ export const bulkResumeById = ({
87
84
  });
88
85
  });
89
86
  if (data.resumed) {
90
- reloadPage(url, parentTaskID)(dispatch);
87
+ reloadPage();
91
88
  }
92
89
  } catch (error) {
93
90
  handleErrorResume(error, dispatch);
@@ -130,13 +127,10 @@ export const bulkCancelBySearch = ({
130
127
  await bulkBySearchRequest({ query, path: BULK_CANCEL_PATH, parentTaskID });
131
128
  };
132
129
 
133
- export const bulkCancelById = ({
134
- selected,
135
- url,
136
- parentTaskID,
137
- }) => async dispatch => {
130
+ export const bulkCancelById = ({ selected, reloadPage }) => async dispatch => {
138
131
  const cancelTasks = selected.filter(
139
- task => task.isCancellable && task.canEdit
132
+ // eslint-disable-next-line camelcase
133
+ task => task?.available_actions?.cancellable && task.can_edit
140
134
  );
141
135
  if (cancelTasks.length < selected.length)
142
136
  dispatch(
@@ -162,7 +156,7 @@ export const bulkCancelById = ({
162
156
  });
163
157
  });
164
158
  if (data.cancelled) {
165
- reloadPage(url, parentTaskID)(dispatch);
159
+ reloadPage();
166
160
  }
167
161
  } catch (error) {
168
162
  handleErrorCancel(error, dispatch);
@@ -183,11 +177,10 @@ const handleErrorForceCancel = (error, dispatch) => {
183
177
 
184
178
  export const bulkForceCancelById = ({
185
179
  selected,
186
- url,
187
- parentTaskID,
180
+ reloadPage,
188
181
  }) => async dispatch => {
189
182
  const stopTasks = selected.filter(task => task.state !== 'stopped');
190
- const authorisedTasks = stopTasks.filter(task => task.canEdit);
183
+ const authorisedTasks = stopTasks.filter(task => task.can_edit);
191
184
  if (authorisedTasks.length < stopTasks.length)
192
185
  dispatch(
193
186
  addToast(
@@ -236,7 +229,7 @@ export const bulkForceCancelById = ({
236
229
  )
237
230
  );
238
231
  if (data.stopped_length > 0) {
239
- reloadPage(url, parentTaskID)(dispatch);
232
+ reloadPage();
240
233
  }
241
234
  } catch (error) {
242
235
  handleErrorForceCancel(error, dispatch);
@@ -0,0 +1,56 @@
1
+ import React from 'react';
2
+ import LongDateTime from 'foremanReact/components/common/dates/LongDateTime';
3
+ import { translate as __ } from 'foremanReact/common/I18n';
4
+ import { getDuration } from './TasksTableHelpers';
5
+ import { CellActionButton } from './Components/CellActionButton';
6
+
7
+ export const columns = (setClickedTask, openModal, canEdit) => ({
8
+ select: {},
9
+ action: {
10
+ title: __('Action'),
11
+ wrapper: ({ id, action }) => (
12
+ <a href={`/foreman_tasks/tasks/${id}`}>{action}</a>
13
+ ),
14
+ },
15
+ state: {
16
+ title: __('State'),
17
+ },
18
+ result: {
19
+ title: __('Result'),
20
+ },
21
+ started_at: {
22
+ title: __('Started at'),
23
+ isSorted: true,
24
+ wrapper: ({ started_at: startedAt }) => (
25
+ <LongDateTime seconds date={startedAt} defaultValue={__('N/A')} />
26
+ ),
27
+ },
28
+ duration: {
29
+ title: __('Duration'),
30
+ isSorted: true,
31
+ wrapper: ({ started_at: startedAt, ended_at: endedAt }) => {
32
+ const duration = getDuration(startedAt, endedAt);
33
+ return (
34
+ <span className="param-value" title={duration.tooltip}>
35
+ {duration.text}
36
+ </span>
37
+ );
38
+ },
39
+ },
40
+ action_button: {
41
+ title: __('Action'),
42
+ wrapper: ({ id, action, available_actions: availableActions, state }) => (
43
+ <CellActionButton
44
+ id={id}
45
+ action={action}
46
+ canEdit={canEdit}
47
+ availableActions={availableActions}
48
+ cancellable={availableActions.cancellable}
49
+ resumable={availableActions.resumable}
50
+ stoppable={state !== 'stopped'}
51
+ setClickedTask={setClickedTask}
52
+ openModal={openModal}
53
+ />
54
+ ),
55
+ },
56
+ });
@@ -1,4 +1,278 @@
1
- import React from 'react';
2
- import TasksTablePage from './';
1
+ import React, { useState, useCallback, useMemo } from 'react';
2
+ import { useDispatch } from 'react-redux';
3
+ import PropTypes from 'prop-types';
4
+ import URI from 'urijs';
5
+ import {
6
+ Toolbar,
7
+ ToolbarContent,
8
+ ToolbarGroup,
9
+ ToolbarItem,
10
+ Button,
11
+ Spinner,
12
+ PageSection,
13
+ } from '@patternfly/react-core';
14
+ import { RedoIcon } from '@patternfly/react-icons';
3
15
 
4
- export const TasksIndexPage = props => <TasksTablePage {...props} />;
16
+ import SelectAllCheckbox from 'foremanReact/components/PF4/TableIndexPage/Table/SelectAllCheckbox';
17
+ import TableIndexPage from 'foremanReact/components/PF4/TableIndexPage/TableIndexPage';
18
+ import { STATUS } from 'foremanReact/constants';
19
+ import { useBulkSelect } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
20
+ import { getPageStats } from 'foremanReact/components/PF4/TableIndexPage/Table/helpers';
21
+ import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
22
+ import { translate as __ } from 'foremanReact/common/I18n';
23
+ import { useForemanPermissions } from 'foremanReact/Root/Context/ForemanContext';
24
+ import { getURIQuery } from 'foremanReact/common/helpers';
25
+
26
+ import { getCSVurl, getApiPathname } from './TasksTableHelpers';
27
+ import { convertDashboardQuery } from '../TaskActions/TaskActionHelpers';
28
+ import {
29
+ TASKS_API_KEY,
30
+ CANCEL_MODAL,
31
+ RESUME_MODAL,
32
+ FORCE_UNLOCK_MODAL,
33
+ CANCEL_SELECTED_MODAL,
34
+ RESUME_SELECTED_MODAL,
35
+ FORCE_UNLOCK_SELECTED_MODAL,
36
+ TASKS_SEARCH_PROPS,
37
+ } from './TasksTableConstants';
38
+ import { columns } from './TasksColumns';
39
+ import TasksModals from './TasksModals';
40
+ import { ActionSelectButton } from './Components/ActionSelectButton';
41
+ import { fetchTasksSummary } from '../TasksDashboard/TasksDashboardActions';
42
+ import TasksDashboard from '../TasksDashboard';
43
+
44
+ const TasksTableIndexPage = ({ match, history }) => {
45
+ const parentTaskID = match.params.id;
46
+ const dispatch = useDispatch();
47
+ const url = window.location.pathname + window.location.search;
48
+ const uriQueryObject = getURIQuery(url);
49
+ const apiUrl = useMemo(() => {
50
+ const urlWithSearch = new URI(getApiPathname(url));
51
+ urlWithSearch.addSearch({
52
+ ...convertDashboardQuery(),
53
+ include_permissions: true,
54
+ });
55
+ return urlWithSearch.toString();
56
+ // convertDashboardQuery uses the url to get the query parameters, so we need to recompute it when the url changes
57
+ // eslint-disable-next-line react-hooks/exhaustive-deps
58
+ }, [url]);
59
+ const apiResponse = useAPI('get', apiUrl, {
60
+ key: TASKS_API_KEY,
61
+ });
62
+
63
+ const { status, setAPIOptions } = apiResponse;
64
+ const overrideSetAPIOptions = useCallback(
65
+ newParams => {
66
+ const { search, ...rest } = newParams;
67
+ const newUrl = new URI(url);
68
+ newUrl.addSearch({ search });
69
+ setAPIOptions({
70
+ params: {
71
+ url: newUrl.toString(),
72
+ ...rest,
73
+ },
74
+ });
75
+ },
76
+ [setAPIOptions, url]
77
+ );
78
+
79
+ const userPermissions = useForemanPermissions();
80
+ const canEdit = userPermissions.has('edit_foreman_tasks');
81
+ const [modalStates, setModalStates] = useState({
82
+ [CANCEL_MODAL]: false,
83
+ [RESUME_MODAL]: false,
84
+ [FORCE_UNLOCK_MODAL]: false,
85
+ [CANCEL_SELECTED_MODAL]: false,
86
+ [RESUME_SELECTED_MODAL]: false,
87
+ [FORCE_UNLOCK_SELECTED_MODAL]: false,
88
+ });
89
+ const openModal = id => {
90
+ setModalStates(prev => ({
91
+ ...prev,
92
+ [id]: true,
93
+ }));
94
+ };
95
+ const closeModal = id => {
96
+ setModalStates(prev => ({
97
+ ...prev,
98
+ [id]: false,
99
+ }));
100
+ };
101
+ const [clickedTask, setClickedTask] = useState(null);
102
+ const {
103
+ search: apiSearchQuery,
104
+ results,
105
+ total,
106
+ per_page: perPage,
107
+ page,
108
+ subtotal,
109
+ } = apiResponse.response;
110
+
111
+ const reloadPage = useCallback(() => {
112
+ setAPIOptions({
113
+ params: {
114
+ page,
115
+ per_page: perPage,
116
+ search: convertDashboardQuery().search,
117
+ },
118
+ });
119
+
120
+ dispatch(fetchTasksSummary(uriQueryObject.time, parentTaskID));
121
+ }, [
122
+ setAPIOptions,
123
+ page,
124
+ perPage,
125
+ uriQueryObject.time,
126
+ dispatch,
127
+ parentTaskID,
128
+ ]);
129
+ const { pageRowCount } = getPageStats({ total, page, perPage });
130
+
131
+ const {
132
+ fetchBulkParams,
133
+ searchQuery,
134
+ updateSearchQuery,
135
+ ...selectAllOptions
136
+ } = useBulkSelect({
137
+ results,
138
+ metadata: { total, page, selectable: subtotal },
139
+ initialSearchQuery: apiSearchQuery,
140
+ });
141
+
142
+ const {
143
+ selectAll,
144
+ selectPage,
145
+ selectNone,
146
+ selectedCount,
147
+ selectOne,
148
+ areAllRowsOnPageSelected,
149
+ areAllRowsSelected,
150
+ isSelected,
151
+ } = selectAllOptions;
152
+
153
+ const customToolbarItems = (
154
+ <Toolbar ouiaId="tasks-table-toolbar">
155
+ <ToolbarContent>
156
+ <ToolbarGroup align={{ default: 'alignRight' }}>
157
+ <ToolbarItem>
158
+ <Button
159
+ ouiaId="tasks-table-refresh-data"
160
+ variant="primary"
161
+ onClick={reloadPage}
162
+ icon={<RedoIcon />}
163
+ >
164
+ {__('Refresh Data')}
165
+ </Button>
166
+ </ToolbarItem>
167
+ {status === STATUS.PENDING && <Spinner size="lg" />}
168
+ <ToolbarItem>
169
+ <Button
170
+ ouiaId="tasks-table-export-all"
171
+ variant="secondary"
172
+ component="a"
173
+ href={getCSVurl()}
174
+ >
175
+ {__('Export All')}
176
+ </Button>
177
+ </ToolbarItem>
178
+ </ToolbarGroup>
179
+ </ToolbarContent>
180
+ </Toolbar>
181
+ );
182
+ const selectionToolbar = (
183
+ <ToolbarItem key="selectAll">
184
+ <SelectAllCheckbox
185
+ {...{
186
+ selectAll,
187
+ selectPage,
188
+ selectNone,
189
+ selectedCount,
190
+ pageRowCount,
191
+ }}
192
+ totalCount={total}
193
+ areAllRowsOnPageSelected={areAllRowsOnPageSelected()}
194
+ areAllRowsSelected={areAllRowsSelected()}
195
+ />
196
+ </ToolbarItem>
197
+ );
198
+ return (
199
+ <>
200
+ <TasksModals
201
+ taskId={clickedTask?.id}
202
+ taskName={clickedTask?.action}
203
+ modalStates={modalStates}
204
+ closeModal={closeModal}
205
+ parentTaskID={parentTaskID}
206
+ uriQuery={apiSearchQuery}
207
+ selectAllOptions={selectAllOptions}
208
+ reloadPage={reloadPage}
209
+ />
210
+ <TableIndexPage
211
+ breadcrumbOptions={
212
+ parentTaskID
213
+ ? {
214
+ breadcrumbItems: [
215
+ { caption: __('Tasks'), url: `/foreman_tasks/tasks` },
216
+ { caption: __('Sub tasks') },
217
+ ],
218
+ }
219
+ : null
220
+ }
221
+ header={parentTaskID ? __('Sub tasks') : __('Tasks')}
222
+ beforeToolbarComponent={
223
+ <>
224
+ <PageSection className="tasks-dashboard-section">
225
+ <TasksDashboard history={history} parentTaskID={parentTaskID} />
226
+ </PageSection>
227
+ {customToolbarItems}
228
+ </>
229
+ }
230
+ apiUrl=""
231
+ apiOptions={{ key: TASKS_API_KEY }}
232
+ controller="foreman_tasks/tasks"
233
+ customSearchProps={TASKS_SEARCH_PROPS}
234
+ columns={columns(setClickedTask, openModal, canEdit)}
235
+ creatable={false}
236
+ showCheckboxes
237
+ selectOne={selectOne}
238
+ selectPage={selectPage}
239
+ selectNone={selectNone}
240
+ selectedCount={selectedCount}
241
+ areAllRowsSelected={areAllRowsSelected}
242
+ isSelected={isSelected}
243
+ selectionToolbar={selectionToolbar}
244
+ customToolbarItems={
245
+ <ToolbarItem>
246
+ <ActionSelectButton
247
+ disabled={!canEdit || !(selectedCount || areAllRowsSelected())}
248
+ onCancel={() => openModal(CANCEL_SELECTED_MODAL)}
249
+ onResume={() => openModal(RESUME_SELECTED_MODAL)}
250
+ onForceCancel={() => openModal(FORCE_UNLOCK_SELECTED_MODAL)}
251
+ />
252
+ </ToolbarItem>
253
+ }
254
+ replacementResponse={{
255
+ ...apiResponse,
256
+ setAPIOptions: overrideSetAPIOptions,
257
+ }}
258
+ />
259
+ </>
260
+ );
261
+ };
262
+
263
+ TasksTableIndexPage.propTypes = {
264
+ match: PropTypes.shape({
265
+ params: PropTypes.shape({
266
+ id: PropTypes.string,
267
+ }),
268
+ }),
269
+ history: PropTypes.object.isRequired,
270
+ };
271
+
272
+ TasksTableIndexPage.defaultProps = {
273
+ match: {
274
+ params: { id: null },
275
+ },
276
+ };
277
+
278
+ export default TasksTableIndexPage;
@@ -0,0 +1,96 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import {
4
+ CANCEL_MODAL,
5
+ RESUME_MODAL,
6
+ FORCE_UNLOCK_MODAL,
7
+ CANCEL_SELECTED_MODAL,
8
+ RESUME_SELECTED_MODAL,
9
+ FORCE_UNLOCK_SELECTED_MODAL,
10
+ } from './TasksTableConstants';
11
+ import {
12
+ CancelModal,
13
+ ResumeModal,
14
+ ForceUnlockModal,
15
+ CancelSelectedModal,
16
+ ResumeSelectedModal,
17
+ ForceUnlockSelectedModal,
18
+ } from './Components/ConfirmModal';
19
+
20
+ const TasksModals = ({
21
+ taskId,
22
+ taskName,
23
+ modalStates,
24
+ closeModal,
25
+ parentTaskID,
26
+ selectAllOptions,
27
+ uriQuery,
28
+ reloadPage,
29
+ }) => (
30
+ <>
31
+ <CancelModal
32
+ reloadPage={reloadPage}
33
+ isModalOpen={modalStates[CANCEL_MODAL]}
34
+ setIsModalOpen={() => closeModal(CANCEL_MODAL)}
35
+ taskId={taskId}
36
+ taskName={taskName}
37
+ />
38
+ <ResumeModal
39
+ reloadPage={reloadPage}
40
+ isModalOpen={modalStates[RESUME_MODAL]}
41
+ setIsModalOpen={() => closeModal(RESUME_MODAL)}
42
+ taskId={taskId}
43
+ taskName={taskName}
44
+ />
45
+ <ForceUnlockModal
46
+ reloadPage={reloadPage}
47
+ isModalOpen={modalStates[FORCE_UNLOCK_MODAL]}
48
+ setIsModalOpen={() => closeModal(FORCE_UNLOCK_MODAL)}
49
+ taskId={taskId}
50
+ taskName={taskName}
51
+ />
52
+ <CancelSelectedModal
53
+ reloadPage={reloadPage}
54
+ isModalOpen={modalStates[CANCEL_SELECTED_MODAL]}
55
+ setIsModalOpen={() => closeModal(CANCEL_SELECTED_MODAL)}
56
+ uriQuery={uriQuery}
57
+ selectAllOptions={selectAllOptions}
58
+ />
59
+ <ResumeSelectedModal
60
+ reloadPage={reloadPage}
61
+ isModalOpen={modalStates[RESUME_SELECTED_MODAL]}
62
+ setIsModalOpen={() => closeModal(RESUME_SELECTED_MODAL)}
63
+ uriQuery={uriQuery}
64
+ parentTaskID={parentTaskID}
65
+ selectAllOptions={selectAllOptions}
66
+ />
67
+ <ForceUnlockSelectedModal
68
+ reloadPage={reloadPage}
69
+ isModalOpen={modalStates[FORCE_UNLOCK_SELECTED_MODAL]}
70
+ setIsModalOpen={() => closeModal(FORCE_UNLOCK_SELECTED_MODAL)}
71
+ uriQuery={uriQuery}
72
+ parentTaskID={parentTaskID}
73
+ selectAllOptions={selectAllOptions}
74
+ />
75
+ </>
76
+ );
77
+
78
+ TasksModals.propTypes = {
79
+ taskId: PropTypes.string,
80
+ taskName: PropTypes.string,
81
+ modalStates: PropTypes.object.isRequired,
82
+ closeModal: PropTypes.func.isRequired,
83
+ parentTaskID: PropTypes.string,
84
+ selectAllOptions: PropTypes.object.isRequired,
85
+ uriQuery: PropTypes.string,
86
+ reloadPage: PropTypes.func.isRequired,
87
+ };
88
+
89
+ TasksModals.defaultProps = {
90
+ taskId: null,
91
+ taskName: null,
92
+ parentTaskID: null,
93
+ uriQuery: null,
94
+ };
95
+
96
+ export default TasksModals;
@@ -1,28 +1,20 @@
1
1
  import { getControllerSearchProps } from 'foremanReact/constants';
2
2
 
3
- export const TASKS_TABLE_ID = 'TASKS_TABLE';
4
-
5
- export const SELECT_ROWS = 'SELECT_ROWS';
6
- export const UNSELECT_ROWS = 'UNSELECT_ROWS';
7
- export const UNSELECT_ALL_ROWS = 'UNSELECT_ALL_ROWS';
8
- export const SELECT_ALL_ROWS = 'SELECT_ALL_ROWS';
9
- export const OPEN_SELECT_ALL = 'OPEN_SELECT_ALL';
10
-
11
3
  export const BULK_CANCEL_PATH = 'bulk_cancel';
12
4
  export const BULK_RESUME_PATH = 'bulk_resume';
13
5
  export const BULK_FORCE_CANCEL_PATH = 'bulk_stop';
14
6
 
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 FORCE_UNLOCK_MODAL = 'forceUnlockConfirmModal';
20
- export const FORCE_UNLOCK_SELECTED_MODAL = 'forceUnlockSelectedConfirmModal';
21
-
22
- export const UPDATE_CLICKED = 'UPDATE_CLICKED';
23
- export const UPDATE_MODAL = 'UPDATE_MODAL';
24
-
25
7
  export const TASKS_SEARCH_PROPS = {
26
8
  ...getControllerSearchProps('tasks'),
27
9
  controller: 'foreman_tasks_tasks',
28
10
  };
11
+
12
+ export const TASKS_API_KEY = 'tasks_table';
13
+
14
+ export const CANCEL_MODAL = 'cancel';
15
+ export const RESUME_MODAL = 'resume';
16
+ export const FORCE_UNLOCK_MODAL = 'force_unlock';
17
+
18
+ export const CANCEL_SELECTED_MODAL = 'cancelSelectedConfirmModal';
19
+ export const RESUME_SELECTED_MODAL = 'resumeSelectedConfirmModal';
20
+ export const FORCE_UNLOCK_SELECTED_MODAL = 'forceUnlockSelectedConfirmModal';
@@ -15,10 +15,10 @@ export const getApiPathname = url => {
15
15
  return uri.pathname().replace('foreman_tasks/', 'foreman_tasks/api/');
16
16
  };
17
17
 
18
- export const getCSVurl = (path, query) => {
19
- let url = new URI(path);
18
+ export const getCSVurl = () => {
19
+ let url = new URI(window.location.pathname);
20
20
  url = url.pathname(`${url.pathname()}.csv`);
21
- url.addSearch(convertDashboardQuery(query));
21
+ url.addSearch(convertDashboardQuery());
22
22
  return url.toString();
23
23
  };
24
24