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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/lib/foreman_tasks/version.rb +1 -1
  3. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +3 -1
  4. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +2 -2
  5. data/webpack/ForemanTasks/Components/TaskDetails/index.js +1 -4
  6. data/webpack/ForemanTasks/Components/TasksDashboard/index.js +1 -4
  7. data/webpack/ForemanTasks/Components/TasksTable/Components/ActionConfirmation.js +49 -0
  8. data/webpack/ForemanTasks/Components/TasksTable/Components/ActionSelectButton.js +37 -0
  9. data/webpack/ForemanTasks/Components/TasksTable/Components/CancelResumeConfirm.js +51 -0
  10. data/webpack/ForemanTasks/Components/TasksTable/Components/TableSelectionCell.js +32 -0
  11. data/webpack/ForemanTasks/Components/TasksTable/Components/TableSelectionHeaderCell.js +38 -0
  12. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ActionConfirmation.test.js +18 -0
  13. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ActionSelectButton.test.js +13 -0
  14. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/CancelResumeConfirm.test.js +28 -0
  15. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/TableSelectionCell.test.js +15 -0
  16. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/TableSelectionHeaderCell.test.js +15 -0
  17. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ActionConfirmation.test.js.snap +89 -0
  18. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ActionSelectButton.test.js.snap +32 -0
  19. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/CancelResumeConfirm.test.js.snap +37 -0
  20. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/TableSelectionCell.test.js.snap +14 -0
  21. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/TableSelectionHeaderCell.test.js.snap +15 -0
  22. data/webpack/ForemanTasks/Components/TasksTable/TasksTable.js +29 -1
  23. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +78 -3
  24. data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +11 -0
  25. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +47 -1
  26. data/webpack/ForemanTasks/Components/TasksTable/TasksTableReducer.js +30 -11
  27. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSchema.js +23 -5
  28. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +8 -0
  29. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +9 -1
  30. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableActions.test.js +46 -1
  31. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableReducer.test.js +29 -1
  32. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +9 -5
  33. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +9 -5
  34. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableActions.test.js.snap +77 -17
  35. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +46 -10
  36. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableReducer.test.js.snap +62 -7
  37. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionCellFormatter.test.js.snap +14 -0
  38. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionNameCellFormatter.test.js.snap +9 -0
  39. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/dateCellFormmatter.test.js.snap +9 -0
  40. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/durationCellFormmatter.test.js.snap +18 -0
  41. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/selectionCellFormatter.test.js.snap +10 -0
  42. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/selectionHeaderCellFormatter.test.js.snap +10 -0
  43. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/actionCellFormatter.test.js +11 -0
  44. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/actionNameCellFormatter.test.js +8 -0
  45. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/dateCellFormmatter.test.js +7 -0
  46. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/durationCellFormmatter.test.js +12 -0
  47. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionCellFormatter.test.js +12 -0
  48. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionHeaderCellFormatter.test.js +12 -0
  49. data/webpack/ForemanTasks/Components/TasksTable/formatters/actionCellFormatter.js +16 -0
  50. data/webpack/ForemanTasks/Components/TasksTable/formatters/actionNameCellFormatter.js +5 -0
  51. data/webpack/ForemanTasks/Components/TasksTable/formatters/dateCellFormmatter.js +7 -0
  52. data/webpack/ForemanTasks/Components/TasksTable/formatters/durationCellFormmatter.js +7 -0
  53. data/webpack/ForemanTasks/Components/TasksTable/formatters/index.js +7 -0
  54. data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionCellFormatter.js +10 -0
  55. data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionHeaderCellFormatter.js +10 -0
  56. data/webpack/ForemanTasks/Components/TasksTable/index.js +5 -4
  57. data/webpack/__mocks__/foremanReact/components/common/table.js +1 -0
  58. metadata +36 -3
  59. 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 { TASKS_TABLE_ID } from './TasksTableConstants';
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}" ${__('task cancelled')}`,
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}" ${__('task cannot be cancelled at the moment.')}`,
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 { TASKS_SEARCH_PROPS } from './TasksTableConstants';
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 { TASKS_TABLE_ID } from './TasksTableConstants';
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
- export const TasksTableQueryReducer = (state = {}, action) => {
8
- const {
9
- type,
10
- payload: {
11
- subtotal,
12
- page,
13
- per_page: perPageString,
14
- action_name: actionName,
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
- dateCellFormmatter,
10
- actionCellFormatter,
9
+ selectionHeaderCellFormatter,
10
+ selectionCellFormatter,
11
11
  actionNameCellFormatter,
12
12
  durationCellFormmatter,
13
- } from './TaskTableFormmatters';
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
- const createTasksTableSchema = (setSort, by, order, taskActions) => {
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
- 'available_actions',
74
+ 'availableActions',
57
75
  __('Operation'),
58
76
  headFormat,
59
77
  [actionCellFormatter(taskActions)],