foreman-tasks 1.1.2 → 2.0.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 (132) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/README.md +2 -0
  4. data/app/controllers/foreman_tasks/api/tasks_controller.rb +33 -1
  5. data/app/controllers/foreman_tasks/tasks_controller.rb +9 -14
  6. data/app/lib/actions/proxy_action.rb +1 -1
  7. data/app/models/foreman_tasks/task.rb +4 -0
  8. data/app/models/foreman_tasks/task/dynflow_task.rb +3 -1
  9. data/app/models/setting/foreman_tasks.rb +1 -1
  10. data/app/services/ui_notifications/tasks/task_bulk_stop.rb +36 -0
  11. data/app/views/foreman_tasks/api/tasks/details.json.rabl +0 -1
  12. data/app/views/foreman_tasks/api/tasks/show.json.rabl +2 -0
  13. data/config/routes.rb +1 -0
  14. data/db/migrate/20200517215015_rename_bookmarks_controller.rb +35 -0
  15. data/db/migrate/20200519093217_drop_dynflow_allow_dangerous_actions_setting.foreman_tasks.rb +5 -0
  16. data/db/migrate/20200611090846_add_task_lock_index_on_resource_type_and_task_id.rb +3 -3
  17. data/db/seeds.d/30-notification_blueprints.rb +7 -0
  18. data/lib/foreman_tasks/engine.rb +2 -7
  19. data/lib/foreman_tasks/version.rb +1 -1
  20. data/locale/action_names.rb +1 -1
  21. data/locale/en/LC_MESSAGES/foreman_tasks.mo +0 -0
  22. data/locale/en/foreman_tasks.po +270 -54
  23. data/locale/foreman_tasks.pot +630 -292
  24. data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
  25. data/locale/fr/foreman_tasks.po +817 -0
  26. data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
  27. data/locale/ja/foreman_tasks.po +817 -0
  28. data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
  29. data/locale/zh_CN/foreman_tasks.po +816 -0
  30. data/package.json +1 -0
  31. data/script/npm_link_foreman_js.sh +26 -0
  32. data/webpack/ForemanTasks/Components/TaskActions/TaskAction.test.js +60 -0
  33. data/webpack/ForemanTasks/Components/{TasksTable/TasksTableActionHelpers.js → TaskActions/TaskActionHelpers.js} +21 -6
  34. data/webpack/ForemanTasks/Components/{TasksTable/__tests__/TasksTableActionHelpers.test.js → TaskActions/TaskActionHelpers.test.js} +2 -2
  35. data/webpack/ForemanTasks/Components/TaskActions/TaskActionsConstants.js +16 -0
  36. data/webpack/ForemanTasks/Components/TaskActions/UnlockModals.js +60 -0
  37. data/webpack/ForemanTasks/Components/TaskActions/UnlockModals.test.js +14 -0
  38. data/webpack/ForemanTasks/Components/TaskActions/__snapshots__/TaskAction.test.js.snap +233 -0
  39. data/webpack/ForemanTasks/Components/TaskActions/__snapshots__/UnlockModals.test.js.snap +25 -0
  40. data/webpack/ForemanTasks/Components/TaskActions/index.js +115 -0
  41. data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +17 -3
  42. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +149 -167
  43. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +8 -1
  44. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +68 -3
  45. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskInfo.test.js +0 -1
  46. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/RunningSteps.test.js.snap +1 -1
  47. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +124 -76
  48. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +35 -5
  49. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +3 -14
  50. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +40 -16
  51. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +3 -4
  52. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +0 -6
  53. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +4 -10
  54. data/webpack/ForemanTasks/Components/TaskDetails/TasksDetailsHelper.js +6 -1
  55. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.fixtures.js +8 -0
  56. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +7 -1
  57. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +18 -2
  58. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +30 -13
  59. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +91 -0
  60. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +13 -4
  61. data/webpack/ForemanTasks/Components/TaskDetails/index.js +6 -8
  62. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardActions.js +1 -1
  63. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardActions.test.js +2 -2
  64. data/webpack/ForemanTasks/Components/TasksTable/Components/ActionSelectButton.js +14 -1
  65. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModal.js +83 -0
  66. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalActions.js +106 -0
  67. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalReducer.js +38 -0
  68. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalSelectors.js +46 -0
  69. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModal.test.js +36 -0
  70. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalActions.test.js +205 -0
  71. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalReducer.test.js +27 -0
  72. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalSelectors.test.js +55 -0
  73. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModal.test.js.snap +41 -0
  74. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalReducer.test.js.snap +19 -0
  75. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalSelectors.test.js.snap +32 -0
  76. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/index.js +29 -0
  77. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ActionSelectButton.test.js +1 -0
  78. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ActionSelectButton.test.js.snap +11 -0
  79. data/webpack/ForemanTasks/Components/TasksTable/TasksBulkActions.js +135 -35
  80. data/webpack/ForemanTasks/Components/TasksTable/TasksTable.js +13 -9
  81. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +26 -66
  82. data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +10 -12
  83. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +30 -96
  84. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSchema.js +2 -2
  85. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +8 -4
  86. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksBulkActions.test.js +50 -2
  87. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +3 -12
  88. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableActions.test.js +22 -26
  89. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTablePage.test.js +2 -1
  90. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +3 -14
  91. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksBulkActions.test.js.snap +155 -0
  92. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +3 -14
  93. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableActions.test.js.snap +17 -124
  94. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +63 -133
  95. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionCellFormatter.test.js.snap +1 -0
  96. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/selectionCellFormatter.test.js.snap +2 -0
  97. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/actionCellFormatter.test.js +1 -1
  98. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionCellFormatter.test.js +1 -1
  99. data/webpack/ForemanTasks/Components/TasksTable/formatters/actionCellFormatter.js +10 -7
  100. data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionCellFormatter.js +7 -0
  101. data/webpack/ForemanTasks/Components/TasksTable/index.js +2 -2
  102. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.js +55 -19
  103. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.test.js +75 -19
  104. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ActionButton.test.js.snap +88 -21
  105. data/webpack/ForemanTasks/Components/common/ClickConfirmation/ClickConfirmation.scss +9 -0
  106. data/webpack/ForemanTasks/Components/common/ClickConfirmation/ClickConfirmation.test.js +44 -0
  107. data/webpack/ForemanTasks/Components/common/ClickConfirmation/__snapshots__/ClickConfirmation.test.js.snap +52 -0
  108. data/webpack/ForemanTasks/Components/common/ClickConfirmation/index.js +59 -66
  109. data/webpack/ForemanTasks/Components/common/{ToastTypesConstants.js → ToastsHelpers/ToastTypesConstants.js} +0 -0
  110. data/webpack/ForemanTasks/Components/common/ToastsHelpers/index.js +15 -0
  111. data/webpack/ForemanTasks/ForemanTasksReducers.js +2 -0
  112. data/webpack/ForemanTasks/Routes/ForemanTasksRoutes.test.js +2 -1
  113. data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalHooks.js +2 -2
  114. data/webpack/__mocks__/foremanReact/components/ForemanModal/index.js +17 -3
  115. data/webpack/__mocks__/foremanReact/components/common/ActionButtons/ActionButtons.js +3 -0
  116. data/webpack/__mocks__/foremanReact/{API.js → redux/API.js} +1 -1
  117. metadata +41 -21
  118. data/webpack/ForemanTasks/Components/TasksTable/Components/CancelConfirm.js +0 -53
  119. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmationModals.js +0 -56
  120. data/webpack/ForemanTasks/Components/TasksTable/Components/ResumeConfirm.js +0 -52
  121. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/CancelConfirm.test.js +0 -26
  122. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ConfirmationModals.test.js +0 -24
  123. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ResumeConfirm.test.js +0 -26
  124. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/CancelConfirm.test.js.snap +0 -65
  125. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ConfirmationModals.test.js.snap +0 -30
  126. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ResumeConfirm.test.js.snap +0 -63
  127. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.js +0 -23
  128. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.test.js +0 -26
  129. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.js +0 -23
  130. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.test.js +0 -27
  131. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/CancelButton.test.js.snap +0 -15
  132. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ResumeButton.test.js.snap +0 -15
@@ -1,13 +1,14 @@
1
1
  import React from 'react';
2
2
 
3
- import API from 'foremanReact/API';
3
+ import { API } from 'foremanReact/redux/API';
4
4
  import { IntegrationTestHelper } from '@theforeman/test';
5
5
 
6
6
  import TaskDetails, { reducers } from '../index';
7
7
  import { selectForemanTasks } from '../../../ForemanTasksSelectors';
8
+ import { minProps } from './TaskDetails.fixtures';
8
9
 
9
10
  jest.mock('../../../ForemanTasksSelectors');
10
- jest.mock('foremanReact/API');
11
+ jest.mock('foremanReact/redux/API');
11
12
  selectForemanTasks.mockImplementation(state => state);
12
13
  describe('TaskDetails integration test', () => {
13
14
  beforeEach(() => {
@@ -15,6 +16,10 @@ describe('TaskDetails integration test', () => {
15
16
  const expectedIntervalId = 1;
16
17
  jest.useFakeTimers();
17
18
  setInterval.mockImplementation(() => expectedIntervalId);
19
+ delete window.location;
20
+ window.location = new URL(
21
+ 'https://foreman.com/foreman_tasks/tasks/a15dd820-32f1-4ced-9ab7-c0fab8234c47/'
22
+ );
18
23
  });
19
24
  it('should flow', async () => {
20
25
  window.location.reload = jest.fn();
@@ -22,7 +27,9 @@ describe('TaskDetails integration test', () => {
22
27
  API.get.mockImplementationOnce();
23
28
  const integrationTestHelper = new IntegrationTestHelper(reducers);
24
29
 
25
- const component = integrationTestHelper.mount(<TaskDetails id="test" />);
30
+ const component = integrationTestHelper.mount(
31
+ <TaskDetails {...minProps} id="test" />
32
+ );
26
33
  integrationTestHelper.takeStoreSnapshot('initial state');
27
34
 
28
35
  const reloadButton = component.find('.reload-button').at(0);
@@ -46,7 +53,9 @@ describe('TaskDetails integration test', () => {
46
53
  }));
47
54
  const integrationTestHelper = new IntegrationTestHelper(reducers);
48
55
 
49
- const component = integrationTestHelper.mount(<TaskDetails id="test" />);
56
+ const component = integrationTestHelper.mount(
57
+ <TaskDetails {...minProps} id="test" />
58
+ );
50
59
 
51
60
  const reloadButton = component.find('.reload-button').at(0);
52
61
  reloadButton.simulate('click');
@@ -1,7 +1,8 @@
1
1
  import { bindActionCreators } from 'redux';
2
2
  import { connect } from 'react-redux';
3
3
  import TaskDetails from './TaskDetails';
4
- import * as actions from './TaskDetailsActions';
4
+ import * as taskDetailsActions from './TaskDetailsActions';
5
+ import * as taskActions from '../TaskActions';
5
6
  import reducer from './TaskDetailsReducer';
6
7
  import {
7
8
  selectEndedAt,
@@ -22,7 +23,6 @@ import {
22
23
  selectFailedSteps,
23
24
  selectRunningSteps,
24
25
  selectHasSubTasks,
25
- selectAllowDangerousActions,
26
26
  selectUsernamePath,
27
27
  selectAction,
28
28
  selectState,
@@ -30,10 +30,9 @@ import {
30
30
  selectTimeoutId,
31
31
  selectTaskReload,
32
32
  selectParentTask,
33
- selectShowUnlockModal,
34
- selectShowForceUnlockModal,
35
33
  selectExternalId,
36
34
  selectDynflowEnableConsole,
35
+ selectCanEdit,
37
36
  } from './TaskDetailsSelectors';
38
37
 
39
38
  const mapStateToProps = state => ({
@@ -54,7 +53,6 @@ const mapStateToProps = state => ({
54
53
  runningSteps: selectRunningSteps(state),
55
54
  help: selectHelp(state),
56
55
  hasSubTasks: selectHasSubTasks(state),
57
- allowDangerousActions: selectAllowDangerousActions(state),
58
56
  locks: selectLocks(state),
59
57
  usernamePath: selectUsernamePath(state),
60
58
  action: selectAction(state),
@@ -63,13 +61,13 @@ const mapStateToProps = state => ({
63
61
  timeoutId: selectTimeoutId(state),
64
62
  taskReload: selectTaskReload(state),
65
63
  parentTask: selectParentTask(state),
66
- showUnlockModal: selectShowUnlockModal(state),
67
- showForceUnlockModal: selectShowForceUnlockModal(state),
68
64
  externalId: selectExternalId(state),
69
65
  dynflowEnableConsole: selectDynflowEnableConsole(state),
66
+ canEdit: selectCanEdit(state),
70
67
  });
71
68
 
72
- const mapDispatchToProps = dispatch => bindActionCreators(actions, dispatch);
69
+ const mapDispatchToProps = dispatch =>
70
+ bindActionCreators({ ...taskActions, ...taskDetailsActions }, dispatch);
73
71
 
74
72
  export const reducers = { taskDetails: reducer };
75
73
 
@@ -1,4 +1,4 @@
1
- import API from 'foremanReact/API';
1
+ import { API } from 'foremanReact/redux/API';
2
2
  import { timeToHoursNumber, resolveQuery } from './TasksDashboardHelper';
3
3
  import {
4
4
  FOREMAN_TASKS_DASHBOARD_INIT,
@@ -1,5 +1,5 @@
1
1
  import { testActionSnapshotWithFixtures } from '@theforeman/test';
2
- import API from 'foremanReact/API';
2
+ import { API } from 'foremanReact/redux/API';
3
3
  import { timeToHoursNumber } from '../TasksDashboardHelper';
4
4
  import {
5
5
  initializeDashboard,
@@ -14,7 +14,7 @@ import {
14
14
  apiGetMock,
15
15
  } from './TaskDashboard.fixtures';
16
16
 
17
- jest.mock('foremanReact/API');
17
+ jest.mock('foremanReact/redux/API');
18
18
  jest.mock('../TasksDashboardHelper');
19
19
 
20
20
  timeToHoursNumber.mockImplementation(arg => arg);
@@ -3,7 +3,12 @@ import { DropdownButton, MenuItem } from 'patternfly-react';
3
3
  import PropTypes from 'prop-types';
4
4
  import { translate as __ } from 'foremanReact/common/I18n';
5
5
 
6
- export const ActionSelectButton = ({ onCancel, onResume, disabled }) => (
6
+ export const ActionSelectButton = ({
7
+ onCancel,
8
+ onResume,
9
+ onForceCancel,
10
+ disabled,
11
+ }) => (
7
12
  <DropdownButton
8
13
  title={__('Select Action')}
9
14
  disabled={disabled}
@@ -23,6 +28,13 @@ export const ActionSelectButton = ({ onCancel, onResume, disabled }) => (
23
28
  >
24
29
  {__('Resume Selected')}
25
30
  </MenuItem>
31
+ <MenuItem
32
+ title={__('Force Cancel selected tasks')}
33
+ onClick={onForceCancel}
34
+ eventKey="3"
35
+ >
36
+ {__('Force Cancel Selected')}
37
+ </MenuItem>
26
38
  </DropdownButton>
27
39
  );
28
40
 
@@ -30,6 +42,7 @@ ActionSelectButton.propTypes = {
30
42
  disabled: PropTypes.bool,
31
43
  onCancel: PropTypes.func.isRequired,
32
44
  onResume: PropTypes.func.isRequired,
45
+ onForceCancel: PropTypes.func.isRequired,
33
46
  };
34
47
 
35
48
  ActionSelectButton.defaultProps = {
@@ -0,0 +1,83 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { startCase } from 'lodash';
4
+ import { sprintf, translate as __ } from 'foremanReact/common/I18n';
5
+ import { Button } from 'patternfly-react';
6
+ import ForemanModal from 'foremanReact/components/ForemanModal';
7
+ import { FORCE_UNLOCK_MODAL } from '../../../TaskActions/TaskActionsConstants';
8
+ import { FORCE_UNLOCK_SELECTED_MODAL } from '../../TasksTableConstants';
9
+ import { ForceUnlockModal } from '../../../TaskActions/UnlockModals';
10
+
11
+ export const ConfirmModal = ({
12
+ actionText,
13
+ actionState,
14
+ actionType,
15
+ selectedRowsLen,
16
+ id,
17
+ parentTaskID,
18
+ url,
19
+ uriQuery: query,
20
+ setModalClosed,
21
+ ...props
22
+ }) => {
23
+ if ([FORCE_UNLOCK_MODAL, FORCE_UNLOCK_SELECTED_MODAL].includes(actionType)) {
24
+ return (
25
+ <ForceUnlockModal
26
+ onClick={() => {
27
+ props[actionType]({ url, query, parentTaskID });
28
+ setModalClosed();
29
+ }}
30
+ id={id}
31
+ selectedRowsLen={selectedRowsLen}
32
+ />
33
+ );
34
+ }
35
+ return (
36
+ <ForemanModal
37
+ title={sprintf(__('%s Selected Tasks'), startCase(actionText))}
38
+ id={id}
39
+ >
40
+ {sprintf(
41
+ __(
42
+ `This will %(action)s %(number)s task(s), putting them in the %(state)s state. Are you sure?`
43
+ ),
44
+ { action: actionText, number: selectedRowsLen, state: actionState }
45
+ )}
46
+ <ForemanModal.Footer>
47
+ <Button onClick={setModalClosed}>{__('No')}</Button>
48
+ <Button
49
+ className="confirm-button"
50
+ bsStyle="primary"
51
+ onClick={() => {
52
+ props[actionType]({ url, query, parentTaskID });
53
+ setModalClosed();
54
+ }}
55
+ >
56
+ {__('Yes')}
57
+ </Button>
58
+ </ForemanModal.Footer>
59
+ </ForemanModal>
60
+ );
61
+ };
62
+
63
+ ConfirmModal.propTypes = {
64
+ actionText: PropTypes.string,
65
+ actionState: PropTypes.string,
66
+ selectedRowsLen: PropTypes.number.isRequired,
67
+ actionType: PropTypes.string,
68
+ id: PropTypes.string.isRequired,
69
+ parentTaskID: PropTypes.string,
70
+ url: PropTypes.string.isRequired,
71
+ uriQuery: PropTypes.object,
72
+ setModalClosed: PropTypes.func.isRequired,
73
+ };
74
+
75
+ ConfirmModal.defaultProps = {
76
+ actionType: '',
77
+ actionText: '',
78
+ actionState: '',
79
+ parentTaskID: '',
80
+ uriQuery: {},
81
+ };
82
+
83
+ export default ConfirmModal;
@@ -0,0 +1,106 @@
1
+ import {
2
+ resumeTask,
3
+ cancelTask,
4
+ forceCancelTask,
5
+ } from '../../TasksTableActions';
6
+ import {
7
+ bulkCancelBySearch,
8
+ bulkCancelById,
9
+ bulkResumeBySearch,
10
+ bulkResumeById,
11
+ bulkForceCancelBySearch,
12
+ bulkForceCancelById,
13
+ } from '../../TasksBulkActions';
14
+ import { selectClicked, selectSelectedTasks } from './ConfirmModalSelectors';
15
+ import { selectAllRowsSelected } from '../../TasksTableSelectors';
16
+ import {
17
+ CANCEL_MODAL,
18
+ RESUME_MODAL,
19
+ CANCEL_SELECTED_MODAL,
20
+ RESUME_SELECTED_MODAL,
21
+ FORCE_UNLOCK_SELECTED_MODAL,
22
+ } from '../../TasksTableConstants';
23
+ import { FORCE_UNLOCK_MODAL } from '../../../TaskActions/TaskActionsConstants';
24
+
25
+ export default {
26
+ [CANCEL_SELECTED_MODAL]: ({ url, query, parentTaskID }) => (
27
+ dispatch,
28
+ getState
29
+ ) => {
30
+ if (selectAllRowsSelected(getState())) {
31
+ return dispatch(bulkCancelBySearch({ query, parentTaskID }));
32
+ }
33
+ return dispatch(
34
+ bulkCancelById({
35
+ selected: selectSelectedTasks(getState()),
36
+ url,
37
+ parentTaskID,
38
+ })
39
+ );
40
+ },
41
+ [CANCEL_MODAL]: ({ url, parentTaskID }) => (dispatch, getState) => {
42
+ const { taskId, taskName } = selectClicked(getState());
43
+ return dispatch(
44
+ cancelTask({
45
+ taskId,
46
+ taskName,
47
+ url,
48
+ parentTaskID,
49
+ })
50
+ );
51
+ },
52
+ [RESUME_SELECTED_MODAL]: ({ url, query, parentTaskID }) => (
53
+ dispatch,
54
+ getState
55
+ ) => {
56
+ if (selectAllRowsSelected(getState())) {
57
+ return dispatch(bulkResumeBySearch({ query, parentTaskID }));
58
+ }
59
+ return dispatch(
60
+ bulkResumeById({
61
+ selected: selectSelectedTasks(getState()),
62
+ url,
63
+ parentTaskID,
64
+ })
65
+ );
66
+ },
67
+
68
+ [RESUME_MODAL]: ({ url, parentTaskID }) => (dispatch, getState) => {
69
+ const { taskId, taskName } = selectClicked(getState());
70
+ return dispatch(
71
+ resumeTask({
72
+ taskId,
73
+ taskName,
74
+ url,
75
+ parentTaskID,
76
+ })
77
+ );
78
+ },
79
+
80
+ [FORCE_UNLOCK_MODAL]: ({ url, parentTaskID }) => (dispatch, getState) => {
81
+ const { taskId, taskName } = selectClicked(getState());
82
+ return dispatch(
83
+ forceCancelTask({
84
+ taskId,
85
+ taskName,
86
+ url,
87
+ parentTaskID,
88
+ })
89
+ );
90
+ },
91
+ [FORCE_UNLOCK_SELECTED_MODAL]: ({ url, query, parentTaskID }) => (
92
+ dispatch,
93
+ getState
94
+ ) => {
95
+ if (selectAllRowsSelected(getState())) {
96
+ return dispatch(bulkForceCancelBySearch({ query, parentTaskID }));
97
+ }
98
+ return dispatch(
99
+ bulkForceCancelById({
100
+ selected: selectSelectedTasks(getState()),
101
+ url,
102
+ parentTaskID,
103
+ })
104
+ );
105
+ },
106
+ };
@@ -0,0 +1,38 @@
1
+ import Immutable from 'seamless-immutable';
2
+ import {
3
+ UPDATE_MODAL,
4
+ CANCEL_SELECTED_MODAL,
5
+ RESUME_SELECTED_MODAL,
6
+ RESUME_MODAL,
7
+ CANCEL_MODAL,
8
+ } from '../../TasksTableConstants';
9
+
10
+ const initialState = Immutable({});
11
+
12
+ export const ConfirmModalReducer = (state = initialState, action) => {
13
+ const { type, payload } = action;
14
+ switch (type) {
15
+ case UPDATE_MODAL:
16
+ switch (payload.modalID) {
17
+ case CANCEL_SELECTED_MODAL:
18
+ case CANCEL_MODAL:
19
+ return state.merge({
20
+ actionText: 'cancel',
21
+ actionState: 'stopped',
22
+ actionType: payload.modalID,
23
+ });
24
+ case RESUME_SELECTED_MODAL:
25
+ case RESUME_MODAL:
26
+ return state.merge({
27
+ actionText: 'resume',
28
+ actionState: 'running',
29
+ actionType: payload.modalID,
30
+ });
31
+ default:
32
+ return state.set('actionType', payload.modalID);
33
+ }
34
+ default:
35
+ return state;
36
+ }
37
+ };
38
+ export default ConfirmModalReducer;
@@ -0,0 +1,46 @@
1
+ import { selectForemanTasks } from '../../../../ForemanTasksSelectors';
2
+ import {
3
+ selectTasksTableQuery,
4
+ selectResults,
5
+ selectSelectedRows,
6
+ selectItemCount,
7
+ selectAllRowsSelected,
8
+ } from '../../TasksTableSelectors';
9
+ import { RESUME_MODAL, CANCEL_MODAL } from '../../TasksTableConstants';
10
+ import { FORCE_UNLOCK_MODAL } from '../../../TaskActions/TaskActionsConstants';
11
+
12
+ export const selectCofirmModal = state =>
13
+ selectForemanTasks(state).confirmModal || {};
14
+
15
+ export const selectActionType = state => selectCofirmModal(state).actionType;
16
+ export const selectActionText = state => selectCofirmModal(state).actionText;
17
+ export const selectActionState = state => selectCofirmModal(state).actionState;
18
+ export const selectClicked = state =>
19
+ selectTasksTableQuery(state).clicked || {};
20
+
21
+ export const selectSelectedTasks = state => {
22
+ const selectedIDs = selectResults(state).filter(item =>
23
+ selectSelectedRows(state).includes(item.id)
24
+ );
25
+ return selectedIDs.map(item => ({
26
+ name: item.action,
27
+ id: item.id,
28
+ isCancellable: item.availableActions.cancellable,
29
+ isResumable: item.availableActions.resumable,
30
+ canEdit: item.canEdit,
31
+ }));
32
+ };
33
+
34
+ export const selectSelectedRowsLen = state => {
35
+ if (
36
+ [CANCEL_MODAL, RESUME_MODAL, FORCE_UNLOCK_MODAL].includes(
37
+ selectActionType(state)
38
+ )
39
+ ) {
40
+ return 1;
41
+ }
42
+ if (selectAllRowsSelected(state)) {
43
+ return selectItemCount(state);
44
+ }
45
+ return selectSelectedRows(state).length;
46
+ };
@@ -0,0 +1,36 @@
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
+ import { ConfirmModal } from '../ConfirmModal';
3
+ import { RESUME_SELECTED_MODAL } from '../../../TasksTableConstants';
4
+ import { FORCE_UNLOCK_MODAL } from '../../../../TaskActions/TaskActionsConstants';
5
+
6
+ const fixtures = {
7
+ 'renders ConfirmModal': {
8
+ actionType: RESUME_SELECTED_MODAL,
9
+ actionText: 'some text',
10
+ actionState: 'some state',
11
+ selectedRowsLen: 1,
12
+ id: 'modalID',
13
+ parentTaskID: 'parent-id',
14
+ allRowsSelected: true,
15
+ url: 'some-url',
16
+ uriQuery: { state: 'stopped' },
17
+ setModalClosed: jest.fn(),
18
+ },
19
+
20
+ 'renders ConfirmModal for unlock ': {
21
+ actionType: FORCE_UNLOCK_MODAL,
22
+ actionText: 'some text',
23
+ actionState: 'some state',
24
+ selectedRowsLen: 1,
25
+ id: 'modalID',
26
+ parentTaskID: 'parent-id',
27
+ allRowsSelected: true,
28
+ url: 'some-url',
29
+ uriQuery: { state: 'stopped' },
30
+ setModalClosed: jest.fn(),
31
+ },
32
+ };
33
+
34
+ describe('ConfirmModal', () => {
35
+ testComponentSnapshotsWithFixtures(ConfirmModal, fixtures);
36
+ });