foreman-tasks 1.1.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (189) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/js_tests.yml +27 -0
  3. data/.github/workflows/ruby_tests.yml +74 -0
  4. data/.rubocop.yml +12 -4
  5. data/.rubocop_todo.yml +32 -25
  6. data/Gemfile +5 -0
  7. data/README.md +2 -0
  8. data/app/controllers/foreman_tasks/api/tasks_controller.rb +63 -58
  9. data/app/controllers/foreman_tasks/concerns/parameters/triggering.rb +1 -1
  10. data/app/controllers/foreman_tasks/recurring_logics_controller.rb +7 -0
  11. data/app/controllers/foreman_tasks/tasks_controller.rb +9 -14
  12. data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +3 -3
  13. data/app/lib/actions/proxy_action.rb +1 -1
  14. data/app/models/foreman_tasks/recurring_logic.rb +1 -1
  15. data/app/models/foreman_tasks/task.rb +15 -0
  16. data/app/models/foreman_tasks/task/dynflow_task.rb +29 -33
  17. data/app/models/foreman_tasks/task/status_explicator.rb +1 -1
  18. data/app/models/foreman_tasks/triggering.rb +1 -1
  19. data/app/models/setting/foreman_tasks.rb +2 -2
  20. data/app/services/ui_notifications/tasks/task_bulk_stop.rb +36 -0
  21. data/app/views/foreman_tasks/api/tasks/details.json.rabl +0 -1
  22. data/app/views/foreman_tasks/api/tasks/index.json.rabl +2 -0
  23. data/app/views/foreman_tasks/api/tasks/show.json.rabl +2 -0
  24. data/app/views/foreman_tasks/recurring_logics/index.html.erb +3 -1
  25. data/config/routes.rb +3 -1
  26. data/db/migrate/20200517215015_rename_bookmarks_controller.rb +35 -0
  27. data/db/migrate/20200519093217_drop_dynflow_allow_dangerous_actions_setting.foreman_tasks.rb +5 -0
  28. data/db/migrate/20200611090846_add_task_lock_index_on_resource_type_and_task_id.rb +1 -1
  29. data/db/seeds.d/30-notification_blueprints.rb +14 -7
  30. data/db/seeds.d/61-foreman_tasks_bookmarks.rb +1 -1
  31. data/lib/foreman_tasks/cleaner.rb +4 -6
  32. data/lib/foreman_tasks/dynflow/configuration.rb +1 -1
  33. data/lib/foreman_tasks/dynflow/persistence.rb +4 -6
  34. data/lib/foreman_tasks/engine.rb +3 -8
  35. data/lib/foreman_tasks/version.rb +1 -1
  36. data/locale/action_names.rb +1 -1
  37. data/locale/en/LC_MESSAGES/foreman_tasks.mo +0 -0
  38. data/locale/en/foreman_tasks.po +270 -54
  39. data/locale/foreman_tasks.pot +630 -292
  40. data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
  41. data/locale/fr/foreman_tasks.po +817 -0
  42. data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
  43. data/locale/ja/foreman_tasks.po +817 -0
  44. data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
  45. data/locale/zh_CN/foreman_tasks.po +816 -0
  46. data/package.json +1 -1
  47. data/script/npm_link_foreman_js.sh +26 -0
  48. data/test/controllers/api/recurring_logics_controller_test.rb +1 -1
  49. data/test/controllers/api/tasks_controller_test.rb +7 -7
  50. data/test/controllers/tasks_controller_test.rb +6 -6
  51. data/test/core/unit/runner_test.rb +20 -20
  52. data/test/core/unit/task_launcher_test.rb +8 -8
  53. data/test/helpers/foreman_tasks/foreman_tasks_helper_test.rb +7 -7
  54. data/test/helpers/foreman_tasks/tasks_helper_test.rb +3 -3
  55. data/test/lib/actions/middleware/keep_current_request_id_test.rb +3 -3
  56. data/test/support/history_tasks_builder.rb +1 -1
  57. data/test/tasks/generate_task_actions_test.rb +1 -1
  58. data/test/unit/actions/action_with_sub_plans_test.rb +2 -2
  59. data/test/unit/actions/bulk_action_test.rb +6 -6
  60. data/test/unit/actions/proxy_action_test.rb +20 -20
  61. data/test/unit/actions/recurring_action_test.rb +30 -32
  62. data/test/unit/cleaner_test.rb +24 -24
  63. data/test/unit/dashboard_table_filter_test.rb +5 -5
  64. data/test/unit/otp_manager_test.rb +2 -2
  65. data/test/unit/proxy_selector_test.rb +9 -9
  66. data/test/unit/recurring_logic_test.rb +32 -32
  67. data/test/unit/remote_task_test.rb +2 -2
  68. data/test/unit/task_groups_test.rb +4 -4
  69. data/test/unit/task_test.rb +18 -18
  70. data/test/unit/triggering_test.rb +8 -8
  71. data/test/unit/troubleshooting_help_generator_test.rb +6 -6
  72. data/test/unit/ui_notifications_test.rb +11 -11
  73. data/webpack/ForemanTasks/Components/TaskActions/TaskAction.test.js +60 -0
  74. data/webpack/ForemanTasks/Components/{TasksTable/TasksTableActionHelpers.js → TaskActions/TaskActionHelpers.js} +21 -6
  75. data/webpack/ForemanTasks/Components/{TasksTable/__tests__/TasksTableActionHelpers.test.js → TaskActions/TaskActionHelpers.test.js} +2 -2
  76. data/webpack/ForemanTasks/Components/TaskActions/TaskActionsConstants.js +16 -0
  77. data/webpack/ForemanTasks/Components/TaskActions/UnlockModals.js +60 -0
  78. data/webpack/ForemanTasks/Components/TaskActions/UnlockModals.test.js +14 -0
  79. data/webpack/ForemanTasks/Components/TaskActions/__snapshots__/TaskAction.test.js.snap +233 -0
  80. data/webpack/ForemanTasks/Components/TaskActions/__snapshots__/UnlockModals.test.js.snap +25 -0
  81. data/webpack/ForemanTasks/Components/TaskActions/index.js +115 -0
  82. data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +17 -3
  83. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +38 -205
  84. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskButtons.js +168 -0
  85. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +6 -7
  86. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskSkeleton.js +48 -0
  87. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +8 -1
  88. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +14 -7
  89. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskButtons.test.js +95 -0
  90. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskInfo.test.js +0 -1
  91. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/RunningSteps.test.js.snap +1 -1
  92. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +90 -189
  93. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskButtons.test.js.snap +212 -0
  94. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +8 -4
  95. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +100 -53
  96. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +3 -14
  97. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +57 -110
  98. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +3 -17
  99. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +57 -37
  100. data/webpack/ForemanTasks/Components/TaskDetails/TasksDetailsHelper.js +6 -1
  101. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.fixtures.js +8 -0
  102. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +13 -1
  103. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +6 -6
  104. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +86 -19
  105. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +25 -21
  106. data/webpack/ForemanTasks/Components/TaskDetails/index.js +12 -11
  107. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardActions.js +1 -1
  108. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardActions.test.js +2 -2
  109. data/webpack/ForemanTasks/Components/TasksTable/Components/ActionSelectButton.js +14 -1
  110. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModal.js +83 -0
  111. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalActions.js +106 -0
  112. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalReducer.js +38 -0
  113. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalSelectors.js +46 -0
  114. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModal.test.js +36 -0
  115. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalActions.test.js +205 -0
  116. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalReducer.test.js +27 -0
  117. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalSelectors.test.js +55 -0
  118. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModal.test.js.snap +41 -0
  119. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalReducer.test.js.snap +19 -0
  120. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalSelectors.test.js.snap +32 -0
  121. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/index.js +29 -0
  122. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ActionSelectButton.test.js +1 -0
  123. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ActionSelectButton.test.js.snap +11 -0
  124. data/webpack/ForemanTasks/Components/TasksTable/TasksBulkActions.js +135 -35
  125. data/webpack/ForemanTasks/Components/TasksTable/TasksTable.js +13 -9
  126. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +26 -66
  127. data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +10 -12
  128. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +30 -96
  129. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSchema.js +2 -2
  130. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +8 -4
  131. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksBulkActions.test.js +50 -2
  132. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +3 -12
  133. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableActions.test.js +22 -26
  134. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTablePage.test.js +2 -1
  135. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +3 -14
  136. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksBulkActions.test.js.snap +155 -0
  137. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +3 -14
  138. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableActions.test.js.snap +17 -124
  139. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +63 -133
  140. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionCellFormatter.test.js.snap +1 -0
  141. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/selectionCellFormatter.test.js.snap +2 -0
  142. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/actionCellFormatter.test.js +1 -1
  143. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionCellFormatter.test.js +1 -1
  144. data/webpack/ForemanTasks/Components/TasksTable/formatters/actionCellFormatter.js +10 -7
  145. data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionCellFormatter.js +7 -0
  146. data/webpack/ForemanTasks/Components/TasksTable/index.js +2 -2
  147. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.js +55 -19
  148. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.test.js +75 -19
  149. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ActionButton.test.js.snap +88 -21
  150. data/webpack/ForemanTasks/Components/common/ClickConfirmation/ClickConfirmation.scss +9 -0
  151. data/webpack/ForemanTasks/Components/common/ClickConfirmation/ClickConfirmation.test.js +44 -0
  152. data/webpack/ForemanTasks/Components/common/ClickConfirmation/__snapshots__/ClickConfirmation.test.js.snap +52 -0
  153. data/webpack/ForemanTasks/Components/common/ClickConfirmation/index.js +59 -66
  154. data/webpack/ForemanTasks/Components/common/{ToastTypesConstants.js → ToastsHelpers/ToastTypesConstants.js} +0 -0
  155. data/webpack/ForemanTasks/Components/common/ToastsHelpers/index.js +15 -0
  156. data/webpack/ForemanTasks/Components/common/urlHelpers.js +7 -0
  157. data/webpack/ForemanTasks/ForemanTasksReducers.js +2 -2
  158. data/webpack/ForemanTasks/Routes/ForemanTasksRoutes.test.js +2 -1
  159. data/webpack/__mocks__/foremanReact/common/helpers.js +2 -0
  160. data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalHooks.js +2 -2
  161. data/webpack/__mocks__/foremanReact/components/ForemanModal/index.js +17 -3
  162. data/webpack/__mocks__/foremanReact/components/common/ActionButtons/ActionButtons.js +3 -0
  163. data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +10 -0
  164. data/webpack/__mocks__/foremanReact/redux/API/index.js +10 -0
  165. data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware.js +5 -0
  166. metadata +51 -28
  167. data/.travis.yml +0 -5
  168. data/script/travis_run_js_tests.sh +0 -7
  169. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +0 -44
  170. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsReducer.test.js +0 -33
  171. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsReducer.test.js.snap +0 -26
  172. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/integration.test.js.snap +0 -122
  173. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +0 -63
  174. data/webpack/ForemanTasks/Components/TasksTable/Components/CancelConfirm.js +0 -53
  175. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmationModals.js +0 -56
  176. data/webpack/ForemanTasks/Components/TasksTable/Components/ResumeConfirm.js +0 -52
  177. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/CancelConfirm.test.js +0 -26
  178. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ConfirmationModals.test.js +0 -24
  179. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ResumeConfirm.test.js +0 -26
  180. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/CancelConfirm.test.js.snap +0 -65
  181. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ConfirmationModals.test.js.snap +0 -30
  182. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ResumeConfirm.test.js.snap +0 -63
  183. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.js +0 -23
  184. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.test.js +0 -26
  185. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.js +0 -23
  186. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.test.js +0 -27
  187. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/CancelButton.test.js.snap +0 -15
  188. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ResumeButton.test.js.snap +0 -15
  189. data/webpack/__mocks__/foremanReact/API.js +0 -7
@@ -0,0 +1,168 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { Col, Button } from 'patternfly-react';
4
+ import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
5
+ import { translate as __ } from 'foremanReact/common/I18n';
6
+ import {
7
+ UNLOCK_MODAL,
8
+ FORCE_UNLOCK_MODAL,
9
+ } from '../../TaskActions/TaskActionsConstants';
10
+
11
+ export const TaskButtons = ({
12
+ canEdit,
13
+ dynflowEnableConsole,
14
+ taskReloadStart,
15
+ taskProgressToggle,
16
+ taskReload,
17
+ externalId,
18
+ id,
19
+ action,
20
+ state,
21
+ resumable,
22
+ cancellable,
23
+ hasSubTasks,
24
+ parentTask,
25
+ cancelTaskRequest,
26
+ resumeTaskRequest,
27
+ }) => {
28
+ const unlockModalActions = useForemanModal({
29
+ id: UNLOCK_MODAL,
30
+ });
31
+ const forceUnlockModalActions = useForemanModal({
32
+ id: FORCE_UNLOCK_MODAL,
33
+ });
34
+ const editActionsTitle = canEdit
35
+ ? undefined
36
+ : __('You do not have permission');
37
+ const dynflowTitle = dynflowEnableConsole
38
+ ? undefined
39
+ : `dynflow_enable_console ${__('Setting is off')}`;
40
+
41
+ return (
42
+ <Col xs={12}>
43
+ <Button
44
+ className="reload-button"
45
+ bsSize="small"
46
+ onClick={taskProgressToggle}
47
+ >
48
+ <span
49
+ className={`glyphicon glyphicon-refresh ${taskReload ? 'spin' : ''}`}
50
+ />
51
+ {__(`${taskReload ? 'Stop' : 'Start'} auto-reloading`)}
52
+ </Button>
53
+ <Button
54
+ className="dynflow-button"
55
+ bsSize="small"
56
+ href={`/foreman_tasks/dynflow/${externalId}`}
57
+ disabled={!dynflowEnableConsole}
58
+ rel="noopener noreferrer"
59
+ target="_blank"
60
+ >
61
+ <span title={dynflowTitle} data-original-title={dynflowTitle}>
62
+ {__('Dynflow console')}
63
+ </span>
64
+ </Button>
65
+ <Button
66
+ className="resume-button"
67
+ bsSize="small"
68
+ title={editActionsTitle}
69
+ data-original-title={editActionsTitle}
70
+ disabled={!canEdit || !resumable}
71
+ onClick={() => {
72
+ if (!taskReload) {
73
+ taskReloadStart(id);
74
+ }
75
+ resumeTaskRequest(id, action);
76
+ }}
77
+ >
78
+ {__('Resume')}
79
+ </Button>
80
+ <Button
81
+ className="cancel-button"
82
+ bsSize="small"
83
+ title={editActionsTitle}
84
+ data-original-title={editActionsTitle}
85
+ disabled={!canEdit || !cancellable}
86
+ onClick={() => {
87
+ if (!taskReload) {
88
+ taskReloadStart(id);
89
+ }
90
+ cancelTaskRequest(id, action);
91
+ }}
92
+ >
93
+ {__('Cancel')}
94
+ </Button>
95
+ {parentTask && (
96
+ <Button
97
+ className="parent-button"
98
+ bsSize="small"
99
+ href={`/foreman_tasks/tasks/${parentTask}`}
100
+ >
101
+ {__('Parent task')}
102
+ </Button>
103
+ )}
104
+ {hasSubTasks && (
105
+ <Button
106
+ className="subtask-button"
107
+ bsSize="small"
108
+ href={`/foreman_tasks/tasks/${id}/sub_tasks`}
109
+ >
110
+ {__('Sub tasks')}
111
+ </Button>
112
+ )}
113
+ <Button
114
+ className="unlock-button"
115
+ bsSize="small"
116
+ disabled={!canEdit || state !== 'paused'}
117
+ onClick={unlockModalActions.setModalOpen}
118
+ title={editActionsTitle}
119
+ data-original-title={editActionsTitle}
120
+ >
121
+ {__('Unlock')}
122
+ </Button>
123
+ <Button
124
+ className="force-unlock-button"
125
+ bsSize="small"
126
+ disabled={!canEdit || state === 'stopped'}
127
+ onClick={forceUnlockModalActions.setModalOpen}
128
+ title={editActionsTitle}
129
+ data-original-title={editActionsTitle}
130
+ >
131
+ {__('Force Unlock')}
132
+ </Button>
133
+ </Col>
134
+ );
135
+ };
136
+
137
+ TaskButtons.propTypes = {
138
+ canEdit: PropTypes.bool,
139
+ dynflowEnableConsole: PropTypes.bool,
140
+ taskReloadStart: PropTypes.func.isRequired,
141
+ taskProgressToggle: PropTypes.func.isRequired,
142
+ taskReload: PropTypes.bool,
143
+ externalId: PropTypes.string,
144
+ id: PropTypes.string.isRequired,
145
+ action: PropTypes.string,
146
+ state: PropTypes.string,
147
+ resumable: PropTypes.bool,
148
+ cancellable: PropTypes.bool,
149
+ hasSubTasks: PropTypes.bool,
150
+ parentTask: PropTypes.string,
151
+ cancelTaskRequest: PropTypes.func,
152
+ resumeTaskRequest: PropTypes.func,
153
+ };
154
+
155
+ TaskButtons.defaultProps = {
156
+ canEdit: false,
157
+ dynflowEnableConsole: false,
158
+ taskReload: false,
159
+ externalId: '',
160
+ action: '',
161
+ state: '',
162
+ resumable: false,
163
+ cancellable: false,
164
+ hasSubTasks: false,
165
+ parentTask: '',
166
+ cancelTaskRequest: () => null,
167
+ resumeTaskRequest: () => null,
168
+ };
@@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
3
3
  import { Grid, Row, Col, ProgressBar } from 'patternfly-react';
4
4
  import { translate as __ } from 'foremanReact/common/I18n';
5
5
  import RelativeDateTime from 'foremanReact/components/common/dates/RelativeDateTime';
6
- import ReactHtmlParser from 'react-html-parser';
7
6
 
8
7
  class TaskInfo extends Component {
9
8
  isDelayed = () => {
@@ -59,7 +58,7 @@ class TaskInfo extends Component {
59
58
  state,
60
59
  help,
61
60
  output,
62
- error,
61
+ errors,
63
62
  progress,
64
63
  username,
65
64
  usernamePath,
@@ -171,7 +170,7 @@ class TaskInfo extends Component {
171
170
  <b>{__('Troubleshooting')}</b>
172
171
  </span>
173
172
  </p>
174
- <p>{ReactHtmlParser(help)}</p>
173
+ <p dangerouslySetInnerHTML={{ __html: help }} />
175
174
  </Col>
176
175
  </Row>
177
176
  )}
@@ -187,7 +186,7 @@ class TaskInfo extends Component {
187
186
  </Col>
188
187
  </Row>
189
188
  )}
190
- {error && error.length > 0 && (
189
+ {errors && errors.length > 0 && (
191
190
  <Row>
192
191
  <Col xs={12}>
193
192
  <div>
@@ -195,7 +194,7 @@ class TaskInfo extends Component {
195
194
  <b>{__('Errors:')}</b>
196
195
  </span>
197
196
  </div>
198
- <pre>{error}</pre>
197
+ <pre>{errors}</pre>
199
198
  </Col>
200
199
  </Row>
201
200
  )}
@@ -213,7 +212,7 @@ TaskInfo.propTypes = {
213
212
  startedAt: PropTypes.string,
214
213
  state: PropTypes.string,
215
214
  help: PropTypes.string,
216
- error: PropTypes.array,
215
+ errors: PropTypes.array,
217
216
  progress: PropTypes.number,
218
217
  username: PropTypes.string,
219
218
  usernamePath: PropTypes.string,
@@ -232,7 +231,7 @@ TaskInfo.defaultProps = {
232
231
  startedAt: '',
233
232
  state: '',
234
233
  help: '',
235
- error: [],
234
+ errors: [],
236
235
  progress: 0,
237
236
  username: '',
238
237
  usernamePath: '',
@@ -0,0 +1,48 @@
1
+ import React from 'react';
2
+ import Skeleton from 'react-loading-skeleton';
3
+ import { Grid, Row, Col } from 'patternfly-react';
4
+
5
+ export const TaskSkeleton = () => {
6
+ const details = [1, 2, 3, 4, 5, 6];
7
+ return (
8
+ <Grid>
9
+ <br />
10
+ <Row>
11
+ <Col>
12
+ <Skeleton />
13
+ </Col>
14
+ </Row>
15
+ {details.map((items, key) => (
16
+ <Row key={key}>
17
+ <Col md={2} sm={6}>
18
+ <Skeleton />
19
+ </Col>
20
+ <Col md={5} sm={6}>
21
+ <Skeleton />
22
+ </Col>
23
+ <Col md={2} sm={6}>
24
+ <Skeleton />
25
+ </Col>
26
+ <Col md={3} sm={6}>
27
+ <Skeleton />
28
+ </Col>
29
+ </Row>
30
+ ))}
31
+ <br />
32
+ <Row>
33
+ <Col xs={6}>
34
+ <div className="progress-description">
35
+ <Skeleton />
36
+ </div>
37
+ </Col>
38
+ <Col xs={3} xsOffset={3} className="progress-label-top-right">
39
+ <Skeleton />
40
+ </Col>
41
+ <Col xs={12}>
42
+ <Skeleton />
43
+ </Col>
44
+ </Row>
45
+ <br />
46
+ </Grid>
47
+ );
48
+ };
@@ -2,9 +2,16 @@ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
2
 
3
3
  import RunningSteps from '../RunningSteps';
4
4
 
5
+ const minProps = {
6
+ id: 'task-id1',
7
+ taskReload: true,
8
+ cancelStep: jest.fn(),
9
+ taskReloadStart: jest.fn(),
10
+ };
5
11
  const fixtures = {
6
- 'render without Props': {},
12
+ 'render with min Props': minProps,
7
13
  'render with Props': {
14
+ ...minProps,
8
15
  executionPlan: {
9
16
  state: 'paused',
10
17
  cancellable: false,
@@ -1,19 +1,26 @@
1
1
  import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
-
2
+ import { STATUS } from 'foremanReact/constants';
3
3
  import Task from '../Task';
4
4
 
5
5
  const fixtures = {
6
- 'render without Props': { id: 'test' },
6
+ 'render with minimal Props': {
7
+ id: 'test',
8
+ taskReloadStart: jest.fn(),
9
+ taskProgressToggle: jest.fn(),
10
+ },
7
11
  'render with some Props': {
8
12
  id: 'test',
9
13
  state: 'paused',
10
14
  hasSubTasks: true,
11
- allowDangerousActions: true,
12
15
  dynflowEnableConsole: true,
16
+ parentTask: 'parent-id',
17
+ taskReload: true,
18
+ canEdit: true,
19
+ status: STATUS.RESOLVED,
20
+ taskProgressToggle: jest.fn(),
21
+ taskReloadStart: jest.fn(),
13
22
  },
14
23
  };
15
24
 
16
- describe('Task', () => {
17
- describe('rendering', () =>
18
- testComponentSnapshotsWithFixtures(Task, fixtures));
19
- });
25
+ describe('Task rendering', () =>
26
+ testComponentSnapshotsWithFixtures(Task, fixtures));
@@ -0,0 +1,95 @@
1
+ import React from 'react';
2
+ import {
3
+ testComponentSnapshotsWithFixtures,
4
+ mount,
5
+ shallow,
6
+ } from '@theforeman/test';
7
+ import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
8
+ import { STATUS } from 'foremanReact/constants';
9
+ import { TaskButtons } from '../TaskButtons';
10
+ import {
11
+ UNLOCK_MODAL,
12
+ FORCE_UNLOCK_MODAL,
13
+ } from '../../../TaskActions/TaskActionsConstants';
14
+
15
+ const fixtures = {
16
+ 'render with minimal Props': {
17
+ id: 'test',
18
+ taskReloadStart: jest.fn(),
19
+ taskProgressToggle: jest.fn(),
20
+ },
21
+ 'render with some Props': {
22
+ id: 'test',
23
+ state: 'paused',
24
+ hasSubTasks: true,
25
+ dynflowEnableConsole: true,
26
+ parentTask: 'parent-id',
27
+ taskReload: true,
28
+ canEdit: true,
29
+ status: STATUS.RESOLVED,
30
+ taskReloadStart: jest.fn(),
31
+ taskProgressToggle: jest.fn(),
32
+ },
33
+ };
34
+
35
+ describe('Task', () => {
36
+ describe('rendering', () =>
37
+ testComponentSnapshotsWithFixtures(TaskButtons, fixtures));
38
+ describe('click test', () => {
39
+ const setModalOpen = jest.fn();
40
+ useForemanModal.mockImplementation(id => ({
41
+ setModalOpen: () => setModalOpen(id),
42
+ }));
43
+ const cancelTaskRequest = jest.fn();
44
+ const resumeTaskRequest = jest.fn();
45
+ const taskProgressToggle = jest.fn();
46
+ const taskReloadStart = jest.fn();
47
+ const id = 'some-id';
48
+ const action = 'some-action';
49
+ const props = {
50
+ taskReload: false,
51
+ id,
52
+ action,
53
+ cancelTaskRequest,
54
+ resumeTaskRequest,
55
+ taskProgressToggle,
56
+ taskReloadStart,
57
+ status: STATUS.RESOLVED,
58
+ };
59
+ afterEach(() => {
60
+ jest.clearAllMocks();
61
+ });
62
+ it('reload', () => {
63
+ const component = mount(<TaskButtons {...props} />);
64
+ const reloadButton = component.find('.reload-button').at(0);
65
+ reloadButton.simulate('click');
66
+ expect(taskProgressToggle).toBeCalled();
67
+ });
68
+ it('resume', () => {
69
+ const component = shallow(<TaskButtons {...props} />);
70
+ const resumeButton = component.find('.resume-button').at(0);
71
+ resumeButton.props().onClick();
72
+ expect(taskReloadStart).toBeCalled();
73
+ expect(resumeTaskRequest).toBeCalledWith(id, action);
74
+ });
75
+ it('cancel', () => {
76
+ const component = shallow(<TaskButtons {...props} />);
77
+ const cancelButton = component.find('.cancel-button').at(0);
78
+ cancelButton.props().onClick();
79
+ expect(taskReloadStart).toBeCalled();
80
+ expect(cancelTaskRequest).toBeCalledWith(id, action);
81
+ });
82
+ it('unlock', () => {
83
+ const component = shallow(<TaskButtons {...props} />);
84
+ const unlockButton = component.find('.unlock-button').at(0);
85
+ unlockButton.props().onClick();
86
+ expect(setModalOpen).toBeCalledWith({ id: UNLOCK_MODAL });
87
+ });
88
+ it('focrce unlock', () => {
89
+ const component = shallow(<TaskButtons {...props} />);
90
+ const forceUnlockButton = component.find('.force-unlock-button').at(0);
91
+ forceUnlockButton.props().onClick();
92
+ expect(setModalOpen).toBeCalledWith({ id: FORCE_UNLOCK_MODAL });
93
+ });
94
+ });
95
+ });
@@ -41,7 +41,6 @@ const fixtures = {
41
41
  help:
42
42
  "A paused task represents a process that has not finished properly. Any task in paused state can lead to potential inconsistency and needs to be resolved.\nThe recommended approach is to investigate the error messages below and in 'errors' tab, address the primary cause of the issue and resume the task.",
43
43
  hasSubTasks: false,
44
- allowDangerousActions: false,
45
44
  locks: [
46
45
  {
47
46
  name: 'task_owner',
@@ -55,7 +55,7 @@ exports[`RunningSteps rendering render with Props 1`] = `
55
55
  </div>
56
56
  `;
57
57
 
58
- exports[`RunningSteps rendering render without Props 1`] = `
58
+ exports[`RunningSteps rendering render with min Props 1`] = `
59
59
  <span>
60
60
  No running steps
61
61
  </span>
@@ -1,26 +1,15 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`Task rendering render with some Props 1`] = `
3
+ exports[`Task rendering render with minimal Props 1`] = `
4
4
  <Fragment>
5
- <ClickConfirmation
6
- 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."
7
- closeModal={[Function]}
8
- confirmAction="Unlock"
9
- confirmType="warning"
10
- confirmationMessage="I understand that this may cause harm and have working database backups of all backend services."
11
- path="/foreman_tasks/tasks/test/unlock"
12
- showModal={false}
13
- title="Unlock"
5
+ <UnlockModal
6
+ id="unlockModal"
7
+ onClick={[Function]}
14
8
  />
15
- <ClickConfirmation
16
- body="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"
17
- closeModal={[Function]}
18
- confirmAction="Force Unlock"
19
- confirmType="danger"
20
- confirmationMessage="I understand that this may cause harm and have working database backups of all backend services."
21
- path="/foreman_tasks/tasks/test/force_unlock"
22
- showModal={false}
23
- title="Force Unlock"
9
+ <ForceUnlockModal
10
+ id="forceUnlockModal"
11
+ onClick={[Function]}
12
+ selectedRowsLen={1}
24
13
  />
25
14
  <Grid
26
15
  bsClass="container"
@@ -31,116 +20,60 @@ exports[`Task rendering render with some Props 1`] = `
31
20
  bsClass="row"
32
21
  componentClass="div"
33
22
  >
34
- <Col
35
- bsClass="col"
36
- componentClass="div"
37
- xs={12}
38
- >
39
- <Button
40
- active={false}
41
- block={false}
42
- bsClass="btn"
43
- bsSize="small"
44
- bsStyle="default"
45
- className="reload-button"
46
- disabled={false}
47
- hidden={false}
48
- onClick={[Function]}
49
- >
50
- <span
51
- className="glyphicon glyphicon-refresh "
52
- />
53
- Start auto-reloading
54
- </Button>
55
- <Button
56
- active={false}
57
- block={false}
58
- bsClass="btn"
59
- bsSize="small"
60
- bsStyle="default"
61
- disabled={false}
62
- href="/foreman_tasks/dynflow/"
63
- >
64
- Dynflow console
65
- </Button>
66
- <ResumeButton
67
- disabled={true}
68
- id="test"
69
- name=""
70
- onClick={[Function]}
71
- />
72
- <CancelButton
73
- disabled={true}
74
- id="test"
75
- name=""
76
- onClick={[Function]}
77
- />
78
- <Button
79
- active={false}
80
- block={false}
81
- bsClass="btn"
82
- bsSize="small"
83
- bsStyle="default"
84
- disabled={false}
85
- href="/foreman_tasks/tasks/test/sub_tasks"
86
- >
87
- Sub tasks
88
- </Button>
89
- <Button
90
- active={false}
91
- block={false}
92
- bsClass="btn"
93
- bsSize="small"
94
- bsStyle="default"
95
- disabled={false}
96
- onClick={[Function]}
97
- >
98
- Unlock
99
- </Button>
100
- <Button
101
- active={false}
102
- block={false}
103
- bsClass="btn"
104
- bsSize="small"
105
- bsStyle="default"
106
- disabled={false}
107
- onClick={[Function]}
108
- >
109
- Force Unlock
110
- </Button>
111
- </Col>
23
+ <TaskButtons
24
+ action=""
25
+ canEdit={false}
26
+ cancelTaskRequest={[Function]}
27
+ cancellable={false}
28
+ dynflowEnableConsole={false}
29
+ endedAt=""
30
+ errors={Array []}
31
+ externalId=""
32
+ hasSubTasks={false}
33
+ help=""
34
+ id="test"
35
+ output=""
36
+ parentTask=""
37
+ progress={0}
38
+ result="error"
39
+ resumable={false}
40
+ resumeTaskRequest={[Function]}
41
+ startAt=""
42
+ startBefore=""
43
+ startedAt=""
44
+ state=""
45
+ taskProgressToggle={[MockFunction]}
46
+ taskReload={false}
47
+ taskReloadStart={[MockFunction]}
48
+ username=""
49
+ usernamePath=""
50
+ />
112
51
  </Row>
113
52
  <TaskInfo
114
53
  action=""
115
- allowDangerousActions={true}
54
+ canEdit={false}
116
55
  cancelTaskRequest={[Function]}
117
56
  cancellable={false}
118
- dynflowEnableConsole={true}
57
+ dynflowEnableConsole={false}
119
58
  endedAt=""
120
- error={Array []}
59
+ errors={Array []}
121
60
  externalId=""
122
- hasSubTasks={true}
61
+ hasSubTasks={false}
123
62
  help=""
124
63
  id="test"
125
64
  output=""
126
65
  parentTask=""
127
66
  progress={0}
128
- refetchTaskDetails={[Function]}
129
67
  result="error"
130
68
  resumable={false}
131
69
  resumeTaskRequest={[Function]}
132
- showForceUnlockModal={false}
133
- showUnlockModal={false}
134
70
  startAt=""
135
71
  startBefore=""
136
72
  startedAt=""
137
- state="paused"
73
+ state=""
74
+ taskProgressToggle={[MockFunction]}
138
75
  taskReload={false}
139
- taskReloadStart={[Function]}
140
- taskReloadStop={[Function]}
141
- timeoutId={null}
142
- toggleForceUnlockModal={[Function]}
143
- toggleUnlockModal={[Function]}
76
+ taskReloadStart={[MockFunction]}
144
77
  username=""
145
78
  usernamePath=""
146
79
  />
@@ -148,27 +81,16 @@ exports[`Task rendering render with some Props 1`] = `
148
81
  </Fragment>
149
82
  `;
150
83
 
151
- exports[`Task rendering render without Props 1`] = `
84
+ exports[`Task rendering render with some Props 1`] = `
152
85
  <Fragment>
153
- <ClickConfirmation
154
- 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."
155
- closeModal={[Function]}
156
- confirmAction="Unlock"
157
- confirmType="warning"
158
- confirmationMessage="I understand that this may cause harm and have working database backups of all backend services."
159
- path="/foreman_tasks/tasks/test/unlock"
160
- showModal={false}
161
- title="Unlock"
86
+ <UnlockModal
87
+ id="unlockModal"
88
+ onClick={[Function]}
162
89
  />
163
- <ClickConfirmation
164
- body="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"
165
- closeModal={[Function]}
166
- confirmAction="Force Unlock"
167
- confirmType="danger"
168
- confirmationMessage="I understand that this may cause harm and have working database backups of all backend services."
169
- path="/foreman_tasks/tasks/test/force_unlock"
170
- showModal={false}
171
- title="Force Unlock"
90
+ <ForceUnlockModal
91
+ id="forceUnlockModal"
92
+ onClick={[Function]}
93
+ selectedRowsLen={1}
172
94
  />
173
95
  <Grid
174
96
  bsClass="container"
@@ -179,83 +101,62 @@ exports[`Task rendering render without Props 1`] = `
179
101
  bsClass="row"
180
102
  componentClass="div"
181
103
  >
182
- <Col
183
- bsClass="col"
184
- componentClass="div"
185
- xs={12}
186
- >
187
- <Button
188
- active={false}
189
- block={false}
190
- bsClass="btn"
191
- bsSize="small"
192
- bsStyle="default"
193
- className="reload-button"
194
- disabled={false}
195
- hidden={true}
196
- onClick={[Function]}
197
- >
198
- <span
199
- className="glyphicon glyphicon-refresh "
200
- />
201
- Start auto-reloading
202
- </Button>
203
- <Button
204
- active={false}
205
- block={false}
206
- bsClass="btn"
207
- bsSize="small"
208
- bsStyle="default"
209
- disabled={true}
210
- href="/foreman_tasks/dynflow/"
211
- >
212
- Dynflow console
213
- </Button>
214
- <ResumeButton
215
- disabled={true}
216
- id="test"
217
- name=""
218
- onClick={[Function]}
219
- />
220
- <CancelButton
221
- disabled={true}
222
- id="test"
223
- name=""
224
- onClick={[Function]}
225
- />
226
- </Col>
104
+ <TaskButtons
105
+ action=""
106
+ canEdit={true}
107
+ cancelTaskRequest={[Function]}
108
+ cancellable={false}
109
+ dynflowEnableConsole={true}
110
+ endedAt=""
111
+ errors={Array []}
112
+ externalId=""
113
+ hasSubTasks={true}
114
+ help=""
115
+ id="test"
116
+ output=""
117
+ parentTask="parent-id"
118
+ progress={0}
119
+ result="error"
120
+ resumable={false}
121
+ resumeTaskRequest={[Function]}
122
+ startAt=""
123
+ startBefore=""
124
+ startedAt=""
125
+ state="paused"
126
+ status="RESOLVED"
127
+ taskProgressToggle={[MockFunction]}
128
+ taskReload={true}
129
+ taskReloadStart={[MockFunction]}
130
+ username=""
131
+ usernamePath=""
132
+ />
227
133
  </Row>
228
134
  <TaskInfo
229
135
  action=""
230
- allowDangerousActions={false}
136
+ canEdit={true}
231
137
  cancelTaskRequest={[Function]}
232
138
  cancellable={false}
233
- dynflowEnableConsole={false}
139
+ dynflowEnableConsole={true}
234
140
  endedAt=""
235
- error={Array []}
141
+ errors={Array []}
236
142
  externalId=""
237
- hasSubTasks={false}
143
+ hasSubTasks={true}
238
144
  help=""
239
145
  id="test"
240
146
  output=""
241
- parentTask=""
147
+ parentTask="parent-id"
242
148
  progress={0}
243
- refetchTaskDetails={[Function]}
244
149
  result="error"
245
150
  resumable={false}
246
151
  resumeTaskRequest={[Function]}
247
- showForceUnlockModal={false}
248
- showUnlockModal={false}
249
152
  startAt=""
250
153
  startBefore=""
251
154
  startedAt=""
252
- state=""
253
- taskReload={false}
254
- taskReloadStart={[Function]}
255
- taskReloadStop={[Function]}
256
- timeoutId={null}
257
- toggleForceUnlockModal={[Function]}
258
- toggleUnlockModal={[Function]}
155
+ state="paused"
156
+ status="RESOLVED"
157
+ taskProgressToggle={[MockFunction]}
158
+ taskReload={true}
159
+ taskReloadStart={[MockFunction]}
259
160
  username=""
260
161
  usernamePath=""
261
162
  />