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.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/foreman_tasks/tasks.css.scss +3 -3
- data/app/controllers/foreman_tasks/api/tasks_controller.rb +50 -30
- data/app/controllers/foreman_tasks/tasks_controller.rb +8 -17
- data/app/models/foreman_tasks/task.rb +6 -4
- data/app/models/foreman_tasks/task/search.rb +0 -25
- data/app/models/setting/foreman_tasks.rb +19 -23
- data/app/views/foreman_tasks/api/tasks/show.json.rabl +1 -0
- data/app/views/foreman_tasks/layouts/react.html.erb +4 -1
- data/config/routes.rb +17 -3
- data/db/migrate/20180927120509_add_user_id.foreman_tasks.rb +4 -2
- data/lib/foreman_tasks/dynflow.rb +1 -1
- data/lib/foreman_tasks/dynflow/console_authorizer.rb +13 -2
- data/lib/foreman_tasks/engine.rb +1 -1
- data/lib/foreman_tasks/version.rb +1 -1
- data/package.json +1 -0
- data/test/controllers/tasks_controller_test.rb +35 -4
- data/test/unit/dynflow_console_authorizer_test.rb +1 -1
- data/test/unit/otp_manager_test.rb +24 -17
- data/test/unit/task_test.rb +48 -2
- data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +29 -16
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskHelper.js +3 -17
- data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +18 -5
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskHelper.test.js +1 -56
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +24 -44
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +22 -10
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +6 -0
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +1 -1
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +2 -0
- data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboard.js +6 -3
- data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardActions.js +2 -3
- data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardHelper.js +10 -41
- data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardReducer.js +0 -1
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboard.test.js +1 -1
- data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboardReducer.test.js.snap +1 -6
- data/webpack/ForemanTasks/Components/TasksTable/SubTasksPage.js +30 -0
- data/webpack/ForemanTasks/Components/TasksTable/TaskTableFormmatters.js +53 -0
- data/webpack/ForemanTasks/Components/TasksTable/TasksIndexPage.js +10 -0
- data/webpack/ForemanTasks/Components/TasksTable/TasksTable.js +119 -0
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +67 -0
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +5 -0
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableHelpers.js +64 -0
- data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +63 -0
- data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.scss +29 -0
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableReducer.js +35 -0
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableSchema.js +67 -0
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +39 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/SubTasksPage.test.js +20 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksIndexPage.test.js +12 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +42 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.test.js +9 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableActions.test.js +48 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableHelpers.test.js +28 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTablePage.test.js +26 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableReducer.test.js +37 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +49 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +42 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTable.test.js.snap +72 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableActions.test.js.snap +115 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +194 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableReducer.test.js.snap +32 -0
- data/webpack/ForemanTasks/Components/TasksTable/index.js +32 -0
- data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.js +39 -0
- data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.test.js +45 -0
- data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.js +23 -0
- data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.test.js +27 -0
- data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.js +23 -0
- data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.test.js +27 -0
- data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ActionButton.test.js.snap +28 -0
- data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/CancelButton.test.js.snap +15 -0
- data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ResumeButton.test.js.snap +15 -0
- data/webpack/ForemanTasks/ForemanTasks.js +1 -17
- data/webpack/ForemanTasks/ForemanTasksReducers.js +2 -0
- data/webpack/ForemanTasks/Routes/ForemanTasksRouter.test.js +5 -1
- data/webpack/ForemanTasks/Routes/ForemanTasksRoutes.js +9 -3
- data/webpack/ForemanTasks/Routes/ForemanTasksRoutes.test.js +1 -1
- data/webpack/ForemanTasks/Routes/ShowTask/__tests__/ShowTask.test.js +5 -1
- data/webpack/ForemanTasks/Routes/__snapshots__/ForemanTasksRoutes.test.js.snap +18 -2
- data/webpack/ForemanTasks/__snapshots__/ForemanTasks.test.js.snap +1 -54
- data/webpack/__mocks__/foremanReact/common/helpers.js +1 -0
- data/webpack/__mocks__/foremanReact/common/urlHelpers.js +1 -0
- data/webpack/__mocks__/foremanReact/components/Pagination/PaginationWrapper.js +2 -0
- data/webpack/__mocks__/foremanReact/components/common/MessageBox.js +4 -0
- data/webpack/__mocks__/foremanReact/components/common/dates/LongDateTime.js +5 -0
- data/webpack/__mocks__/foremanReact/components/common/dates/RelativeDateTime.js +3 -0
- data/webpack/__mocks__/foremanReact/components/common/table.js +4 -0
- data/webpack/__mocks__/foremanReact/components/common/table/actionsHelpers/actionTypeCreator.js +7 -0
- data/webpack/__mocks__/foremanReact/constants.js +24 -0
- data/webpack/__mocks__/foremanReact/redux/actions/toasts.js +8 -0
- data/webpack/__mocks__/foremanReact/routes/common/PageLayout/PageLayout.js +10 -0
- data/webpack/__mocks__/foremanReact/routes/common/PageLayout/components/ExportButton/ExportButton.js +5 -0
- data/webpack/index.js +5 -0
- metadata +49 -9
- data/app/views/foreman_tasks/tasks/index.html.erb +0 -46
- data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskHelper.test.js.snap +0 -37
- data/webpack/ForemanTasks/Routes/IndexTasks/IndexTasks.js +0 -10
- data/webpack/ForemanTasks/Routes/IndexTasks/__tests__/IndexTasks.test.js +0 -10
- data/webpack/ForemanTasks/Routes/IndexTasks/__tests__/__snapshots__/IndexTasks.test.js.snap +0 -12
- data/webpack/ForemanTasks/Routes/IndexTasks/index.js +0 -1
- 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
|
-
<
|
60
|
-
|
61
|
-
|
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
|
-
<
|
119
|
-
|
120
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 ||
|
61
|
+
export const selectAction = state => selectTaskDetails(state).action || '';
|
62
62
|
|
63
63
|
export const selectState = state => selectTaskDetails(state).state || null;
|
64
64
|
|
data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap
CHANGED
@@ -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={
|
51
|
+
updateQuery={updateQueryHistory}
|
50
52
|
/>
|
51
|
-
<TasksLabelsRow query={query} 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 =
|
70
|
-
const uriQuery =
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
};
|
@@ -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":
|
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;
|