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
@@ -7,6 +7,7 @@ exports[`actionCellFormatter render 1`] = `
7
7
  "cancellable": true,
8
8
  }
9
9
  }
10
+ canEdit={true}
10
11
  id="some-id"
11
12
  name="some-name"
12
13
  taskActions={Object {}}
@@ -3,8 +3,10 @@
3
3
  exports[`selectionCellFormatter render 1`] = `
4
4
  <TableSelectionCell
5
5
  checked={true}
6
+ disabled={true}
6
7
  id="selectsome-index"
7
8
  label="Select row"
8
9
  onChange={[Function]}
10
+ title="You do not have permission"
9
11
  />
10
12
  `;
@@ -4,7 +4,7 @@ describe('actionCellFormatter', () => {
4
4
  it('render', () => {
5
5
  const data = [
6
6
  { cancellable: true },
7
- { rowData: { action: 'some-name', id: 'some-id' } },
7
+ { rowData: { action: 'some-name', id: 'some-id', canEdit: true } },
8
8
  ];
9
9
  expect(actionCellFormatter({})(...data)).toMatchSnapshot();
10
10
  });
@@ -5,7 +5,7 @@ describe('selectionCellFormatter', () => {
5
5
  expect(
6
6
  selectionCellFormatter(
7
7
  { isSelected: () => true },
8
- { rowIndex: 'some-index' }
8
+ { rowIndex: 'some-index', rowData: {} }
9
9
  )
10
10
  ).toMatchSnapshot();
11
11
  });
@@ -4,13 +4,16 @@ import { ActionButton } from '../../common/ActionButtons/ActionButton';
4
4
 
5
5
  export const actionCellFormatter = taskActions => (
6
6
  value,
7
- { rowData: { action, id } }
7
+ { rowData: { action, id, canEdit } }
8
8
  ) =>
9
9
  cellFormatter(
10
- <ActionButton
11
- id={id}
12
- name={action}
13
- taskActions={taskActions}
14
- availableActions={value}
15
- />
10
+ canEdit && (
11
+ <ActionButton
12
+ canEdit={canEdit}
13
+ id={id}
14
+ name={action}
15
+ taskActions={taskActions}
16
+ availableActions={value}
17
+ />
18
+ )
16
19
  );
@@ -1,9 +1,16 @@
1
1
  import React from 'react';
2
+ import { translate as __ } from 'foremanReact/common/I18n';
2
3
  import TableSelectionCell from '../Components/TableSelectionCell';
3
4
 
4
5
  export default (selectionController, additionalData) => (
5
6
  <TableSelectionCell
6
7
  id={`select${additionalData.rowIndex}`}
8
+ disabled={!additionalData.rowData.canEdit}
9
+ title={
10
+ additionalData.rowData.canEdit
11
+ ? undefined
12
+ : __('You do not have permission')
13
+ }
7
14
  checked={selectionController.isSelected(additionalData)}
8
15
  onChange={() => selectionController.selectRow(additionalData)}
9
16
  />
@@ -13,9 +13,9 @@ import {
13
13
  selectSort,
14
14
  selectActionName,
15
15
  selectSelectedRows,
16
- selectClicked,
17
16
  selectAllRowsSelected,
18
17
  selectShowSelectAll,
18
+ selectModalID,
19
19
  } from './TasksTableSelectors';
20
20
 
21
21
  const mapStateToProps = state => ({
@@ -27,9 +27,9 @@ const mapStateToProps = state => ({
27
27
  itemCount: selectItemCount(state),
28
28
  actionName: selectActionName(state),
29
29
  selectedRows: selectSelectedRows(state),
30
- clicked: selectClicked(state),
31
30
  allRowsSelected: selectAllRowsSelected(state),
32
31
  showSelectAll: selectShowSelectAll(state),
32
+ modalID: selectModalID(state),
33
33
  });
34
34
 
35
35
  const mapDispatchToProps = dispatch =>
@@ -1,39 +1,75 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { CancelButton } from './CancelButton';
4
- import { ResumeButton } from './ResumeButton';
3
+ import { translate as __ } from 'foremanReact/common/I18n';
4
+ import { ActionButtons } from 'foremanReact/components/common/ActionButtons/ActionButtons';
5
5
 
6
- export const ActionButton = ({ id, name, availableActions, taskActions }) => {
7
- const isResume = availableActions.resumable;
8
- if (isResume) {
9
- return (
10
- <ResumeButton
11
- id={id}
12
- name={name}
13
- onClick={taskActions.resumeTask}
14
- disabled={false}
15
- />
16
- );
6
+ export const ActionButton = ({
7
+ canEdit,
8
+ id,
9
+ name,
10
+ availableActions: { resumable, cancellable, stoppable },
11
+ taskActions,
12
+ }) => {
13
+ const buttons = [];
14
+ const isTitle = canEdit && !(resumable || cancellable || stoppable);
15
+ const title = isTitle ? __('Task cannot be canceled') : undefined;
16
+ if (canEdit) {
17
+ if (resumable) {
18
+ buttons.push({
19
+ title: __('Resume'),
20
+ action: {
21
+ disabled: !resumable,
22
+ onClick: () => taskActions.resumeTask(id, name),
23
+ id: `task-resume-button-${id}`,
24
+ },
25
+ });
26
+ }
27
+ if (cancellable || (!stoppable && !resumable)) {
28
+ // Cancel is the default button that should be shown if no task action can be done
29
+ buttons.push({
30
+ title: __('Cancel'),
31
+ action: {
32
+ disabled: !cancellable,
33
+ onClick: () => taskActions.cancelTask(id, name),
34
+ id: `task-cancel-button-${id}`,
35
+ },
36
+ });
37
+ }
38
+
39
+ if (stoppable) {
40
+ buttons.push({
41
+ title: __('Force Cancel'),
42
+ action: {
43
+ disabled: !stoppable,
44
+ onClick: () => taskActions.forceCancelTask(id, name),
45
+ id: `task-force-cancel-button-${id}`,
46
+ },
47
+ });
48
+ }
17
49
  }
18
50
  return (
19
- <CancelButton
20
- id={id}
21
- name={name}
22
- disabled={!availableActions.cancellable}
23
- onClick={taskActions.cancelTask}
24
- />
51
+ <span title={title}>
52
+ <ActionButtons buttons={buttons} />
53
+ </span>
25
54
  );
26
55
  };
27
56
 
28
57
  ActionButton.propTypes = {
58
+ canEdit: PropTypes.bool,
29
59
  id: PropTypes.string.isRequired,
30
60
  name: PropTypes.string.isRequired,
31
61
  availableActions: PropTypes.shape({
32
62
  cancellable: PropTypes.bool,
33
63
  resumable: PropTypes.bool,
64
+ stoppable: PropTypes.bool,
34
65
  }).isRequired,
35
66
  taskActions: PropTypes.shape({
36
67
  cancelTask: PropTypes.func,
37
68
  resumeTask: PropTypes.func,
69
+ forceCancelTask: PropTypes.func,
38
70
  }).isRequired,
39
71
  };
72
+
73
+ ActionButton.defaultProps = {
74
+ canEdit: false,
75
+ };
@@ -1,45 +1,101 @@
1
- import { testComponentSnapshotsWithFixtures } from '@theforeman/test';
1
+ import React from 'react';
2
+ import { testComponentSnapshotsWithFixtures, shallow } from '@theforeman/test';
2
3
 
3
4
  import { ActionButton } from './ActionButton';
4
5
 
6
+ const resumeTask = jest.fn();
7
+ const cancelTask = jest.fn();
8
+ const forceCancelTask = jest.fn();
9
+ const taskActions = { resumeTask, cancelTask, forceCancelTask };
10
+ const minProps = { canEdit: true, id: 'id', name: 'some-name' };
5
11
  const fixtures = {
6
12
  'render with cancellable true props': {
7
13
  availableActions: {
8
14
  cancellable: true,
9
15
  resumable: false,
10
16
  },
11
- taskActions: {
12
- cancel: jest.fn(),
13
- resume: jest.fn(),
14
- },
15
- id: 'id',
16
- name: 'some-name',
17
+ taskActions,
18
+ ...minProps,
17
19
  },
18
20
  'render with resumable true props': {
19
21
  availableActions: {
20
22
  cancellable: false,
21
23
  resumable: true,
22
24
  },
23
- taskActions: {
24
- cancel: jest.fn(),
25
- resume: jest.fn(),
25
+ taskActions,
26
+ ...minProps,
27
+ },
28
+ 'render with stoppable and cancellable true props': {
29
+ availableActions: {
30
+ cancellable: true,
31
+ stoppable: true,
26
32
  },
27
- id: 'id',
28
- name: 'some-name',
33
+ taskActions,
34
+ ...minProps,
29
35
  },
30
36
  'render with cancellable false props': {
31
37
  availableActions: {
32
38
  cancellable: false,
33
39
  resumable: false,
34
40
  },
35
- taskActions: {
36
- cancel: jest.fn(),
37
- resume: jest.fn(),
41
+ taskActions,
42
+ ...minProps,
43
+ },
44
+ 'render with canEdit false': {
45
+ availableActions: {
46
+ cancellable: false,
47
+ resumable: false,
38
48
  },
39
- id: 'id',
40
- name: 'some-name',
49
+ taskActions,
50
+ ...minProps,
51
+ canEdit: false,
41
52
  },
42
53
  };
43
54
 
44
- describe('ActionButton', () =>
45
- testComponentSnapshotsWithFixtures(ActionButton, fixtures));
55
+ describe('ActionButton', () => {
56
+ describe('snapshot test', () =>
57
+ testComponentSnapshotsWithFixtures(ActionButton, fixtures));
58
+ describe('click test', () => {
59
+ const id = 'some-id';
60
+ const name = 'some-name';
61
+ it('cancel', () => {
62
+ const component = shallow(
63
+ <ActionButton
64
+ id={id}
65
+ name={name}
66
+ canEdit
67
+ availableActions={{ cancellable: true }}
68
+ taskActions={taskActions}
69
+ />
70
+ ).children();
71
+ component.props().buttons[0].action.onClick();
72
+ expect(cancelTask).toHaveBeenCalledWith(id, name);
73
+ });
74
+ it('resume', () => {
75
+ const component = shallow(
76
+ <ActionButton
77
+ id={id}
78
+ name={name}
79
+ canEdit
80
+ availableActions={{ resumable: true }}
81
+ taskActions={taskActions}
82
+ />
83
+ ).children();
84
+ component.props().buttons[0].action.onClick();
85
+ expect(resumeTask).toHaveBeenCalledWith(id, name);
86
+ });
87
+ it('force cancel', () => {
88
+ const component = shallow(
89
+ <ActionButton
90
+ id={id}
91
+ name={name}
92
+ canEdit
93
+ availableActions={{ stoppable: true }}
94
+ taskActions={taskActions}
95
+ />
96
+ ).children();
97
+ component.props().buttons[0].action.onClick();
98
+ expect(cancelTask).toHaveBeenCalledWith(id, name);
99
+ });
100
+ });
101
+ });
@@ -1,28 +1,95 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`ActionButton render with cancellable false props 1`] = `
4
- <CancelButton
5
- disabled={true}
6
- id="id"
7
- name="some-name"
8
- onClick={[Function]}
9
- />
3
+ exports[`ActionButton snapshot test render with canEdit false 1`] = `
4
+ <span>
5
+ <ActionButtons
6
+ buttons={Array []}
7
+ />
8
+ </span>
10
9
  `;
11
10
 
12
- exports[`ActionButton render with cancellable true props 1`] = `
13
- <CancelButton
14
- disabled={false}
15
- id="id"
16
- name="some-name"
17
- onClick={[Function]}
18
- />
11
+ exports[`ActionButton snapshot test render with cancellable false props 1`] = `
12
+ <span
13
+ title="Task cannot be canceled"
14
+ >
15
+ <ActionButtons
16
+ buttons={
17
+ Array [
18
+ Object {
19
+ "action": Object {
20
+ "disabled": true,
21
+ "id": "task-cancel-button-id",
22
+ "onClick": [Function],
23
+ },
24
+ "title": "Cancel",
25
+ },
26
+ ]
27
+ }
28
+ />
29
+ </span>
19
30
  `;
20
31
 
21
- exports[`ActionButton render with resumable true props 1`] = `
22
- <ResumeButton
23
- disabled={false}
24
- id="id"
25
- name="some-name"
26
- onClick={[Function]}
27
- />
32
+ exports[`ActionButton snapshot test render with cancellable true props 1`] = `
33
+ <span>
34
+ <ActionButtons
35
+ buttons={
36
+ Array [
37
+ Object {
38
+ "action": Object {
39
+ "disabled": false,
40
+ "id": "task-cancel-button-id",
41
+ "onClick": [Function],
42
+ },
43
+ "title": "Cancel",
44
+ },
45
+ ]
46
+ }
47
+ />
48
+ </span>
49
+ `;
50
+
51
+ exports[`ActionButton snapshot test render with resumable true props 1`] = `
52
+ <span>
53
+ <ActionButtons
54
+ buttons={
55
+ Array [
56
+ Object {
57
+ "action": Object {
58
+ "disabled": false,
59
+ "id": "task-resume-button-id",
60
+ "onClick": [Function],
61
+ },
62
+ "title": "Resume",
63
+ },
64
+ ]
65
+ }
66
+ />
67
+ </span>
68
+ `;
69
+
70
+ exports[`ActionButton snapshot test render with stoppable and cancellable true props 1`] = `
71
+ <span>
72
+ <ActionButtons
73
+ buttons={
74
+ Array [
75
+ Object {
76
+ "action": Object {
77
+ "disabled": false,
78
+ "id": "task-cancel-button-id",
79
+ "onClick": [Function],
80
+ },
81
+ "title": "Cancel",
82
+ },
83
+ Object {
84
+ "action": Object {
85
+ "disabled": false,
86
+ "id": "task-force-cancel-button-id",
87
+ "onClick": [Function],
88
+ },
89
+ "title": "Force Cancel",
90
+ },
91
+ ]
92
+ }
93
+ />
94
+ </span>
28
95
  `;
@@ -0,0 +1,9 @@
1
+ .confirmation-check {
2
+ margin-top: 1em;
3
+ input {
4
+ vertical-align: text-top;
5
+ }
6
+ span {
7
+ vertical-align: middle;
8
+ }
9
+ }