foreman-tasks 0.17.0 → 0.17.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/foreman_tasks/tasks.css.scss +3 -3
  3. data/app/controllers/foreman_tasks/api/tasks_controller.rb +50 -30
  4. data/app/controllers/foreman_tasks/tasks_controller.rb +8 -17
  5. data/app/models/foreman_tasks/task.rb +6 -4
  6. data/app/models/foreman_tasks/task/search.rb +0 -25
  7. data/app/models/setting/foreman_tasks.rb +19 -23
  8. data/app/views/foreman_tasks/api/tasks/show.json.rabl +1 -0
  9. data/app/views/foreman_tasks/layouts/react.html.erb +4 -1
  10. data/config/routes.rb +17 -3
  11. data/db/migrate/20180927120509_add_user_id.foreman_tasks.rb +4 -2
  12. data/lib/foreman_tasks/dynflow.rb +1 -1
  13. data/lib/foreman_tasks/dynflow/console_authorizer.rb +13 -2
  14. data/lib/foreman_tasks/engine.rb +1 -1
  15. data/lib/foreman_tasks/version.rb +1 -1
  16. data/package.json +1 -0
  17. data/test/controllers/tasks_controller_test.rb +35 -4
  18. data/test/unit/dynflow_console_authorizer_test.rb +1 -1
  19. data/test/unit/otp_manager_test.rb +24 -17
  20. data/test/unit/task_test.rb +48 -2
  21. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +29 -16
  22. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskHelper.js +3 -17
  23. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +18 -5
  24. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskHelper.test.js +1 -56
  25. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +24 -44
  26. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +22 -10
  27. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +6 -0
  28. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +1 -1
  29. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +2 -0
  30. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboard.js +6 -3
  31. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardActions.js +2 -3
  32. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardHelper.js +10 -41
  33. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardReducer.js +0 -1
  34. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboard.test.js +1 -1
  35. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboardReducer.test.js.snap +1 -6
  36. data/webpack/ForemanTasks/Components/TasksTable/SubTasksPage.js +30 -0
  37. data/webpack/ForemanTasks/Components/TasksTable/TaskTableFormmatters.js +53 -0
  38. data/webpack/ForemanTasks/Components/TasksTable/TasksIndexPage.js +10 -0
  39. data/webpack/ForemanTasks/Components/TasksTable/TasksTable.js +119 -0
  40. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +67 -0
  41. data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +5 -0
  42. data/webpack/ForemanTasks/Components/TasksTable/TasksTableHelpers.js +64 -0
  43. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +63 -0
  44. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.scss +29 -0
  45. data/webpack/ForemanTasks/Components/TasksTable/TasksTableReducer.js +35 -0
  46. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSchema.js +67 -0
  47. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +39 -0
  48. data/webpack/ForemanTasks/Components/TasksTable/__tests__/SubTasksPage.test.js +20 -0
  49. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksIndexPage.test.js +12 -0
  50. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +42 -0
  51. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.test.js +9 -0
  52. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableActions.test.js +48 -0
  53. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableHelpers.test.js +28 -0
  54. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTablePage.test.js +26 -0
  55. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableReducer.test.js +37 -0
  56. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +49 -0
  57. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +42 -0
  58. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTable.test.js.snap +72 -0
  59. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableActions.test.js.snap +115 -0
  60. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +194 -0
  61. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableReducer.test.js.snap +32 -0
  62. data/webpack/ForemanTasks/Components/TasksTable/index.js +32 -0
  63. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.js +39 -0
  64. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.test.js +45 -0
  65. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.js +23 -0
  66. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.test.js +27 -0
  67. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.js +23 -0
  68. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.test.js +27 -0
  69. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ActionButton.test.js.snap +28 -0
  70. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/CancelButton.test.js.snap +15 -0
  71. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ResumeButton.test.js.snap +15 -0
  72. data/webpack/ForemanTasks/ForemanTasks.js +1 -17
  73. data/webpack/ForemanTasks/ForemanTasksReducers.js +2 -0
  74. data/webpack/ForemanTasks/Routes/ForemanTasksRouter.test.js +5 -1
  75. data/webpack/ForemanTasks/Routes/ForemanTasksRoutes.js +9 -3
  76. data/webpack/ForemanTasks/Routes/ForemanTasksRoutes.test.js +1 -1
  77. data/webpack/ForemanTasks/Routes/ShowTask/__tests__/ShowTask.test.js +5 -1
  78. data/webpack/ForemanTasks/Routes/__snapshots__/ForemanTasksRoutes.test.js.snap +18 -2
  79. data/webpack/ForemanTasks/__snapshots__/ForemanTasks.test.js.snap +1 -54
  80. data/webpack/__mocks__/foremanReact/common/helpers.js +1 -0
  81. data/webpack/__mocks__/foremanReact/common/urlHelpers.js +1 -0
  82. data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +2 -0
  83. data/webpack/__mocks__/foremanReact/components/common/MessageBox.js +4 -0
  84. data/webpack/__mocks__/foremanReact/components/common/dates/LongDateTime.js +5 -0
  85. data/webpack/__mocks__/foremanReact/components/common/dates/RelativeDateTime.js +3 -0
  86. data/webpack/__mocks__/foremanReact/components/common/table.js +4 -0
  87. data/webpack/__mocks__/foremanReact/components/common/table/actionsHelpers/actionTypeCreator.js +7 -0
  88. data/webpack/__mocks__/foremanReact/constants.js +24 -0
  89. data/webpack/__mocks__/foremanReact/redux/actions/toasts.js +8 -0
  90. data/webpack/__mocks__/foremanReact/routes/common/PageLayout/PageLayout.js +10 -0
  91. data/webpack/__mocks__/foremanReact/routes/common/PageLayout/components/ExportButton/ExportButton.js +5 -0
  92. data/webpack/index.js +5 -0
  93. metadata +49 -9
  94. data/app/views/foreman_tasks/tasks/index.html.erb +0 -46
  95. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskHelper.test.js.snap +0 -37
  96. data/webpack/ForemanTasks/Routes/IndexTasks/IndexTasks.js +0 -10
  97. data/webpack/ForemanTasks/Routes/IndexTasks/__tests__/IndexTasks.test.js +0 -10
  98. data/webpack/ForemanTasks/Routes/IndexTasks/__tests__/__snapshots__/IndexTasks.test.js.snap +0 -12
  99. data/webpack/ForemanTasks/Routes/IndexTasks/index.js +0 -1
  100. data/webpack/ForemanTasks/Routes/IndexTasks/indexTasks.scss +0 -0
@@ -56,9 +56,9 @@ exports[`TaskInfo rendering render with Props 1`] = `
56
56
  md={3}
57
57
  sm={6}
58
58
  >
59
- <FormattedRelative
60
- updateInterval={10000}
61
- value={2019-06-17T13:04:09.000Z}
59
+ <Component
60
+ date="2019-06-17 16:04:09 +0300"
61
+ defaultValue="N/A"
62
62
  />
63
63
  </Col>
64
64
  </Row>
@@ -115,9 +115,9 @@ exports[`TaskInfo rendering render with Props 1`] = `
115
115
  md={3}
116
116
  sm={6}
117
117
  >
118
- <FormattedRelative
119
- updateInterval={10000}
120
- value={2019-06-17T13:04:09.000Z}
118
+ <Component
119
+ date="2019-06-17 16:04:09 +0300"
120
+ defaultValue="N/A"
121
121
  />
122
122
  </Col>
123
123
  </Row>
@@ -168,7 +168,10 @@ exports[`TaskInfo rendering render with Props 1`] = `
168
168
  md={3}
169
169
  sm={6}
170
170
  >
171
- N/A
171
+ <Component
172
+ date={null}
173
+ defaultValue="N/A"
174
+ />
172
175
  </Col>
173
176
  </Row>
174
177
  <Row
@@ -356,7 +359,10 @@ exports[`TaskInfo rendering render without Props 1`] = `
356
359
  md={3}
357
360
  sm={6}
358
361
  >
359
- N/A
362
+ <Component
363
+ date=""
364
+ defaultValue="N/A"
365
+ />
360
366
  </Col>
361
367
  </Row>
362
368
  <Row
@@ -412,7 +418,10 @@ exports[`TaskInfo rendering render without Props 1`] = `
412
418
  md={3}
413
419
  sm={6}
414
420
  >
415
- N/A
421
+ <Component
422
+ date=""
423
+ defaultValue="N/A"
424
+ />
416
425
  </Col>
417
426
  </Row>
418
427
  <Row
@@ -460,7 +469,10 @@ exports[`TaskInfo rendering render without Props 1`] = `
460
469
  md={3}
461
470
  sm={6}
462
471
  >
463
- N/A
472
+ <Component
473
+ date=""
474
+ defaultValue="N/A"
475
+ />
464
476
  </Col>
465
477
  </Row>
466
478
  <Row
@@ -12,6 +12,10 @@ import {
12
12
  FOREMAN_TASK_DETAILS_TOGGLE_UNLOCK_MODAL,
13
13
  FOREMAN_TASK_DETAILS_TOGGLE_FORCE_UNLOCK_MODAL,
14
14
  } from './TaskDetailsConstants';
15
+ import {
16
+ cancelTaskRequest,
17
+ resumeTaskRequest,
18
+ } from '../TasksTable/TasksTableActions';
15
19
 
16
20
  export const taskReloadStop = timeoutId => {
17
21
  if (timeoutId) {
@@ -107,3 +111,5 @@ export const toggleUnlockModal = () => ({
107
111
  export const toggleForceUnlockModal = () => ({
108
112
  type: FOREMAN_TASK_DETAILS_TOGGLE_FORCE_UNLOCK_MODAL,
109
113
  });
114
+
115
+ export { cancelTaskRequest, resumeTaskRequest };
@@ -58,7 +58,7 @@ export const selectLocks = state => selectTaskDetails(state).locks || [];
58
58
  export const selectUsernamePath = state =>
59
59
  selectTaskDetails(state).username_path || null;
60
60
 
61
- export const selectAction = state => selectTaskDetails(state).action || null;
61
+ export const selectAction = state => selectTaskDetails(state).action || '';
62
62
 
63
63
  export const selectState = state => selectTaskDetails(state).state || null;
64
64
 
@@ -16,6 +16,7 @@ exports[`TaskDetails rendering render without Props 1`] = `
16
16
  <Task
17
17
  action=""
18
18
  allowDangerousActions={false}
19
+ cancelTaskRequest={[Function]}
19
20
  cancellable={false}
20
21
  endedAt=""
21
22
  error={Array []}
@@ -35,6 +36,7 @@ exports[`TaskDetails rendering render without Props 1`] = `
35
36
  refetchTaskDetails={[Function]}
36
37
  result="error"
37
38
  resumable={false}
39
+ resumeTaskRequest={[Function]}
38
40
  runningSteps={Array []}
39
41
  showForceUnlockModal={false}
40
42
  showUnlockModal={false}
@@ -38,7 +38,9 @@ class TasksDashboard extends React.Component {
38
38
 
39
39
  render() {
40
40
  const { time, query, tasksSummary, updateTime, updateQuery } = this.props;
41
-
41
+ const updateQueryHistory = labelQuery => {
42
+ updateQuery(labelQuery, this.props.history);
43
+ };
42
44
  return (
43
45
  <Grid fluid className="tasks-dashboard-grid">
44
46
  <TasksTimeRow time={time} updateTime={updateTime} />
@@ -46,9 +48,9 @@ class TasksDashboard extends React.Component {
46
48
  time={time}
47
49
  query={query}
48
50
  data={tasksSummary}
49
- updateQuery={updateQuery}
51
+ updateQuery={updateQueryHistory}
50
52
  />
51
- <TasksLabelsRow query={query} updateQuery={updateQuery} />
53
+ <TasksLabelsRow query={query} updateQuery={updateQueryHistory} />
52
54
  </Grid>
53
55
  );
54
56
  }
@@ -62,6 +64,7 @@ TasksDashboard.propTypes = {
62
64
  updateTime: PropTypes.func,
63
65
  updateQuery: PropTypes.func,
64
66
  fetchTasksSummary: PropTypes.func,
67
+ history: PropTypes.object.isRequired,
65
68
  };
66
69
 
67
70
  TasksDashboard.defaultProps = {
@@ -21,16 +21,15 @@ export const updateTime = time => ({
21
21
  payload: time,
22
22
  });
23
23
 
24
- export const updateQuery = query => (dispatch, getState) => {
24
+ export const updateQuery = (query, history) => (dispatch, getState) => {
25
25
  if (query.time === TASKS_DASHBOARD_CURRENT_TIME)
26
26
  query.time = selectTime(getState());
27
27
 
28
+ resolveQuery(query, history);
28
29
  dispatch({
29
30
  type: FOREMAN_TASKS_DASHBOARD_UPDATE_QUERY,
30
31
  payload: query,
31
32
  });
32
-
33
- resolveQuery(query);
34
33
  };
35
34
 
36
35
  export const fetchTasksSummary = time => async dispatch => {
@@ -1,4 +1,3 @@
1
- import URI from 'urijs';
2
1
  import { getURIQuery } from 'foremanReact/common/helpers';
3
2
 
4
3
  import {
@@ -6,6 +5,7 @@ import {
6
5
  TASKS_DASHBOARD_QUERY_KEYS_TEXT,
7
6
  TASKS_DASHBOARD_QUERY_VALUES_TEXT,
8
7
  } from './TasksDashboardConstants';
8
+ import { updateURlQuery } from '../TasksTable/TasksTableHelpers';
9
9
 
10
10
  export const getQueryKeyText = key => TASKS_DASHBOARD_QUERY_KEYS_TEXT[key];
11
11
 
@@ -46,50 +46,19 @@ const queryFromUriQuery = uriQuery => {
46
46
  return query;
47
47
  };
48
48
 
49
- const uriQueryFromQuery = query => {
50
- const uriQuery = {};
51
-
52
- Object.entries(uriToQueryMap).forEach(([uriField, queryField]) => {
53
- if (query[queryField]) uriQuery[uriField] = query[queryField];
54
- });
55
-
56
- if (uriQuery.time_mode === 'last') {
57
- uriQuery.time_mode = 'recent';
58
- }
59
-
60
- return uriQuery;
61
- };
62
-
63
49
  export const getQueryFromUrl = () => {
64
50
  const uriQuery = getURIQuery(window.location.href);
65
51
 
66
52
  return queryFromUriQuery(uriQuery);
67
53
  };
68
54
 
69
- export const resolveQuery = query => {
70
- const uriQuery = uriQueryFromQuery(query);
71
-
72
- const uri = new URI(window.location.href);
73
- const { search } = uri.query(true);
74
-
75
- const data = { search, ...uriQuery, page: 1 };
76
- const { $, tfm } = window;
77
-
78
- uri.query(URI.buildQuery(data, true));
79
- tfm.tools.showSpinner();
80
- $.ajax({
81
- type: 'get',
82
- url: uri.toString(),
83
- success(result) {
84
- const res = $(`<div>${result}</div>`);
85
-
86
- $('#tasks-table').html(res.find('#tasks-table'));
87
- },
88
- error({ statusText }) {
89
- $('#tasks-table').html(statusText);
90
- },
91
- complete(result) {
92
- tfm.tools.hideSpinner();
93
- },
94
- });
55
+ export const resolveQuery = ({ state, result, mode, time }, history) => {
56
+ const uriQuery = {
57
+ state,
58
+ result,
59
+ time_mode: mode === 'last' ? 'recent' : mode,
60
+ time_horizon: time,
61
+ page: 1,
62
+ };
63
+ updateURlQuery(uriQuery, history);
95
64
  };
@@ -12,7 +12,6 @@ import {
12
12
 
13
13
  const initialState = Immutable({
14
14
  time: TASKS_DASHBOARD_AVAILABLE_TIMES.H24,
15
- query: {},
16
15
  isLoadingTasksSummary: false,
17
16
  error: null,
18
17
  tasksSummary: TASKS_SUMMARY_ZERO,
@@ -3,7 +3,7 @@ import { testComponentSnapshotsWithFixtures } from 'react-redux-test-utils';
3
3
  import TasksDashboard from '../TasksDashboard';
4
4
 
5
5
  const fixtures = {
6
- 'render without Props': {},
6
+ 'render without Props': { history: {} },
7
7
  /** fixtures, props for the component */
8
8
  };
9
9
 
@@ -5,7 +5,6 @@ Object {
5
5
  "error": [Error: some error],
6
6
  "isLoading": false,
7
7
  "isLoadingTasksSummary": false,
8
- "query": Object {},
9
8
  "tasksSummary": Object {
10
9
  "paused": Object {
11
10
  "recent": 0,
@@ -44,7 +43,6 @@ Object {
44
43
  "error": null,
45
44
  "isLoading": true,
46
45
  "isLoadingTasksSummary": false,
47
- "query": Object {},
48
46
  "tasksSummary": Object {
49
47
  "paused": Object {
50
48
  "recent": 0,
@@ -83,7 +81,6 @@ Object {
83
81
  "error": null,
84
82
  "isLoading": false,
85
83
  "isLoadingTasksSummary": false,
86
- "query": Object {},
87
84
  "tasksSummary": "some-payload",
88
85
  "time": "H24",
89
86
  }
@@ -93,7 +90,7 @@ exports[`BreadcrumbBar reducer should handle FOREMAN_TASKS_DASHBOARD_INIT 1`] =
93
90
  Object {
94
91
  "error": null,
95
92
  "isLoadingTasksSummary": false,
96
- "query": Object {},
93
+ "query": undefined,
97
94
  "tasksSummary": Object {
98
95
  "paused": Object {
99
96
  "recent": 0,
@@ -207,7 +204,6 @@ exports[`BreadcrumbBar reducer should handle FOREMAN_TASKS_DASHBOARD_UPDATE_TIME
207
204
  Object {
208
205
  "error": null,
209
206
  "isLoadingTasksSummary": false,
210
- "query": Object {},
211
207
  "tasksSummary": Object {
212
208
  "paused": Object {
213
209
  "recent": 0,
@@ -245,7 +241,6 @@ exports[`BreadcrumbBar reducer should return the initial state 1`] = `
245
241
  Object {
246
242
  "error": null,
247
243
  "isLoadingTasksSummary": false,
248
- "query": Object {},
249
244
  "tasksSummary": Object {
250
245
  "paused": Object {
251
246
  "recent": 0,
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { translate as __ } from 'foremanReact/common/I18n';
4
+ import TasksTablePage from './';
5
+
6
+ export const SubTasksPage = props => {
7
+ const getBreadcrumbs = actionName => ({
8
+ breadcrumbItems: [
9
+ { caption: __('Tasks'), url: `/foreman_tasks/tasks` },
10
+ {
11
+ caption: actionName,
12
+ url: `/foreman_tasks/tasks/${props.match.params.id}`,
13
+ },
14
+ { caption: __('Sub tasks') },
15
+ ],
16
+ });
17
+ return <TasksTablePage getBreadcrumbs={getBreadcrumbs} {...props} />;
18
+ };
19
+
20
+ SubTasksPage.propTypes = {
21
+ match: PropTypes.shape({
22
+ params: PropTypes.object,
23
+ }),
24
+ };
25
+
26
+ SubTasksPage.defaultProps = {
27
+ match: {
28
+ params: {},
29
+ },
30
+ };
@@ -0,0 +1,53 @@
1
+ import React from 'react';
2
+ import { FormattedDate } from 'react-intl';
3
+ import { isoCompatibleDate } from 'foremanReact/common/helpers';
4
+ import { translate as __ } from 'foremanReact/common/I18n';
5
+ import EllipsisWithTooltip from 'react-ellipsis-with-tooltip';
6
+ import { cellFormatter } from 'foremanReact/components/common/table';
7
+ import { ActionButton } from '../common/ActionButtons/ActionButton';
8
+
9
+ export const dateCellFormmatter = value => {
10
+ if (value) {
11
+ const isoDate = isoCompatibleDate(value);
12
+ return (
13
+ <span>
14
+ <FormattedDate
15
+ value={isoDate}
16
+ day="2-digit"
17
+ month="long"
18
+ hour="2-digit"
19
+ minute="2-digit"
20
+ second="2-digit"
21
+ year="numeric"
22
+ />
23
+ </span>
24
+ );
25
+ }
26
+ return <span>{__('N/A')}</span>;
27
+ };
28
+
29
+ export const actionNameCellFormatter = url => (value, { rowData: { id } }) =>
30
+ cellFormatter(
31
+ <EllipsisWithTooltip>
32
+ <a href={`/${url}/${id}`}>{value}</a>
33
+ </EllipsisWithTooltip>
34
+ );
35
+
36
+ export const actionCellFormatter = taskActions => (
37
+ value,
38
+ { rowData: { action, id } }
39
+ ) =>
40
+ cellFormatter(
41
+ <ActionButton
42
+ taskActions={taskActions}
43
+ availableActions={value}
44
+ id={id}
45
+ name={action}
46
+ />
47
+ );
48
+
49
+ export const durationCellFormmatter = value => (
50
+ <span className="param-value" title={value.tooltip}>
51
+ {value.text}
52
+ </span>
53
+ );
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { translate as __ } from 'foremanReact/common/I18n';
3
+ import TasksTablePage from './';
4
+
5
+ export const TasksIndexPage = props => {
6
+ const getBreadcrumbs = () => ({
7
+ breadcrumbItems: [{ caption: __('Tasks'), url: `/foreman_tasks/tasks` }],
8
+ });
9
+ return <TasksTablePage getBreadcrumbs={getBreadcrumbs} {...props} />;
10
+ };
@@ -0,0 +1,119 @@
1
+ import React, { useEffect } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { Table } from 'foremanReact/components/common/table';
4
+ import { STATUS } from 'foremanReact/constants';
5
+ import MessageBox from 'foremanReact/components/common/MessageBox';
6
+ import { translate as __ } from 'foremanReact/common/I18n';
7
+ import Pagination from 'foremanReact/components/Pagination/PaginationWrapper';
8
+ import { getURIQuery } from 'foremanReact/common/helpers';
9
+ import createTasksTableSchema from './TasksTableSchema';
10
+ import { updateURlQuery } from './TasksTableHelpers';
11
+
12
+ const TasksTable = ({
13
+ getTableItems,
14
+ error,
15
+ status,
16
+ results,
17
+ history,
18
+ itemCount,
19
+ pagination,
20
+ cancelTask,
21
+ resumeTask,
22
+ }) => {
23
+ const url = history.location.pathname + history.location.search;
24
+ const uriQuery = getURIQuery(url);
25
+
26
+ useEffect(() => {
27
+ getTableItems(url);
28
+ }, [history.location.search]);
29
+
30
+ if (status === STATUS.ERROR) {
31
+ return (
32
+ <MessageBox
33
+ key="tasks-table-error"
34
+ icontype="error-circle-o"
35
+ msg={__(`Could not receive data: ${error && error.message}`)}
36
+ />
37
+ );
38
+ }
39
+
40
+ if (status === STATUS.PENDING && results.length === 0) {
41
+ return <div />;
42
+ }
43
+
44
+ if (results.length === 0) {
45
+ return <span>{__('No Tasks')}</span>;
46
+ }
47
+
48
+ const changeTablePage = ({ page, perPage }) => {
49
+ updateURlQuery(
50
+ {
51
+ page,
52
+ per_page: perPage,
53
+ },
54
+ history
55
+ );
56
+ };
57
+
58
+ const setSortHistory = (by, order) => {
59
+ updateURlQuery({ sort_by: by, sort_order: order }, history);
60
+ };
61
+
62
+ const taskActions = {
63
+ cancel: (id, name) => {
64
+ cancelTask(id, name, url);
65
+ },
66
+ resume: (id, name) => {
67
+ resumeTask(id, name, url);
68
+ },
69
+ };
70
+
71
+ return (
72
+ <div className="tasks-table">
73
+ <Table
74
+ key="tasks-table"
75
+ columns={createTasksTableSchema(
76
+ setSortHistory,
77
+ uriQuery.sort_by,
78
+ uriQuery.sort_order,
79
+ taskActions
80
+ )}
81
+ rows={results}
82
+ />
83
+ <Pagination
84
+ className="tasks-pagination"
85
+ viewType="table"
86
+ itemCount={itemCount}
87
+ pagination={pagination}
88
+ onChange={changeTablePage}
89
+ dropdownButtonId="tasks-table-dropdown"
90
+ />
91
+ </div>
92
+ );
93
+ };
94
+
95
+ TasksTable.propTypes = {
96
+ results: PropTypes.array.isRequired,
97
+ getTableItems: PropTypes.func.isRequired,
98
+ status: PropTypes.oneOf(Object.keys(STATUS)),
99
+ error: PropTypes.instanceOf(Error),
100
+ itemCount: PropTypes.number.isRequired,
101
+ pagination: PropTypes.shape({
102
+ page: PropTypes.number,
103
+ perPage: PropTypes.number,
104
+ }),
105
+ history: PropTypes.object.isRequired,
106
+ cancelTask: PropTypes.func.isRequired,
107
+ resumeTask: PropTypes.func.isRequired,
108
+ };
109
+
110
+ TasksTable.defaultProps = {
111
+ status: STATUS.PENDING,
112
+ error: null,
113
+ pagination: {
114
+ page: 1,
115
+ perPage: 20,
116
+ },
117
+ };
118
+
119
+ export default TasksTable;