foreman-tasks 1.1.2 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,25 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`ForceUnlockModal render 1`] = `
4
+ <ClickConfirmation
5
+ body="Resources for 1 task(s) will be unlocked and will not prevent other tasks from being run. As the task(s) might be still running, it should be avoided to use this unless you are really sure the task(s) got stuck."
6
+ confirmAction="Force Unlock"
7
+ confirmType="danger"
8
+ confirmationMessage="I understand that this may cause harm and have working database backups of all backend services."
9
+ id="forceUnlockModal"
10
+ onClick={[MockFunction]}
11
+ title="Force Unlock"
12
+ />
13
+ `;
14
+
15
+ exports[`UnlockModal render 1`] = `
16
+ <ClickConfirmation
17
+ body="This will unlock the resources that the task is running against. Please note that this might lead to inconsistent state and should be used with caution, after making sure that the task can't be resumed."
18
+ confirmAction="Unlock"
19
+ confirmType="warning"
20
+ confirmationMessage="I understand that this may cause harm and have working database backups of all backend services."
21
+ id="unlockModal"
22
+ onClick={[MockFunction]}
23
+ title="Unlock"
24
+ />
25
+ `;
@@ -0,0 +1,115 @@
1
+ import { sprintf } from 'foremanReact/common/I18n';
2
+ import { API } from 'foremanReact/redux/API';
3
+ import { addToast } from 'foremanReact/redux/actions/toasts';
4
+ import {
5
+ TASKS_RESUME_REQUEST,
6
+ TASKS_RESUME_SUCCESS,
7
+ TASKS_RESUME_FAILURE,
8
+ TASKS_CANCEL_REQUEST,
9
+ TASKS_CANCEL_SUCCESS,
10
+ TASKS_CANCEL_FAILURE,
11
+ TASKS_FORCE_CANCEL_REQUEST,
12
+ TASKS_FORCE_CANCEL_SUCCESS,
13
+ TASKS_FORCE_CANCEL_FAILURE,
14
+ TASKS_UNLOCK_REQUEST,
15
+ TASKS_UNLOCK_SUCCESS,
16
+ TASKS_UNLOCK_FAILURE,
17
+ } from './TaskActionsConstants';
18
+ import { infoToastData } from '../common/ToastsHelpers/';
19
+ import {
20
+ resumeToastInfo,
21
+ cancelToastInfo,
22
+ forceCancelToastInfo,
23
+ unlockToastInfo,
24
+ toastDispatch,
25
+ } from './TaskActionHelpers';
26
+
27
+ export const cancelTaskRequest = (id, name) => async dispatch => {
28
+ dispatch(addToast(infoToastData(sprintf('Trying to cancel %s task', name))));
29
+ dispatch({ type: TASKS_CANCEL_REQUEST });
30
+ try {
31
+ await API.post(`/foreman_tasks/tasks/${id}/cancel`);
32
+ dispatch({ type: TASKS_CANCEL_SUCCESS });
33
+ toastDispatch({
34
+ type: 'cancelled',
35
+ name,
36
+ toastInfo: cancelToastInfo,
37
+ dispatch,
38
+ });
39
+ } catch (error) {
40
+ dispatch({ type: TASKS_CANCEL_FAILURE, payload: error });
41
+ toastDispatch({
42
+ type: 'skipped',
43
+ name,
44
+ toastInfo: cancelToastInfo,
45
+ dispatch,
46
+ });
47
+ }
48
+ };
49
+
50
+ export const resumeTaskRequest = (id, name) => async dispatch => {
51
+ dispatch({ type: TASKS_RESUME_REQUEST });
52
+ try {
53
+ await API.post(`/foreman_tasks/tasks/${id}/resume`);
54
+
55
+ dispatch({ type: TASKS_RESUME_SUCCESS });
56
+ toastDispatch({
57
+ type: 'resumed',
58
+ name,
59
+ toastInfo: resumeToastInfo,
60
+ dispatch,
61
+ });
62
+ } catch (error) {
63
+ dispatch({ type: TASKS_RESUME_FAILURE, payload: error });
64
+ toastDispatch({
65
+ type: 'failed',
66
+ name,
67
+ toastInfo: resumeToastInfo,
68
+ dispatch,
69
+ });
70
+ }
71
+ };
72
+
73
+ export const forceCancelTaskRequest = (id, name) => async dispatch => {
74
+ dispatch({ type: TASKS_FORCE_CANCEL_REQUEST });
75
+ try {
76
+ await API.post(`/foreman_tasks/tasks/${id}/force_unlock`);
77
+ dispatch({ type: TASKS_FORCE_CANCEL_SUCCESS });
78
+ toastDispatch({
79
+ type: 'forceCancelled',
80
+ name,
81
+ toastInfo: forceCancelToastInfo,
82
+ dispatch,
83
+ });
84
+ } catch ({ response }) {
85
+ dispatch({ type: TASKS_FORCE_CANCEL_FAILURE });
86
+ toastDispatch({
87
+ type: 'failed',
88
+ name,
89
+ toastInfo: forceCancelToastInfo,
90
+ dispatch,
91
+ });
92
+ }
93
+ };
94
+
95
+ export const unlockTaskRequest = (id, name) => async dispatch => {
96
+ dispatch({ type: TASKS_UNLOCK_REQUEST });
97
+ try {
98
+ await API.post(`/foreman_tasks/tasks/${id}/unlock`);
99
+ dispatch({ type: TASKS_UNLOCK_SUCCESS });
100
+ toastDispatch({
101
+ type: 'unlocked',
102
+ name,
103
+ toastInfo: unlockToastInfo,
104
+ dispatch,
105
+ });
106
+ } catch ({ response }) {
107
+ dispatch({ type: TASKS_UNLOCK_FAILURE });
108
+ toastDispatch({
109
+ type: 'failed',
110
+ name,
111
+ toastInfo: unlockToastInfo,
112
+ dispatch,
113
+ });
114
+ }
115
+ };
@@ -3,7 +3,13 @@ import PropTypes from 'prop-types';
3
3
  import { Alert, Button } from 'patternfly-react';
4
4
  import { translate as __ } from 'foremanReact/common/I18n';
5
5
 
6
- const RunningSteps = ({ runningSteps }) => {
6
+ const RunningSteps = ({
7
+ runningSteps,
8
+ id,
9
+ cancelStep,
10
+ taskReload,
11
+ taskProgressToggle,
12
+ }) => {
7
13
  if (!runningSteps.length) return <span>{__('No running steps')}</span>;
8
14
  return (
9
15
  <div>
@@ -13,8 +19,12 @@ const RunningSteps = ({ runningSteps }) => {
13
19
  <p>
14
20
  <Button
15
21
  bsSize="small"
16
- data-method="post"
17
- href={`/foreman_tasks/tasks/${step.id}/cancel_step`}
22
+ onClick={() => {
23
+ if (!taskReload) {
24
+ taskProgressToggle();
25
+ }
26
+ cancelStep(id, step.id);
27
+ }}
18
28
  >
19
29
  {__('Cancel')}
20
30
  </Button>
@@ -46,6 +56,10 @@ const RunningSteps = ({ runningSteps }) => {
46
56
 
47
57
  RunningSteps.propTypes = {
48
58
  runningSteps: PropTypes.array,
59
+ id: PropTypes.string.isRequired,
60
+ cancelStep: PropTypes.func.isRequired,
61
+ taskReload: PropTypes.bool.isRequired,
62
+ taskProgressToggle: PropTypes.func.isRequired,
49
63
  };
50
64
 
51
65
  RunningSteps.defaultProps = {
@@ -1,178 +1,169 @@
1
- import React, { Component } from 'react';
1
+ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { Grid, Row, Col, Button } from 'patternfly-react';
4
4
  import { translate as __ } from 'foremanReact/common/I18n';
5
+ import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
5
6
  import TaskInfo from './TaskInfo';
6
- import { ClickConfirmation } from '../../common/ClickConfirmation';
7
- import { ResumeButton } from '../../common/ActionButtons/ResumeButton';
8
- import { CancelButton } from '../../common/ActionButtons/CancelButton';
7
+ import {
8
+ UNLOCK_MODAL,
9
+ FORCE_UNLOCK_MODAL,
10
+ } from '../../TaskActions/TaskActionsConstants';
11
+ import { ForceUnlockModal, UnlockModal } from '../../TaskActions/UnlockModals';
9
12
 
10
- class Task extends Component {
11
- taskProgressToggle = () => {
12
- const {
13
- timeoutId,
14
- refetchTaskDetails,
15
- id,
16
- loading,
17
- taskReloadStop,
18
- taskReloadStart,
19
- } = this.props;
20
- if (timeoutId) {
21
- taskReloadStop(timeoutId);
22
- } else {
23
- taskReloadStart(timeoutId, refetchTaskDetails, id, loading);
13
+ const Task = props => {
14
+ const unlockModalActions = useForemanModal({
15
+ id: UNLOCK_MODAL,
16
+ });
17
+ const forceUnlockModalActions = useForemanModal({
18
+ id: FORCE_UNLOCK_MODAL,
19
+ });
20
+
21
+ const {
22
+ taskReload,
23
+ externalId,
24
+ id,
25
+ state,
26
+ resumable,
27
+ cancellable,
28
+ hasSubTasks,
29
+ parentTask,
30
+ cancelTaskRequest,
31
+ resumeTaskRequest,
32
+ forceCancelTaskRequest,
33
+ unlockTaskRequest,
34
+ action,
35
+ dynflowEnableConsole,
36
+ taskProgressToggle,
37
+ canEdit,
38
+ } = props;
39
+ const forceUnlock = () => {
40
+ if (!taskReload) {
41
+ taskProgressToggle();
24
42
  }
43
+ forceCancelTaskRequest(id, action);
25
44
  };
26
-
27
- render() {
28
- const {
29
- taskReload,
30
- externalId,
31
- id,
32
- state,
33
- allowDangerousActions,
34
- resumable,
35
- cancellable,
36
- hasSubTasks,
37
- parentTask,
38
- showUnlockModal,
39
- showForceUnlockModal,
40
- toggleUnlockModal,
41
- toggleForceUnlockModal,
42
- cancelTaskRequest,
43
- resumeTaskRequest,
44
- action,
45
- dynflowEnableConsole,
46
- } = this.props;
47
- const modalUnlock = (
48
- <ClickConfirmation
49
- showModal={showUnlockModal}
50
- title={__('Unlock')}
51
- body={__(
52
- "This will unlock the resources that the task is running against. Please note that this might lead to inconsistent state and should be used with caution, after making sure that the task can't be resumed."
53
- )}
54
- confirmationMessage={__(
55
- 'I understand that this may cause harm and have working database backups of all backend services.'
56
- )}
57
- confirmAction={__('Unlock')}
58
- path={`/foreman_tasks/tasks/${id}/unlock`}
59
- confirmType="warning"
60
- closeModal={toggleUnlockModal}
61
- />
62
- );
63
-
64
- const modalForceUnlock = (
65
- <ClickConfirmation
66
- showModal={showForceUnlockModal}
67
- title={__('Force Unlock')}
68
- body={__(
69
- 'Resources will be unlocked and will not prevent other tasks from being run. As the task might be still running, it should be avoided to use this unless you are really sure the task got stuck'
70
- )}
71
- confirmationMessage={__(
72
- 'I understand that this may cause harm and have working database backups of all backend services.'
73
- )}
74
- confirmAction={__('Force Unlock')}
75
- path={`/foreman_tasks/tasks/${id}/force_unlock`}
76
- confirmType="danger"
77
- closeModal={toggleForceUnlockModal}
78
- />
79
- );
80
- return (
81
- <React.Fragment>
82
- {modalUnlock}
83
- {modalForceUnlock}
84
- <Grid>
85
- <Row>
86
- <Col xs={12}>
45
+ const unlock = () => {
46
+ if (!taskReload) {
47
+ taskProgressToggle();
48
+ }
49
+ unlockTaskRequest(id, action);
50
+ };
51
+ const editActionsTitle = canEdit
52
+ ? undefined
53
+ : __('You do not have permission');
54
+ const dynflowTitle = dynflowEnableConsole
55
+ ? undefined
56
+ : `dynflow_enable_console ${__('Setting is off')}`;
57
+ return (
58
+ <React.Fragment>
59
+ <UnlockModal onClick={unlock} />
60
+ <ForceUnlockModal onClick={forceUnlock} />
61
+ <Grid>
62
+ <Row>
63
+ <Col xs={12}>
64
+ <Button
65
+ className="reload-button"
66
+ bsSize="small"
67
+ onClick={taskProgressToggle}
68
+ >
69
+ <span
70
+ className={`glyphicon glyphicon-refresh ${
71
+ taskReload ? 'spin' : ''
72
+ }`}
73
+ />
74
+ {__(`${taskReload ? 'Stop' : 'Start'} auto-reloading`)}
75
+ </Button>
76
+ <Button
77
+ className="dynflow-button"
78
+ bsSize="small"
79
+ href={`/foreman_tasks/dynflow/${externalId}`}
80
+ disabled={!dynflowEnableConsole}
81
+ rel="noopener noreferrer"
82
+ target="_blank"
83
+ >
84
+ <span title={dynflowTitle} data-original-title={dynflowTitle}>
85
+ {__('Dynflow console')}
86
+ </span>
87
+ </Button>
88
+ <Button
89
+ className="resume-button"
90
+ bsSize="small"
91
+ title={editActionsTitle}
92
+ data-original-title={editActionsTitle}
93
+ disabled={!canEdit || !resumable}
94
+ onClick={() => {
95
+ if (!taskReload) {
96
+ taskProgressToggle();
97
+ }
98
+ resumeTaskRequest(id, action);
99
+ }}
100
+ >
101
+ {__('Resume')}
102
+ </Button>
103
+ <Button
104
+ className="cancel-button"
105
+ bsSize="small"
106
+ title={editActionsTitle}
107
+ data-original-title={editActionsTitle}
108
+ disabled={!canEdit || !cancellable}
109
+ onClick={() => {
110
+ if (!taskReload) {
111
+ taskProgressToggle();
112
+ }
113
+ cancelTaskRequest(id, action);
114
+ }}
115
+ >
116
+ {__('Cancel')}
117
+ </Button>
118
+ {parentTask && (
87
119
  <Button
88
- hidden={!allowDangerousActions}
89
- className="reload-button"
120
+ className="parent-button"
90
121
  bsSize="small"
91
- onClick={this.taskProgressToggle}
122
+ href={`/foreman_tasks/tasks/${parentTask}`}
92
123
  >
93
- <span
94
- className={`glyphicon glyphicon-refresh ${
95
- taskReload ? 'spin' : ''
96
- }`}
97
- />
98
- {__(`${taskReload ? 'Stop' : 'Start'} auto-reloading`)}
124
+ {__('Parent task')}
99
125
  </Button>
126
+ )}
127
+ {hasSubTasks && (
100
128
  <Button
129
+ className="subtask-button"
101
130
  bsSize="small"
102
- href={`/foreman_tasks/dynflow/${externalId}`}
103
- disabled={!dynflowEnableConsole}
131
+ href={`/foreman_tasks/tasks/${id}/sub_tasks`}
104
132
  >
105
- {__('Dynflow console')}
133
+ {__('Sub tasks')}
106
134
  </Button>
107
- <ResumeButton
108
- id={id}
109
- onClick={() => {
110
- if (!taskReload) {
111
- this.taskProgressToggle();
112
- }
113
- resumeTaskRequest(id, action);
114
- }}
115
- name={action}
116
- disabled={!resumable}
117
- />
118
- <CancelButton
119
- id={id}
120
- name={action}
121
- disabled={!cancellable}
122
- onClick={() => {
123
- if (!taskReload) {
124
- this.taskProgressToggle();
125
- }
126
- cancelTaskRequest(id, action);
127
- }}
128
- />
129
- {parentTask && (
130
- <Button
131
- bsSize="small"
132
- href={`/foreman_tasks/tasks/${parentTask}`}
133
- >
134
- {__('Parent task')}
135
- </Button>
136
- )}
137
- {hasSubTasks && (
138
- <Button
139
- bsSize="small"
140
- href={`/foreman_tasks/tasks/${id}/sub_tasks`}
141
- >
142
- {__('Sub tasks')}
143
- </Button>
144
- )}
145
- {allowDangerousActions && (
146
- <Button
147
- bsSize="small"
148
- disabled={state !== 'paused'}
149
- onClick={toggleUnlockModal}
150
- >
151
- {__('Unlock')}
152
- </Button>
153
- )}
154
- {allowDangerousActions && (
155
- <Button
156
- bsSize="small"
157
- disabled={state === 'stopped'}
158
- onClick={toggleForceUnlockModal}
159
- >
160
- {__('Force Unlock')}
161
- </Button>
162
- )}
163
- </Col>
164
- </Row>
165
- <TaskInfo {...this.props} />
166
- </Grid>
167
- </React.Fragment>
168
- );
169
- }
170
- }
135
+ )}
136
+ <Button
137
+ className="unlock-button"
138
+ bsSize="small"
139
+ disabled={!canEdit || state !== 'paused'}
140
+ onClick={unlockModalActions.setModalOpen}
141
+ title={editActionsTitle}
142
+ data-original-title={editActionsTitle}
143
+ >
144
+ {__('Unlock')}
145
+ </Button>
146
+ <Button
147
+ className="force-unlock-button"
148
+ bsSize="small"
149
+ disabled={!canEdit || state === 'stopped'}
150
+ onClick={forceUnlockModalActions.setModalOpen}
151
+ title={editActionsTitle}
152
+ data-original-title={editActionsTitle}
153
+ >
154
+ {__('Force Unlock')}
155
+ </Button>
156
+ </Col>
157
+ </Row>
158
+ <TaskInfo {...props} />
159
+ </Grid>
160
+ </React.Fragment>
161
+ );
162
+ };
171
163
 
172
164
  Task.propTypes = {
173
165
  ...TaskInfo.PropTypes,
174
166
  state: PropTypes.string,
175
- allowDangerousActions: PropTypes.bool,
176
167
  resumable: PropTypes.bool,
177
168
  cancellable: PropTypes.bool,
178
169
  refetchTaskDetails: PropTypes.func,
@@ -180,23 +171,18 @@ Task.propTypes = {
180
171
  parentTask: PropTypes.string,
181
172
  taskReload: PropTypes.bool,
182
173
  taskReloadStop: PropTypes.func,
183
- taskReloadStart: PropTypes.func,
184
174
  timeoutId: PropTypes.number,
185
175
  externalId: PropTypes.string,
186
176
  id: PropTypes.string.isRequired,
187
- showUnlockModal: PropTypes.bool,
188
- showForceUnlockModal: PropTypes.bool,
189
- toggleUnlockModal: PropTypes.func,
190
- toggleForceUnlockModal: PropTypes.func,
191
177
  cancelTaskRequest: PropTypes.func,
192
178
  resumeTaskRequest: PropTypes.func,
193
179
  dynflowEnableConsole: PropTypes.bool,
180
+ canEdit: PropTypes.bool,
194
181
  };
195
182
 
196
183
  Task.defaultProps = {
197
184
  ...TaskInfo.defaultProps,
198
185
  state: '',
199
- allowDangerousActions: false,
200
186
  resumable: false,
201
187
  cancellable: false,
202
188
  refetchTaskDetails: () => null,
@@ -204,16 +190,12 @@ Task.defaultProps = {
204
190
  parentTask: '',
205
191
  taskReload: false,
206
192
  taskReloadStop: () => null,
207
- taskReloadStart: () => null,
208
193
  timeoutId: null,
209
194
  externalId: '',
210
- showUnlockModal: false,
211
- showForceUnlockModal: false,
212
- toggleUnlockModal: () => null,
213
- toggleForceUnlockModal: () => null,
214
195
  cancelTaskRequest: () => null,
215
196
  resumeTaskRequest: () => null,
216
197
  dynflowEnableConsole: false,
198
+ canEdit: false,
217
199
  };
218
200
 
219
201
  export default Task;