foreman-tasks 0.17.1 → 0.17.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/foreman_tasks/version.rb +1 -1
- data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +3 -1
- data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +2 -2
- data/webpack/ForemanTasks/Components/TaskDetails/index.js +1 -4
- data/webpack/ForemanTasks/Components/TasksDashboard/index.js +1 -4
- data/webpack/ForemanTasks/Components/TasksTable/Components/ActionConfirmation.js +49 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/ActionSelectButton.js +37 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/CancelResumeConfirm.js +51 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/TableSelectionCell.js +32 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/TableSelectionHeaderCell.js +38 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ActionConfirmation.test.js +18 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ActionSelectButton.test.js +13 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/CancelResumeConfirm.test.js +28 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/TableSelectionCell.test.js +15 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/TableSelectionHeaderCell.test.js +15 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ActionConfirmation.test.js.snap +89 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ActionSelectButton.test.js.snap +32 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/CancelResumeConfirm.test.js.snap +37 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/TableSelectionCell.test.js.snap +14 -0
- data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/TableSelectionHeaderCell.test.js.snap +15 -0
- data/webpack/ForemanTasks/Components/TasksTable/TasksTable.js +29 -1
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +78 -3
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +11 -0
- data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +47 -1
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableReducer.js +30 -11
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableSchema.js +23 -5
- data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +8 -0
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +9 -1
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableActions.test.js +46 -1
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableReducer.test.js +29 -1
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +9 -5
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +9 -5
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableActions.test.js.snap +77 -17
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +46 -10
- data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableReducer.test.js.snap +62 -7
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionCellFormatter.test.js.snap +14 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionNameCellFormatter.test.js.snap +9 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/dateCellFormmatter.test.js.snap +9 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/durationCellFormmatter.test.js.snap +18 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/selectionCellFormatter.test.js.snap +10 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/selectionHeaderCellFormatter.test.js.snap +10 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/actionCellFormatter.test.js +11 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/actionNameCellFormatter.test.js +8 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/dateCellFormmatter.test.js +7 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/durationCellFormmatter.test.js +12 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionCellFormatter.test.js +12 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionHeaderCellFormatter.test.js +12 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/actionCellFormatter.js +16 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/actionNameCellFormatter.js +5 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/dateCellFormmatter.js +7 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/durationCellFormmatter.js +7 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/index.js +7 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionCellFormatter.js +10 -0
- data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionHeaderCellFormatter.js +10 -0
- data/webpack/ForemanTasks/Components/TasksTable/index.js +5 -4
- data/webpack/__mocks__/foremanReact/components/common/table.js +1 -0
- metadata +36 -3
- data/webpack/ForemanTasks/Components/TasksTable/TaskTableFormmatters.js +0 -53
@@ -0,0 +1,32 @@
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
2
|
+
|
3
|
+
exports[`ActionSelectButton renders with minimal props 1`] = `
|
4
|
+
<DropdownButton
|
5
|
+
disabled={false}
|
6
|
+
id="selcted-action-type"
|
7
|
+
title="Select Action"
|
8
|
+
>
|
9
|
+
<MenuItem
|
10
|
+
bsClass="dropdown"
|
11
|
+
disabled={false}
|
12
|
+
divider={false}
|
13
|
+
eventKey="1"
|
14
|
+
header={false}
|
15
|
+
onClick={[MockFunction]}
|
16
|
+
title="Cancel selected tasks"
|
17
|
+
>
|
18
|
+
Cancel Selected
|
19
|
+
</MenuItem>
|
20
|
+
<MenuItem
|
21
|
+
bsClass="dropdown"
|
22
|
+
disabled={false}
|
23
|
+
divider={false}
|
24
|
+
eventKey="2"
|
25
|
+
header={false}
|
26
|
+
onClick={[MockFunction]}
|
27
|
+
title="Resume selected tasks"
|
28
|
+
>
|
29
|
+
Resume Selected
|
30
|
+
</MenuItem>
|
31
|
+
</DropdownButton>
|
32
|
+
`;
|
@@ -0,0 +1,37 @@
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
2
|
+
|
3
|
+
exports[`CancelResumeConfirm renders CANCEL modal 1`] = `
|
4
|
+
<ActionConfirmation
|
5
|
+
abortAction="No"
|
6
|
+
closeModal={[Function]}
|
7
|
+
confirmAction="Yes"
|
8
|
+
message="This will stop 3 tasks, putting them in the canceled state. Are you sure?"
|
9
|
+
onClick={[Function]}
|
10
|
+
showModal={true}
|
11
|
+
title="Cancel Selected Tasks"
|
12
|
+
/>
|
13
|
+
`;
|
14
|
+
|
15
|
+
exports[`CancelResumeConfirm renders CLOSED modal 1`] = `
|
16
|
+
<ActionConfirmation
|
17
|
+
abortAction="No"
|
18
|
+
closeModal={[Function]}
|
19
|
+
confirmAction="Yes"
|
20
|
+
message="This will resume 3 tasks, putting them in the running state. Are you sure?"
|
21
|
+
onClick={[Function]}
|
22
|
+
showModal={false}
|
23
|
+
title="Resume Selected Tasks"
|
24
|
+
/>
|
25
|
+
`;
|
26
|
+
|
27
|
+
exports[`CancelResumeConfirm renders RESUME modal 1`] = `
|
28
|
+
<ActionConfirmation
|
29
|
+
abortAction="No"
|
30
|
+
closeModal={[Function]}
|
31
|
+
confirmAction="Yes"
|
32
|
+
message="This will resume 3 tasks, putting them in the running state. Are you sure?"
|
33
|
+
onClick={[Function]}
|
34
|
+
showModal={true}
|
35
|
+
title="Resume Selected Tasks"
|
36
|
+
/>
|
37
|
+
`;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
2
|
+
|
3
|
+
exports[`TableSelectionCell renders TableSelectionCell 1`] = `
|
4
|
+
<TableSelectionCell
|
5
|
+
className=""
|
6
|
+
>
|
7
|
+
<TableCheckbox
|
8
|
+
checked={true}
|
9
|
+
id="some id"
|
10
|
+
label="some label"
|
11
|
+
onChange={[MockFunction]}
|
12
|
+
/>
|
13
|
+
</TableSelectionCell>
|
14
|
+
`;
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
2
|
+
|
3
|
+
exports[`TableSelectionHeaderCell renders TableSelectionHeaderCell 1`] = `
|
4
|
+
<TableSelectionHeading
|
5
|
+
aria-label="some label"
|
6
|
+
className=""
|
7
|
+
>
|
8
|
+
<TableCheckbox
|
9
|
+
checked={true}
|
10
|
+
id="some id"
|
11
|
+
label="some label"
|
12
|
+
onChange={[MockFunction]}
|
13
|
+
/>
|
14
|
+
</TableSelectionHeading>
|
15
|
+
`;
|
@@ -19,6 +19,11 @@ const TasksTable = ({
|
|
19
19
|
pagination,
|
20
20
|
cancelTask,
|
21
21
|
resumeTask,
|
22
|
+
selectedRows,
|
23
|
+
selectAllRows,
|
24
|
+
unselectAllRows,
|
25
|
+
selectRow,
|
26
|
+
unselectRow,
|
22
27
|
}) => {
|
23
28
|
const url = history.location.pathname + history.location.search;
|
24
29
|
const uriQuery = getURIQuery(url);
|
@@ -27,6 +32,22 @@ const TasksTable = ({
|
|
27
32
|
getTableItems(url);
|
28
33
|
}, [history.location.search]);
|
29
34
|
|
35
|
+
const getSelectionController = () => {
|
36
|
+
const checkAllRowsSelected = () => results.length === selectedRows.length;
|
37
|
+
return {
|
38
|
+
allRowsSelected: () => checkAllRowsSelected(),
|
39
|
+
selectAllRows: () => {
|
40
|
+
if (checkAllRowsSelected()) unselectAllRows();
|
41
|
+
else selectAllRows(results);
|
42
|
+
},
|
43
|
+
selectRow: ({ rowData: { id } }) => {
|
44
|
+
if (selectedRows.includes(id)) unselectRow(id);
|
45
|
+
else selectRow(id);
|
46
|
+
},
|
47
|
+
isSelected: ({ rowData }) => selectedRows.includes(rowData.id),
|
48
|
+
};
|
49
|
+
};
|
50
|
+
|
30
51
|
if (status === STATUS.ERROR) {
|
31
52
|
return (
|
32
53
|
<MessageBox
|
@@ -76,7 +97,8 @@ const TasksTable = ({
|
|
76
97
|
setSortHistory,
|
77
98
|
uriQuery.sort_by,
|
78
99
|
uriQuery.sort_order,
|
79
|
-
taskActions
|
100
|
+
taskActions,
|
101
|
+
getSelectionController()
|
80
102
|
)}
|
81
103
|
rows={results}
|
82
104
|
/>
|
@@ -105,6 +127,11 @@ TasksTable.propTypes = {
|
|
105
127
|
history: PropTypes.object.isRequired,
|
106
128
|
cancelTask: PropTypes.func.isRequired,
|
107
129
|
resumeTask: PropTypes.func.isRequired,
|
130
|
+
selectedRows: PropTypes.array,
|
131
|
+
selectAllRows: PropTypes.func.isRequired,
|
132
|
+
unselectAllRows: PropTypes.func.isRequired,
|
133
|
+
selectRow: PropTypes.func.isRequired,
|
134
|
+
unselectRow: PropTypes.func.isRequired,
|
108
135
|
};
|
109
136
|
|
110
137
|
TasksTable.defaultProps = {
|
@@ -114,6 +141,7 @@ TasksTable.defaultProps = {
|
|
114
141
|
page: 1,
|
115
142
|
perPage: 20,
|
116
143
|
},
|
144
|
+
selectedRows: [],
|
117
145
|
};
|
118
146
|
|
119
147
|
export default TasksTable;
|
@@ -3,7 +3,16 @@ import { getTableItemsAction } from 'foremanReact/components/common/table';
|
|
3
3
|
import API from 'foremanReact/API';
|
4
4
|
import { addToast } from 'foremanReact/redux/actions/toasts';
|
5
5
|
import { translate as __ } from 'foremanReact/common/I18n';
|
6
|
-
import {
|
6
|
+
import {
|
7
|
+
TASKS_TABLE_ID,
|
8
|
+
SELECT_ROWS,
|
9
|
+
UNSELECT_ALL_ROWS,
|
10
|
+
UNSELECT_ROWS,
|
11
|
+
TASKS_TABLE_SELECTED_MODAL,
|
12
|
+
CLOSED,
|
13
|
+
RESUME,
|
14
|
+
CANCEL,
|
15
|
+
} from './TasksTableConstants';
|
7
16
|
import { getApiPathname } from './TasksTableHelpers';
|
8
17
|
import { fetchTasksSummary } from '../TasksDashboard/TasksDashboardActions';
|
9
18
|
|
@@ -28,14 +37,14 @@ export const cancelTaskRequest = (id, name) => async dispatch => {
|
|
28
37
|
dispatch(
|
29
38
|
addToast({
|
30
39
|
type: 'success',
|
31
|
-
message: `"${name}" ${__('
|
40
|
+
message: `"${name}" ${__('Task cancelled')}`,
|
32
41
|
})
|
33
42
|
);
|
34
43
|
} catch ({ response }) {
|
35
44
|
dispatch(
|
36
45
|
addToast({
|
37
46
|
type: 'error',
|
38
|
-
message: `"${name}" ${__('
|
47
|
+
message: `"${name}" ${__('Task cannot be cancelled at the moment.')}`,
|
39
48
|
})
|
40
49
|
);
|
41
50
|
}
|
@@ -65,3 +74,69 @@ export const resumeTaskRequest = (id, name) => async dispatch => {
|
|
65
74
|
);
|
66
75
|
}
|
67
76
|
};
|
77
|
+
|
78
|
+
export const selectAllRows = results => ({
|
79
|
+
type: SELECT_ROWS,
|
80
|
+
payload: results.map(row => row.id),
|
81
|
+
});
|
82
|
+
|
83
|
+
export const unselectAllRows = () => ({
|
84
|
+
type: UNSELECT_ALL_ROWS,
|
85
|
+
});
|
86
|
+
|
87
|
+
export const selectRow = id => ({
|
88
|
+
type: SELECT_ROWS,
|
89
|
+
payload: [id],
|
90
|
+
});
|
91
|
+
|
92
|
+
export const unselectRow = id => ({
|
93
|
+
type: UNSELECT_ROWS,
|
94
|
+
payload: id,
|
95
|
+
});
|
96
|
+
|
97
|
+
export const actionSelected = (actionType, selected, url) => async dispatch => {
|
98
|
+
let notAllActionable = false;
|
99
|
+
let someActionable = false;
|
100
|
+
const promises = selected.map(task => {
|
101
|
+
if (actionType === RESUME && task.isResumeble) {
|
102
|
+
someActionable = true;
|
103
|
+
return dispatch(resumeTaskRequest(task.id, task.name, url));
|
104
|
+
} else if (actionType === CANCEL && task.isCancelleble) {
|
105
|
+
someActionable = true;
|
106
|
+
return dispatch(cancelTaskRequest(task.id, task.name, url));
|
107
|
+
}
|
108
|
+
notAllActionable = true;
|
109
|
+
return null;
|
110
|
+
});
|
111
|
+
if (notAllActionable)
|
112
|
+
dispatch(
|
113
|
+
addToast({
|
114
|
+
type: 'warning',
|
115
|
+
message: __(
|
116
|
+
`Not all the selected tasks can be ${
|
117
|
+
actionType === RESUME ? 'resumed' : 'canceled'
|
118
|
+
}`
|
119
|
+
),
|
120
|
+
})
|
121
|
+
);
|
122
|
+
if (someActionable) {
|
123
|
+
await Promise.all(promises);
|
124
|
+
dispatch(getTableItems(url));
|
125
|
+
dispatch(fetchTasksSummary(getURIQuery(url).time));
|
126
|
+
}
|
127
|
+
};
|
128
|
+
|
129
|
+
export const showCancelSelcetedModal = () => ({
|
130
|
+
type: TASKS_TABLE_SELECTED_MODAL,
|
131
|
+
payload: CANCEL,
|
132
|
+
});
|
133
|
+
|
134
|
+
export const showResumeSelcetedModal = () => ({
|
135
|
+
type: TASKS_TABLE_SELECTED_MODAL,
|
136
|
+
payload: RESUME,
|
137
|
+
});
|
138
|
+
|
139
|
+
export const hideSelcetedModal = () => ({
|
140
|
+
type: TASKS_TABLE_SELECTED_MODAL,
|
141
|
+
payload: CLOSED,
|
142
|
+
});
|
@@ -1,5 +1,16 @@
|
|
1
1
|
import { getControllerSearchProps } from 'foremanReact/constants';
|
2
2
|
|
3
3
|
export const TASKS_TABLE_ID = 'TASKS_TABLE';
|
4
|
+
export const TASKS_CONTROLLER = 'tasks';
|
5
|
+
export const TASKS_SUCCESS = 'TASKS_SUCCESS';
|
6
|
+
export const TASKS_REQUEST = 'TASKS_REQUEST';
|
7
|
+
export const TASKS_FAILURE = 'TASKS_FAILURE';
|
8
|
+
export const SELECT_ROWS = 'SELECT_ROWS';
|
9
|
+
export const UNSELECT_ROWS = 'UNSELECT_ROWS';
|
10
|
+
export const UNSELECT_ALL_ROWS = 'UNSELECT_ALL_ROWS';
|
11
|
+
export const CANCEL = 'CANCEL';
|
12
|
+
export const RESUME = 'RESUME';
|
13
|
+
export const CLOSED = 'CLOSED';
|
4
14
|
|
15
|
+
export const TASKS_TABLE_SELECTED_MODAL = 'TASKS_TABLE_SELECTED_MODAL';
|
5
16
|
export const TASKS_SEARCH_PROPS = getControllerSearchProps('tasks');
|
@@ -3,13 +3,21 @@ import PropTypes from 'prop-types';
|
|
3
3
|
import { getURIsearch } from 'foremanReact/common/urlHelpers';
|
4
4
|
import { Spinner } from 'patternfly-react';
|
5
5
|
import PageLayout from 'foremanReact/routes/common/PageLayout/PageLayout';
|
6
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
6
7
|
import { getURIQuery } from 'foremanReact/common/helpers';
|
7
8
|
import ExportButton from 'foremanReact/routes/common/PageLayout/components/ExportButton/ExportButton';
|
8
9
|
import { STATUS } from 'foremanReact/constants';
|
9
10
|
import TasksDashboard from '../TasksDashboard';
|
10
11
|
import TasksTable from './TasksTable';
|
11
12
|
import { resolveSearchQuery, addSearchToURL } from './TasksTableHelpers';
|
12
|
-
import {
|
13
|
+
import { CancelResumeConfirm } from './Components/CancelResumeConfirm';
|
14
|
+
import {
|
15
|
+
TASKS_SEARCH_PROPS,
|
16
|
+
RESUME,
|
17
|
+
CANCEL,
|
18
|
+
CLOSED,
|
19
|
+
} from './TasksTableConstants';
|
20
|
+
import { ActionSelectButton } from './Components/ActionSelectButton';
|
13
21
|
import './TasksTablePage.scss';
|
14
22
|
|
15
23
|
const TasksTablePage = ({ getBreadcrumbs, history, ...props }) => {
|
@@ -20,8 +28,31 @@ const TasksTablePage = ({ getBreadcrumbs, history, ...props }) => {
|
|
20
28
|
props.getTableItems(url);
|
21
29
|
};
|
22
30
|
|
31
|
+
const getSelected = () => {
|
32
|
+
const selected = props.results.filter(item =>
|
33
|
+
props.selectedRows.includes(item.id)
|
34
|
+
);
|
35
|
+
return selected.map(item => ({
|
36
|
+
name: item.action,
|
37
|
+
id: item.id,
|
38
|
+
isCancelleble: item.availableActions.cancellable,
|
39
|
+
isResumeble: item.availableActions.resumable,
|
40
|
+
}));
|
41
|
+
};
|
42
|
+
|
43
|
+
const TaskSelectedAction = (id, name) => {
|
44
|
+
props.actionSelected(id, name, url);
|
45
|
+
};
|
46
|
+
|
23
47
|
return (
|
24
48
|
<div className="tasks-table-wrapper">
|
49
|
+
<CancelResumeConfirm
|
50
|
+
closeModal={props.hideSelcetedModal}
|
51
|
+
action={TaskSelectedAction}
|
52
|
+
selected={getSelected()}
|
53
|
+
modalStatus={props.modalStatus}
|
54
|
+
selectedRowsLen={props.selectedRows.length}
|
55
|
+
/>
|
25
56
|
<PageLayout
|
26
57
|
searchable
|
27
58
|
searchProps={TASKS_SEARCH_PROPS}
|
@@ -33,6 +64,12 @@ const TasksTablePage = ({ getBreadcrumbs, history, ...props }) => {
|
|
33
64
|
{props.status === STATUS.PENDING && <Spinner size="lg" loading />}
|
34
65
|
<ExportButton
|
35
66
|
url={addSearchToURL('/foreman_tasks/tasks.csv', uriQuery)}
|
67
|
+
title={__('Export All')}
|
68
|
+
/>
|
69
|
+
<ActionSelectButton
|
70
|
+
disabled={props.selectedRows.length < 1}
|
71
|
+
onCancel={props.showCancelSelcetedModal}
|
72
|
+
onResume={props.showResumeSelcetedModal}
|
36
73
|
/>
|
37
74
|
</React.Fragment>
|
38
75
|
}
|
@@ -46,18 +83,27 @@ const TasksTablePage = ({ getBreadcrumbs, history, ...props }) => {
|
|
46
83
|
};
|
47
84
|
|
48
85
|
TasksTablePage.propTypes = {
|
86
|
+
results: PropTypes.array.isRequired,
|
49
87
|
getTableItems: PropTypes.func.isRequired,
|
50
88
|
getBreadcrumbs: PropTypes.func.isRequired,
|
51
89
|
actionName: PropTypes.string,
|
52
90
|
isSubTask: PropTypes.bool,
|
53
91
|
status: PropTypes.oneOf(Object.keys(STATUS)),
|
54
92
|
history: PropTypes.object.isRequired,
|
93
|
+
actionSelected: PropTypes.func.isRequired,
|
94
|
+
selectedRows: PropTypes.arrayOf(PropTypes.string),
|
95
|
+
showResumeSelcetedModal: PropTypes.func.isRequired,
|
96
|
+
showCancelSelcetedModal: PropTypes.func.isRequired,
|
97
|
+
hideSelcetedModal: PropTypes.func.isRequired,
|
98
|
+
modalStatus: PropTypes.oneOf([CANCEL, RESUME, CLOSED]),
|
55
99
|
};
|
56
100
|
|
57
101
|
TasksTablePage.defaultProps = {
|
58
102
|
actionName: '',
|
59
103
|
isSubTask: false,
|
60
104
|
status: STATUS.PENDING,
|
105
|
+
selectedRows: [],
|
106
|
+
modalStatus: CLOSED,
|
61
107
|
};
|
62
108
|
|
63
109
|
export default TasksTablePage;
|
@@ -1,19 +1,26 @@
|
|
1
1
|
import Immutable from 'seamless-immutable';
|
2
2
|
import { combineReducers } from 'redux';
|
3
|
+
import { union } from 'lodash';
|
3
4
|
import { createTableReducer } from 'foremanReact/components/common/table';
|
4
5
|
import createTableActionTypes from 'foremanReact/components/common/table/actionsHelpers/actionTypeCreator';
|
5
|
-
import {
|
6
|
+
import {
|
7
|
+
TASKS_TABLE_ID,
|
8
|
+
SELECT_ROWS,
|
9
|
+
UNSELECT_ROWS,
|
10
|
+
UNSELECT_ALL_ROWS,
|
11
|
+
TASKS_TABLE_SELECTED_MODAL,
|
12
|
+
CLOSED,
|
13
|
+
} from './TasksTableConstants';
|
6
14
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
} = action;
|
15
|
+
const initialState = Immutable({
|
16
|
+
selectedRows: [],
|
17
|
+
modalStatus: CLOSED,
|
18
|
+
});
|
19
|
+
|
20
|
+
export const TasksTableQueryReducer = (state = initialState, action) => {
|
21
|
+
const { type, payload } = action;
|
22
|
+
const { subtotal, page, per_page: perPageString, action_name: actionName } =
|
23
|
+
payload || {};
|
17
24
|
const ACTION_TYPES = createTableActionTypes(TASKS_TABLE_ID);
|
18
25
|
switch (type) {
|
19
26
|
case ACTION_TYPES.SUCCESS:
|
@@ -24,7 +31,19 @@ export const TasksTableQueryReducer = (state = {}, action) => {
|
|
24
31
|
page: Number(page),
|
25
32
|
perPage: Number(perPageString),
|
26
33
|
},
|
34
|
+
selectedRows: [],
|
27
35
|
});
|
36
|
+
case SELECT_ROWS:
|
37
|
+
return state.set('selectedRows', union(payload, state.selectedRows));
|
38
|
+
case UNSELECT_ROWS:
|
39
|
+
return state.set(
|
40
|
+
'selectedRows',
|
41
|
+
state.selectedRows.filter(row => row !== payload)
|
42
|
+
);
|
43
|
+
case UNSELECT_ALL_ROWS:
|
44
|
+
return state.set('selectedRows', []);
|
45
|
+
case TASKS_TABLE_SELECTED_MODAL:
|
46
|
+
return state.set('modalStatus', payload);
|
28
47
|
default:
|
29
48
|
return state;
|
30
49
|
}
|
@@ -6,11 +6,13 @@ import {
|
|
6
6
|
} from 'foremanReact/components/common/table';
|
7
7
|
import { translate as __ } from 'foremanReact/common/I18n';
|
8
8
|
import {
|
9
|
-
|
10
|
-
|
9
|
+
selectionHeaderCellFormatter,
|
10
|
+
selectionCellFormatter,
|
11
11
|
actionNameCellFormatter,
|
12
12
|
durationCellFormmatter,
|
13
|
-
|
13
|
+
actionCellFormatter,
|
14
|
+
dateCellFormmatter,
|
15
|
+
} from './formatters';
|
14
16
|
|
15
17
|
const headFormat = [headerFormatterWithProps];
|
16
18
|
const cellFormat = [cellFormatter];
|
@@ -25,7 +27,14 @@ const cellFormat = [cellFormatter];
|
|
25
27
|
* @param {function} cancelTask A function to run when the cancel cell is clicked
|
26
28
|
* @return {Array}
|
27
29
|
*/
|
28
|
-
|
30
|
+
|
31
|
+
const createTasksTableSchema = (
|
32
|
+
setSort,
|
33
|
+
by,
|
34
|
+
order,
|
35
|
+
taskActions,
|
36
|
+
selectionController
|
37
|
+
) => {
|
29
38
|
const sortController = {
|
30
39
|
apply: setSort,
|
31
40
|
property: by,
|
@@ -33,6 +42,15 @@ const createTasksTableSchema = (setSort, by, order, taskActions) => {
|
|
33
42
|
};
|
34
43
|
|
35
44
|
return [
|
45
|
+
column(
|
46
|
+
'select',
|
47
|
+
'Select all rows',
|
48
|
+
[label => selectionHeaderCellFormatter(selectionController, label)],
|
49
|
+
[
|
50
|
+
(value, additionalData) =>
|
51
|
+
selectionCellFormatter(selectionController, additionalData),
|
52
|
+
]
|
53
|
+
),
|
36
54
|
column(
|
37
55
|
'action',
|
38
56
|
__('Action'),
|
@@ -53,7 +71,7 @@ const createTasksTableSchema = (setSort, by, order, taskActions) => {
|
|
53
71
|
durationCellFormmatter,
|
54
72
|
]),
|
55
73
|
column(
|
56
|
-
'
|
74
|
+
'availableActions',
|
57
75
|
__('Operation'),
|
58
76
|
headFormat,
|
59
77
|
[actionCellFormatter(taskActions)],
|