foreman-tasks 0.17.1 → 0.17.2

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 (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)],