foreman-tasks 1.0.1 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -12
  3. data/.rubocop_todo.yml +34 -116
  4. data/README.md +2 -0
  5. data/app/controllers/foreman_tasks/api/recurring_logics_controller.rb +20 -1
  6. data/app/controllers/foreman_tasks/api/tasks_controller.rb +65 -10
  7. data/app/controllers/foreman_tasks/concerns/hosts_controller_extension.rb +1 -1
  8. data/app/controllers/foreman_tasks/recurring_logics_controller.rb +19 -0
  9. data/app/controllers/foreman_tasks/tasks_controller.rb +9 -14
  10. data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +1 -3
  11. data/app/lib/actions/helpers/humanizer.rb +1 -3
  12. data/app/lib/actions/proxy_action.rb +33 -12
  13. data/app/lib/foreman_tasks/concerns/polling_action_extensions.rb +12 -0
  14. data/app/models/foreman_tasks/concerns/action_triggering.rb +1 -1
  15. data/app/models/foreman_tasks/recurring_logic.rb +1 -0
  16. data/app/models/foreman_tasks/remote_task.rb +1 -0
  17. data/app/models/foreman_tasks/task.rb +8 -0
  18. data/app/models/foreman_tasks/task/dynflow_task.rb +2 -1
  19. data/app/models/foreman_tasks/task/search.rb +11 -1
  20. data/app/models/setting/foreman_tasks.rb +7 -2
  21. data/app/services/foreman_tasks/troubleshooting_help_generator.rb +0 -4
  22. data/app/services/ui_notifications/tasks/task_bulk_cancel.rb +36 -0
  23. data/app/services/ui_notifications/tasks/task_bulk_resume.rb +38 -0
  24. data/app/services/ui_notifications/tasks/task_bulk_stop.rb +36 -0
  25. data/app/views/foreman_tasks/api/recurring_logics/base.json.rabl +2 -1
  26. data/app/views/foreman_tasks/api/tasks/details.json.rabl +1 -1
  27. data/app/views/foreman_tasks/api/tasks/show.json.rabl +1 -1
  28. data/app/views/foreman_tasks/recurring_logics/index.html.erb +30 -0
  29. data/app/views/foreman_tasks/tasks/show.html.erb +3 -0
  30. data/config/routes.rb +8 -0
  31. data/db/migrate/20200517215015_rename_bookmarks_controller.rb +35 -0
  32. data/db/migrate/20200519093217_drop_dynflow_allow_dangerous_actions_setting.foreman_tasks.rb +5 -0
  33. data/db/migrate/20200611090846_add_task_lock_index_on_resource_type_and_task_id.rb +9 -0
  34. data/db/seeds.d/30-notification_blueprints.rb +21 -0
  35. data/foreman-tasks.gemspec +5 -6
  36. data/gemfile.d/foreman-tasks.rb +1 -0
  37. data/lib/foreman_tasks/dynflow/console_authorizer.rb +2 -2
  38. data/lib/foreman_tasks/engine.rb +17 -19
  39. data/lib/foreman_tasks/tasks/cleanup.rake +1 -1
  40. data/lib/foreman_tasks/tasks/export_tasks.rake +2 -2
  41. data/lib/foreman_tasks/test_extensions.rb +1 -1
  42. data/lib/foreman_tasks/version.rb +1 -1
  43. data/locale/action_names.rb +2 -2
  44. data/locale/en/LC_MESSAGES/foreman_tasks.mo +0 -0
  45. data/locale/en/foreman_tasks.po +270 -54
  46. data/locale/foreman_tasks.pot +630 -292
  47. data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
  48. data/locale/fr/foreman_tasks.po +817 -0
  49. data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
  50. data/locale/ja/foreman_tasks.po +817 -0
  51. data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
  52. data/locale/zh_CN/foreman_tasks.po +816 -0
  53. data/package.json +1 -2
  54. data/script/rails +2 -2
  55. data/script/travis_run_js_tests.sh +2 -2
  56. data/test/factories/task_factory.rb +34 -2
  57. data/test/foreman_tasks_test_helper.rb +4 -0
  58. data/test/lib/concerns/polling_action_extensions_test.rb +34 -0
  59. data/test/unit/actions/action_with_sub_plans_test.rb +1 -1
  60. data/test/unit/task_test.rb +160 -74
  61. data/webpack/ForemanTasks/Components/TaskActions/TaskAction.test.js +60 -0
  62. data/webpack/ForemanTasks/Components/TaskActions/TaskActionHelpers.js +67 -0
  63. data/webpack/ForemanTasks/Components/TaskActions/TaskActionHelpers.test.js +46 -0
  64. data/webpack/ForemanTasks/Components/TaskActions/TaskActionsConstants.js +16 -0
  65. data/webpack/ForemanTasks/Components/TaskActions/UnlockModals.js +60 -0
  66. data/webpack/ForemanTasks/Components/TaskActions/UnlockModals.test.js +14 -0
  67. data/webpack/ForemanTasks/Components/TaskActions/__snapshots__/TaskAction.test.js.snap +233 -0
  68. data/webpack/ForemanTasks/Components/TaskActions/__snapshots__/UnlockModals.test.js.snap +25 -0
  69. data/webpack/ForemanTasks/Components/TaskActions/index.js +115 -0
  70. data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +17 -3
  71. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +132 -165
  72. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +3 -12
  73. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +8 -1
  74. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +68 -3
  75. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskInfo.test.js +0 -1
  76. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/RunningSteps.test.js.snap +1 -1
  77. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +108 -75
  78. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +3 -9
  79. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +35 -5
  80. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +34 -14
  81. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +3 -4
  82. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +0 -6
  83. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +4 -10
  84. data/webpack/ForemanTasks/Components/TaskDetails/TasksDetailsHelper.js +6 -1
  85. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.fixtures.js +8 -0
  86. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +7 -1
  87. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +18 -2
  88. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +30 -13
  89. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +91 -0
  90. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +13 -4
  91. data/webpack/ForemanTasks/Components/TaskDetails/index.js +6 -8
  92. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardActions.js +1 -1
  93. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardConstants.js +5 -0
  94. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardHelper.js +3 -2
  95. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardActions.test.js +2 -2
  96. data/webpack/ForemanTasks/Components/TasksTable/Components/ActionSelectButton.js +14 -1
  97. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModal.js +83 -0
  98. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalActions.js +106 -0
  99. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalReducer.js +38 -0
  100. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalSelectors.js +45 -0
  101. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModal.test.js +36 -0
  102. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalActions.test.js +205 -0
  103. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalReducer.test.js +27 -0
  104. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalSelectors.test.js +54 -0
  105. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModal.test.js.snap +41 -0
  106. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalReducer.test.js.snap +19 -0
  107. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalSelectors.test.js.snap +30 -0
  108. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/index.js +29 -0
  109. data/webpack/ForemanTasks/Components/TasksTable/Components/SelectAllAlert.js +43 -0
  110. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ActionSelectButton.test.js +1 -0
  111. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/SelectAllAlert.test.js +29 -0
  112. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ActionSelectButton.test.js.snap +11 -0
  113. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/SelectAllAlert.test.js.snap +75 -0
  114. data/webpack/ForemanTasks/Components/TasksTable/SubTasksPage.js +4 -1
  115. data/webpack/ForemanTasks/Components/TasksTable/TasksBulkActions.js +247 -0
  116. data/webpack/ForemanTasks/Components/TasksTable/TasksTable.js +37 -19
  117. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +56 -92
  118. data/webpack/ForemanTasks/Components/TasksTable/TasksTableConstants.js +19 -11
  119. data/webpack/ForemanTasks/Components/TasksTable/TasksTableHelpers.js +4 -3
  120. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +64 -73
  121. data/webpack/ForemanTasks/Components/TasksTable/TasksTableReducer.js +21 -2
  122. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSchema.js +2 -2
  123. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +13 -4
  124. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksBulkActions.test.js +147 -0
  125. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +3 -10
  126. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableActions.test.js +46 -74
  127. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableHelpers.test.js +17 -1
  128. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTablePage.test.js +9 -1
  129. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTableReducer.test.js +22 -1
  130. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +4 -12
  131. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksBulkActions.test.js.snap +336 -0
  132. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +3 -12
  133. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableActions.test.js.snap +22 -158
  134. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +56 -132
  135. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTableReducer.test.js.snap +34 -0
  136. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionHeaderCellFormatter.test.js +1 -1
  137. data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionHeaderCellFormatter.js +2 -2
  138. data/webpack/ForemanTasks/Components/TasksTable/index.js +10 -4
  139. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.js +47 -19
  140. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.test.js +61 -14
  141. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ActionButton.test.js.snap +80 -21
  142. data/webpack/ForemanTasks/Components/common/ClickConfirmation/ClickConfirmation.scss +9 -0
  143. data/webpack/ForemanTasks/Components/common/ClickConfirmation/ClickConfirmation.test.js +44 -0
  144. data/webpack/ForemanTasks/Components/common/ClickConfirmation/__snapshots__/ClickConfirmation.test.js.snap +52 -0
  145. data/webpack/ForemanTasks/Components/common/ClickConfirmation/index.js +59 -66
  146. data/webpack/ForemanTasks/Components/common/ToastsHelpers/ToastTypesConstants.js +11 -0
  147. data/webpack/ForemanTasks/Components/common/ToastsHelpers/index.js +15 -0
  148. data/webpack/ForemanTasks/ForemanTasksReducers.js +2 -0
  149. data/webpack/ForemanTasks/Routes/ForemanTasksRoutes.test.js +2 -1
  150. data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalHooks.js +2 -2
  151. data/webpack/__mocks__/foremanReact/components/ForemanModal/index.js +17 -3
  152. data/webpack/__mocks__/foremanReact/components/common/ActionButtons/ActionButtons.js +3 -0
  153. data/webpack/__mocks__/foremanReact/{API.js → redux/API.js} +1 -1
  154. metadata +76 -27
  155. data/webpack/ForemanTasks/Components/TasksTable/Components/CancelConfirm.js +0 -53
  156. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmationModals.js +0 -56
  157. data/webpack/ForemanTasks/Components/TasksTable/Components/ResumeConfirm.js +0 -52
  158. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/CancelConfirm.test.js +0 -26
  159. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ConfirmationModals.test.js +0 -24
  160. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/ResumeConfirm.test.js +0 -26
  161. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/CancelConfirm.test.js.snap +0 -65
  162. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ConfirmationModals.test.js.snap +0 -30
  163. data/webpack/ForemanTasks/Components/TasksTable/Components/__test__/__snapshots__/ResumeConfirm.test.js.snap +0 -63
  164. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.js +0 -23
  165. data/webpack/ForemanTasks/Components/common/ActionButtons/CancelButton.test.js +0 -26
  166. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.js +0 -23
  167. data/webpack/ForemanTasks/Components/common/ActionButtons/ResumeButton.test.js +0 -27
  168. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/CancelButton.test.js.snap +0 -15
  169. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ResumeButton.test.js.snap +0 -15
@@ -1,17 +1,19 @@
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 };
5
10
  const fixtures = {
6
11
  'render with cancellable true props': {
7
12
  availableActions: {
8
13
  cancellable: true,
9
14
  resumable: false,
10
15
  },
11
- taskActions: {
12
- cancel: jest.fn(),
13
- resume: jest.fn(),
14
- },
16
+ taskActions,
15
17
  id: 'id',
16
18
  name: 'some-name',
17
19
  },
@@ -20,10 +22,16 @@ const fixtures = {
20
22
  cancellable: false,
21
23
  resumable: true,
22
24
  },
23
- taskActions: {
24
- cancel: jest.fn(),
25
- resume: jest.fn(),
25
+ taskActions,
26
+ id: 'id',
27
+ name: 'some-name',
28
+ },
29
+ 'render with stoppable and cancellable true props': {
30
+ availableActions: {
31
+ cancellable: true,
32
+ stoppable: true,
26
33
  },
34
+ taskActions,
27
35
  id: 'id',
28
36
  name: 'some-name',
29
37
  },
@@ -32,14 +40,53 @@ const fixtures = {
32
40
  cancellable: false,
33
41
  resumable: false,
34
42
  },
35
- taskActions: {
36
- cancel: jest.fn(),
37
- resume: jest.fn(),
38
- },
43
+ taskActions,
39
44
  id: 'id',
40
45
  name: 'some-name',
41
46
  },
42
47
  };
43
48
 
44
- describe('ActionButton', () =>
45
- testComponentSnapshotsWithFixtures(ActionButton, fixtures));
49
+ describe('ActionButton', () => {
50
+ describe('snapshot test', () =>
51
+ testComponentSnapshotsWithFixtures(ActionButton, fixtures));
52
+ describe('click test', () => {
53
+ const id = 'some-id';
54
+ const name = 'some-name';
55
+ it('cancel', () => {
56
+ const component = shallow(
57
+ <ActionButton
58
+ id={id}
59
+ name={name}
60
+ availableActions={{ cancellable: true }}
61
+ taskActions={taskActions}
62
+ />
63
+ ).children();
64
+ component.props().buttons[0].action.onClick();
65
+ expect(cancelTask).toHaveBeenCalledWith(id, name);
66
+ });
67
+ it('resume', () => {
68
+ const component = shallow(
69
+ <ActionButton
70
+ id={id}
71
+ name={name}
72
+ availableActions={{ resumable: true }}
73
+ taskActions={taskActions}
74
+ />
75
+ ).children();
76
+ component.props().buttons[0].action.onClick();
77
+ expect(resumeTask).toHaveBeenCalledWith(id, name);
78
+ });
79
+ it('force cancel', () => {
80
+ const component = shallow(
81
+ <ActionButton
82
+ id={id}
83
+ name={name}
84
+ availableActions={{ stoppable: true }}
85
+ taskActions={taskActions}
86
+ />
87
+ ).children();
88
+ component.props().buttons[0].action.onClick();
89
+ expect(cancelTask).toHaveBeenCalledWith(id, name);
90
+ });
91
+ });
92
+ });
@@ -1,28 +1,87 @@
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 cancellable false props 1`] = `
4
+ <span
5
+ title="Task cannot be canceled"
6
+ >
7
+ <ActionButtons
8
+ buttons={
9
+ Array [
10
+ Object {
11
+ "action": Object {
12
+ "disabled": true,
13
+ "id": "task-cancel-button-id",
14
+ "onClick": [Function],
15
+ },
16
+ "title": "Cancel",
17
+ },
18
+ ]
19
+ }
20
+ />
21
+ </span>
10
22
  `;
11
23
 
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
- />
24
+ exports[`ActionButton snapshot test render with cancellable true props 1`] = `
25
+ <span>
26
+ <ActionButtons
27
+ buttons={
28
+ Array [
29
+ Object {
30
+ "action": Object {
31
+ "disabled": false,
32
+ "id": "task-cancel-button-id",
33
+ "onClick": [Function],
34
+ },
35
+ "title": "Cancel",
36
+ },
37
+ ]
38
+ }
39
+ />
40
+ </span>
19
41
  `;
20
42
 
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
- />
43
+ exports[`ActionButton snapshot test render with resumable true props 1`] = `
44
+ <span>
45
+ <ActionButtons
46
+ buttons={
47
+ Array [
48
+ Object {
49
+ "action": Object {
50
+ "disabled": false,
51
+ "id": "task-resume-button-id",
52
+ "onClick": [Function],
53
+ },
54
+ "title": "Resume",
55
+ },
56
+ ]
57
+ }
58
+ />
59
+ </span>
60
+ `;
61
+
62
+ exports[`ActionButton snapshot test render with stoppable and cancellable true props 1`] = `
63
+ <span>
64
+ <ActionButtons
65
+ buttons={
66
+ Array [
67
+ Object {
68
+ "action": Object {
69
+ "disabled": false,
70
+ "id": "task-cancel-button-id",
71
+ "onClick": [Function],
72
+ },
73
+ "title": "Cancel",
74
+ },
75
+ Object {
76
+ "action": Object {
77
+ "disabled": false,
78
+ "id": "task-force-cancel-button-id",
79
+ "onClick": [Function],
80
+ },
81
+ "title": "Force Cancel",
82
+ },
83
+ ]
84
+ }
85
+ />
86
+ </span>
28
87
  `;
@@ -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
+ }
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+ import { testComponentSnapshotsWithFixtures, mount } from '@theforeman/test';
3
+ import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
4
+ import { ClickConfirmation } from './';
5
+
6
+ const fixtures = {
7
+ render: {
8
+ title: 'some-title',
9
+ confirmType: 'danger',
10
+ body: 'some-body',
11
+ confirmationMessage: 'some-message',
12
+ id: 'some-id',
13
+ confirmAction: 'some-confirm',
14
+ onClick: jest.fn(),
15
+ },
16
+ };
17
+
18
+ describe('ClickConfirmation', () => {
19
+ testComponentSnapshotsWithFixtures(ClickConfirmation, fixtures);
20
+ it('enable button on checkbox click', () => {
21
+ const component = mount(<ClickConfirmation {...fixtures.render} />);
22
+ const getButton = () => component.find('.confirm-button').at(0);
23
+ expect(getButton().props().disabled).toBeTruthy();
24
+ const checkbox = component.find('input').at(0);
25
+ checkbox.simulate('change', { target: { checked: true } });
26
+ expect(getButton().props().disabled).toBeFalsy();
27
+ });
28
+
29
+ it('click test', () => {
30
+ const setModalClosed = jest.fn();
31
+ useForemanModal.mockImplementation(id => ({
32
+ setModalClosed: () => setModalClosed(id),
33
+ }));
34
+ const onClick = jest.fn();
35
+ const props = { ...fixtures.render, onClick };
36
+ const component = mount(<ClickConfirmation {...props} />);
37
+ const getButton = () => component.find('.confirm-button').at(0);
38
+ const checkbox = component.find('input').at(0);
39
+ checkbox.simulate('change', { target: { checked: true } });
40
+ getButton().simulate('click');
41
+ expect(onClick).toBeCalled();
42
+ expect(setModalClosed).toBeCalledWith({ id: fixtures.render.id });
43
+ });
44
+ });
@@ -0,0 +1,52 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`ClickConfirmation render 1`] = `
4
+ <ForemanModal
5
+ id="some-id"
6
+ >
7
+ <Component>
8
+ <span
9
+ className="glyphicon glyphicon-exclamation-sign"
10
+ />
11
+ some-title
12
+ </Component>
13
+ <span>
14
+ some-body
15
+ </span>
16
+ <div
17
+ className="confirmation-check"
18
+ >
19
+ <input
20
+ checked={false}
21
+ onChange={[Function]}
22
+ type="checkbox"
23
+ />
24
+ <span>
25
+ some-message
26
+ </span>
27
+ </div>
28
+ <Component>
29
+ <Button
30
+ active={false}
31
+ block={false}
32
+ bsClass="btn"
33
+ bsStyle="danger"
34
+ className="confirm-button"
35
+ disabled={true}
36
+ onClick={[Function]}
37
+ >
38
+ some-confirm
39
+ </Button>
40
+ <Button
41
+ active={false}
42
+ block={false}
43
+ bsClass="btn"
44
+ bsStyle="default"
45
+ disabled={false}
46
+ onClick={[MockFunction]}
47
+ >
48
+ Cancel
49
+ </Button>
50
+ </Component>
51
+ </ForemanModal>
52
+ `;
@@ -1,82 +1,75 @@
1
- import { Modal, Button } from 'patternfly-react';
1
+ import React, { useState, useEffect } from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import React from 'react';
3
+ import { Button } from 'patternfly-react';
4
+ import ForemanModal from 'foremanReact/components/ForemanModal';
4
5
  import { translate as __ } from 'foremanReact/common/I18n';
6
+ import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
7
+ import './ClickConfirmation.scss';
5
8
 
6
- export class ClickConfirmation extends React.Component {
7
- state = { disableConfirm: true };
8
- render() {
9
- const { disableConfirm } = this.state;
10
- const {
11
- title,
12
- body,
13
- confirmationMessage,
14
- confirmAction,
15
- path,
16
- confirmType,
17
- closeModal,
18
- showModal,
19
- } = this.props;
20
- const icon = confirmType === 'warning' ? confirmType : 'exclamation';
21
- return (
22
- <Modal show={showModal} onHide={closeModal}>
23
- <Modal.Header>
24
- <Button
25
- className="close"
26
- onClick={closeModal}
27
- aria-hidden="true"
28
- aria-label="Close"
29
- >
30
- &times;
31
- </Button>
32
- <Modal.Title>
33
- <span className={`glyphicon glyphicon-${icon}-sign`} />
34
- {` ${title}`}
35
- </Modal.Title>
36
- </Modal.Header>
37
- <Modal.Body>
38
- {body}
39
- <div>
40
- <input
41
- onChange={e => {
42
- this.setState({
43
- disableConfirm: !e.target.checked,
44
- });
45
- }}
46
- type="checkbox"
47
- />
48
- {` ${confirmationMessage}`}
49
- </div>
50
- </Modal.Body>
51
- <Modal.Footer>
52
- <Button onClick={closeModal}>{__('Cancel')}</Button>
53
- <Button
54
- href={path}
55
- data-method="post"
56
- bsStyle={confirmType}
57
- disabled={disableConfirm}
58
- >
59
- {confirmAction}
60
- </Button>
61
- </Modal.Footer>
62
- </Modal>
63
- );
64
- }
65
- }
9
+ export const ClickConfirmation = ({
10
+ title,
11
+ confirmType,
12
+ body,
13
+ confirmationMessage,
14
+ id,
15
+ confirmAction,
16
+ onClick,
17
+ }) => {
18
+ const [isConfirmed, setConfirm] = useState(false);
19
+ const { setModalClosed, modalOpen } = useForemanModal({
20
+ id,
21
+ });
22
+ useEffect(() => {
23
+ setConfirm(false);
24
+ }, [modalOpen]);
25
+ const icon = confirmType === 'warning' ? confirmType : 'exclamation';
26
+
27
+ return (
28
+ <ForemanModal id={id}>
29
+ <ForemanModal.Header>
30
+ <span className={`glyphicon glyphicon-${icon}-sign`} />
31
+ {` ${title}`}
32
+ </ForemanModal.Header>
33
+ <span>{body}</span>
34
+ <div className="confirmation-check">
35
+ <input
36
+ onChange={e => {
37
+ setConfirm(e.target.checked);
38
+ }}
39
+ checked={isConfirmed}
40
+ type="checkbox"
41
+ />
42
+ <span>{` ${confirmationMessage}`}</span>
43
+ </div>
44
+ <ForemanModal.Footer>
45
+ <Button
46
+ className="confirm-button"
47
+ onClick={() => {
48
+ onClick();
49
+ setModalClosed();
50
+ }}
51
+ bsStyle={confirmType}
52
+ disabled={!isConfirmed}
53
+ >
54
+ {confirmAction}
55
+ </Button>
56
+ <Button onClick={setModalClosed}>{__('Cancel')}</Button>
57
+ </ForemanModal.Footer>
58
+ </ForemanModal>
59
+ );
60
+ };
66
61
 
67
62
  ClickConfirmation.propTypes = {
68
- showModal: PropTypes.bool,
69
63
  title: PropTypes.string.isRequired,
70
64
  body: PropTypes.string.isRequired,
71
65
  confirmationMessage: PropTypes.string.isRequired,
72
66
  confirmAction: PropTypes.string.isRequired,
73
- path: PropTypes.string.isRequired,
67
+ onClick: PropTypes.func.isRequired,
74
68
  confirmType: PropTypes.oneOf(['warning', 'danger']),
75
- closeModal: PropTypes.func.isRequired,
69
+ id: PropTypes.string.isRequired,
76
70
  };
77
71
 
78
72
  ClickConfirmation.defaultProps = {
79
- showModal: false,
80
73
  confirmType: 'warning',
81
74
  };
82
75