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,14 @@
1
+ import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
2
+
3
+ import { UnlockModal, ForceUnlockModal } from './UnlockModals';
4
+
5
+ const fixtures = {
6
+ render: { taskID: 'some-id', onClick: jest.fn() },
7
+ };
8
+
9
+ describe('UnlockModal', () => {
10
+ testComponentSnapshotsWithFixtures(UnlockModal, fixtures);
11
+ });
12
+ describe('ForceUnlockModal', () => {
13
+ testComponentSnapshotsWithFixtures(ForceUnlockModal, fixtures);
14
+ });
@@ -0,0 +1,233 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Tasks actions should cancelTaskRequest and fail 1`] = `
4
+ Array [
5
+ Array [
6
+ Object {
7
+ "payload": Object {
8
+ "message": Object {
9
+ "message": "Trying to cancel some-name task",
10
+ "type": "info",
11
+ },
12
+ },
13
+ "type": "TOASTS_ADD",
14
+ },
15
+ ],
16
+ Array [
17
+ Object {
18
+ "type": "TASKS_CANCEL_REQUEST",
19
+ },
20
+ ],
21
+ Array [
22
+ Object {
23
+ "payload": [Error: Network Error],
24
+ "type": "TASKS_CANCEL_FAILURE",
25
+ },
26
+ ],
27
+ Array [
28
+ Object {
29
+ "payload": Object {
30
+ "message": Object {
31
+ "message": "some-name Task execution task has to be cancellable",
32
+ "type": "warning",
33
+ },
34
+ },
35
+ "type": "TOASTS_ADD",
36
+ },
37
+ ],
38
+ ]
39
+ `;
40
+
41
+ exports[`Tasks actions should cancelTaskRequest and succeed 1`] = `
42
+ Array [
43
+ Array [
44
+ Object {
45
+ "payload": Object {
46
+ "message": Object {
47
+ "message": "Trying to cancel some-name task",
48
+ "type": "info",
49
+ },
50
+ },
51
+ "type": "TOASTS_ADD",
52
+ },
53
+ ],
54
+ Array [
55
+ Object {
56
+ "type": "TASKS_CANCEL_REQUEST",
57
+ },
58
+ ],
59
+ Array [
60
+ Object {
61
+ "type": "TASKS_CANCEL_SUCCESS",
62
+ },
63
+ ],
64
+ Array [
65
+ Object {
66
+ "payload": Object {
67
+ "message": Object {
68
+ "message": "some-name Task execution was cancelled",
69
+ "type": "success",
70
+ },
71
+ },
72
+ "type": "TOASTS_ADD",
73
+ },
74
+ ],
75
+ ]
76
+ `;
77
+
78
+ exports[`Tasks actions should forceCancelTaskRequest and fail 1`] = `
79
+ Array [
80
+ Array [
81
+ Object {
82
+ "type": "TASKS_FORCE_CANCEL_REQUEST",
83
+ },
84
+ ],
85
+ Array [
86
+ Object {
87
+ "type": "TASKS_FORCE_CANCEL_FAILURE",
88
+ },
89
+ ],
90
+ Array [
91
+ Object {
92
+ "payload": Object {
93
+ "message": Object {
94
+ "message": "some-name Task execution cannot be cancelled with force at the moment.",
95
+ "type": "warning",
96
+ },
97
+ },
98
+ "type": "TOASTS_ADD",
99
+ },
100
+ ],
101
+ ]
102
+ `;
103
+
104
+ exports[`Tasks actions should forceCancelTaskRequest and succeed 1`] = `
105
+ Array [
106
+ Array [
107
+ Object {
108
+ "type": "TASKS_FORCE_CANCEL_REQUEST",
109
+ },
110
+ ],
111
+ Array [
112
+ Object {
113
+ "type": "TASKS_FORCE_CANCEL_SUCCESS",
114
+ },
115
+ ],
116
+ Array [
117
+ Object {
118
+ "payload": Object {
119
+ "message": Object {
120
+ "message": "some-name Task execution resources were unlocked with force.",
121
+ "type": "success",
122
+ },
123
+ },
124
+ "type": "TOASTS_ADD",
125
+ },
126
+ ],
127
+ ]
128
+ `;
129
+
130
+ exports[`Tasks actions should resumeTaskRequest and fail 1`] = `
131
+ Array [
132
+ Array [
133
+ Object {
134
+ "type": "TASKS_RESUME_REQUEST",
135
+ },
136
+ ],
137
+ Array [
138
+ Object {
139
+ "payload": [Error: Network Error],
140
+ "type": "TASKS_RESUME_FAILURE",
141
+ },
142
+ ],
143
+ Array [
144
+ Object {
145
+ "payload": Object {
146
+ "message": Object {
147
+ "message": "some-name Task execution could not be resumed",
148
+ "type": "error",
149
+ },
150
+ },
151
+ "type": "TOASTS_ADD",
152
+ },
153
+ ],
154
+ ]
155
+ `;
156
+
157
+ exports[`Tasks actions should resumeTaskRequest and succeed 1`] = `
158
+ Array [
159
+ Array [
160
+ Object {
161
+ "type": "TASKS_RESUME_REQUEST",
162
+ },
163
+ ],
164
+ Array [
165
+ Object {
166
+ "type": "TASKS_RESUME_SUCCESS",
167
+ },
168
+ ],
169
+ Array [
170
+ Object {
171
+ "payload": Object {
172
+ "message": Object {
173
+ "message": "some-name Task execution was resumed",
174
+ "type": "success",
175
+ },
176
+ },
177
+ "type": "TOASTS_ADD",
178
+ },
179
+ ],
180
+ ]
181
+ `;
182
+
183
+ exports[`Tasks actions should unlockTaskRequest and fail 1`] = `
184
+ Array [
185
+ Array [
186
+ Object {
187
+ "type": "TASKS_FORCE_CANCEL_REQUEST",
188
+ },
189
+ ],
190
+ Array [
191
+ Object {
192
+ "type": "TASKS_FORCE_CANCEL_FAILURE",
193
+ },
194
+ ],
195
+ Array [
196
+ Object {
197
+ "payload": Object {
198
+ "message": Object {
199
+ "message": "some-name Task execution cannot be cancelled with force at the moment.",
200
+ "type": "warning",
201
+ },
202
+ },
203
+ "type": "TOASTS_ADD",
204
+ },
205
+ ],
206
+ ]
207
+ `;
208
+
209
+ exports[`Tasks actions should unlockTaskRequest and succeed 1`] = `
210
+ Array [
211
+ Array [
212
+ Object {
213
+ "type": "TASKS_UNLOCK_REQUEST",
214
+ },
215
+ ],
216
+ Array [
217
+ Object {
218
+ "type": "TASKS_UNLOCK_SUCCESS",
219
+ },
220
+ ],
221
+ Array [
222
+ Object {
223
+ "payload": Object {
224
+ "message": Object {
225
+ "message": "some-name Task execution resources were unlocked ",
226
+ "type": "success",
227
+ },
228
+ },
229
+ "type": "TOASTS_ADD",
230
+ },
231
+ ],
232
+ ]
233
+ `;
@@ -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
+ taskReloadStart,
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
+ taskReloadStart(id);
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
+ taskReloadStart: PropTypes.func.isRequired,
49
63
  };
50
64
 
51
65
  RunningSteps.defaultProps = {
@@ -1,219 +1,52 @@
1
- import React, { Component } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { Grid, Row, Col, Button } from 'patternfly-react';
4
- import { translate as __ } from 'foremanReact/common/I18n';
1
+ import React from 'react';
2
+ import { Grid, Row } from 'patternfly-react';
5
3
  import TaskInfo from './TaskInfo';
6
- import { ClickConfirmation } from '../../common/ClickConfirmation';
7
- import { ResumeButton } from '../../common/ActionButtons/ResumeButton';
8
- import { CancelButton } from '../../common/ActionButtons/CancelButton';
4
+ import { ForceUnlockModal, UnlockModal } from '../../TaskActions/UnlockModals';
5
+ import { TaskButtons } from './TaskButtons';
9
6
 
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);
7
+ const Task = props => {
8
+ const {
9
+ taskReload,
10
+ id,
11
+ forceCancelTaskRequest,
12
+ unlockTaskRequest,
13
+ action,
14
+ taskReloadStart,
15
+ } = props;
16
+ const forceUnlock = () => {
17
+ if (!taskReload) {
18
+ taskReloadStart(id);
24
19
  }
20
+ forceCancelTaskRequest(id, action);
25
21
  };
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}>
87
- <Button
88
- hidden={!allowDangerousActions}
89
- className="reload-button"
90
- bsSize="small"
91
- onClick={this.taskProgressToggle}
92
- >
93
- <span
94
- className={`glyphicon glyphicon-refresh ${
95
- taskReload ? 'spin' : ''
96
- }`}
97
- />
98
- {__(`${taskReload ? 'Stop' : 'Start'} auto-reloading`)}
99
- </Button>
100
- <Button
101
- bsSize="small"
102
- href={`/foreman_tasks/dynflow/${externalId}`}
103
- disabled={!dynflowEnableConsole}
104
- >
105
- {__('Dynflow console')}
106
- </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
- }
22
+ const unlock = () => {
23
+ if (!taskReload) {
24
+ taskReloadStart(id);
25
+ }
26
+ unlockTaskRequest(id, action);
27
+ };
28
+ return (
29
+ <React.Fragment>
30
+ <UnlockModal onClick={unlock} />
31
+ <ForceUnlockModal onClick={forceUnlock} />
32
+ <Grid>
33
+ <Row>
34
+ <TaskButtons taskReloadStart={taskReloadStart} {...props} />
35
+ </Row>
36
+ <TaskInfo {...props} />
37
+ </Grid>
38
+ </React.Fragment>
39
+ );
40
+ };
171
41
 
172
42
  Task.propTypes = {
173
43
  ...TaskInfo.PropTypes,
174
- state: PropTypes.string,
175
- allowDangerousActions: PropTypes.bool,
176
- resumable: PropTypes.bool,
177
- cancellable: PropTypes.bool,
178
- refetchTaskDetails: PropTypes.func,
179
- hasSubTasks: PropTypes.bool,
180
- parentTask: PropTypes.string,
181
- taskReload: PropTypes.bool,
182
- taskReloadStop: PropTypes.func,
183
- taskReloadStart: PropTypes.func,
184
- timeoutId: PropTypes.number,
185
- externalId: PropTypes.string,
186
- id: PropTypes.string.isRequired,
187
- showUnlockModal: PropTypes.bool,
188
- showForceUnlockModal: PropTypes.bool,
189
- toggleUnlockModal: PropTypes.func,
190
- toggleForceUnlockModal: PropTypes.func,
191
- cancelTaskRequest: PropTypes.func,
192
- resumeTaskRequest: PropTypes.func,
193
- dynflowEnableConsole: PropTypes.bool,
44
+ ...TaskButtons.PropTypes,
194
45
  };
195
46
 
196
47
  Task.defaultProps = {
197
48
  ...TaskInfo.defaultProps,
198
- state: '',
199
- allowDangerousActions: false,
200
- resumable: false,
201
- cancellable: false,
202
- refetchTaskDetails: () => null,
203
- hasSubTasks: false,
204
- parentTask: '',
205
- taskReload: false,
206
- taskReloadStop: () => null,
207
- taskReloadStart: () => null,
208
- timeoutId: null,
209
- externalId: '',
210
- showUnlockModal: false,
211
- showForceUnlockModal: false,
212
- toggleUnlockModal: () => null,
213
- toggleForceUnlockModal: () => null,
214
- cancelTaskRequest: () => null,
215
- resumeTaskRequest: () => null,
216
- dynflowEnableConsole: false,
49
+ ...TaskButtons.defaultProps,
217
50
  };
218
51
 
219
52
  export default Task;