foreman-tasks 2.0.0 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/js_tests.yml +31 -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/app/controllers/foreman_tasks/api/tasks_controller.rb +36 -60
  8. data/app/controllers/foreman_tasks/concerns/parameters/triggering.rb +1 -1
  9. data/app/controllers/foreman_tasks/recurring_logics_controller.rb +7 -0
  10. data/app/controllers/foreman_tasks/tasks_controller.rb +6 -3
  11. data/app/helpers/foreman_tasks/foreman_tasks_helper.rb +3 -3
  12. data/app/lib/actions/proxy_action.rb +1 -1
  13. data/app/models/foreman_tasks/recurring_logic.rb +1 -1
  14. data/app/models/foreman_tasks/task.rb +11 -0
  15. data/app/models/foreman_tasks/task/dynflow_task.rb +29 -33
  16. data/app/models/foreman_tasks/task/status_explicator.rb +1 -1
  17. data/app/models/foreman_tasks/triggering.rb +1 -1
  18. data/app/models/setting/foreman_tasks.rb +9 -9
  19. data/app/services/foreman_tasks/dashboard_table_filter.rb +5 -1
  20. data/app/views/foreman_tasks/api/tasks/index.json.rabl +2 -0
  21. data/app/views/foreman_tasks/api/tasks/show.json.rabl +2 -0
  22. data/app/views/foreman_tasks/layouts/react.html.erb +1 -2
  23. data/app/views/foreman_tasks/recurring_logics/index.html.erb +3 -1
  24. data/app/views/foreman_tasks/tasks/show.html.erb +1 -6
  25. data/config/routes.rb +2 -1
  26. data/db/migrate/20200517215015_rename_bookmarks_controller.rb +2 -2
  27. data/db/migrate/20200611090846_add_task_lock_index_on_resource_type_and_task_id.rb +9 -0
  28. data/db/seeds.d/30-notification_blueprints.rb +7 -7
  29. data/db/seeds.d/61-foreman_tasks_bookmarks.rb +1 -1
  30. data/foreman-tasks.gemspec +1 -0
  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 +2 -7
  35. data/lib/foreman_tasks/tasks/cleanup.rake +2 -2
  36. data/lib/foreman_tasks/tasks/dynflow.rake +6 -0
  37. data/lib/foreman_tasks/tasks/export_tasks.rake +1 -1
  38. data/lib/foreman_tasks/version.rb +1 -1
  39. data/locale/en/LC_MESSAGES/foreman_tasks.mo +0 -0
  40. data/locale/en/foreman_tasks.po +50 -20
  41. data/locale/foreman_tasks.pot +173 -126
  42. data/locale/fr/LC_MESSAGES/foreman_tasks.mo +0 -0
  43. data/locale/fr/foreman_tasks.po +817 -0
  44. data/locale/ja/LC_MESSAGES/foreman_tasks.mo +0 -0
  45. data/locale/ja/foreman_tasks.po +817 -0
  46. data/locale/zh_CN/LC_MESSAGES/foreman_tasks.mo +0 -0
  47. data/locale/zh_CN/foreman_tasks.po +816 -0
  48. data/package.json +1 -1
  49. data/script/npm_link_foreman_js.sh +26 -0
  50. data/test/controllers/api/recurring_logics_controller_test.rb +1 -1
  51. data/test/controllers/api/tasks_controller_test.rb +17 -7
  52. data/test/controllers/tasks_controller_test.rb +6 -6
  53. data/test/core/unit/runner_test.rb +20 -20
  54. data/test/core/unit/task_launcher_test.rb +8 -8
  55. data/test/helpers/foreman_tasks/foreman_tasks_helper_test.rb +7 -7
  56. data/test/helpers/foreman_tasks/tasks_helper_test.rb +3 -3
  57. data/test/lib/actions/middleware/keep_current_request_id_test.rb +3 -3
  58. data/test/support/history_tasks_builder.rb +1 -1
  59. data/test/tasks/generate_task_actions_test.rb +1 -1
  60. data/test/unit/actions/action_with_sub_plans_test.rb +2 -2
  61. data/test/unit/actions/bulk_action_test.rb +6 -6
  62. data/test/unit/actions/proxy_action_test.rb +20 -20
  63. data/test/unit/actions/recurring_action_test.rb +30 -32
  64. data/test/unit/cleaner_test.rb +24 -24
  65. data/test/unit/dashboard_table_filter_test.rb +5 -5
  66. data/test/unit/otp_manager_test.rb +2 -2
  67. data/test/unit/proxy_selector_test.rb +9 -9
  68. data/test/unit/recurring_logic_test.rb +32 -32
  69. data/test/unit/remote_task_test.rb +2 -2
  70. data/test/unit/task_groups_test.rb +4 -4
  71. data/test/unit/task_test.rb +18 -18
  72. data/test/unit/triggering_test.rb +8 -8
  73. data/test/unit/troubleshooting_help_generator_test.rb +6 -6
  74. data/test/unit/ui_notifications_test.rb +11 -11
  75. data/webpack/ForemanTasks/Components/TaskActions/TaskAction.test.js +2 -2
  76. data/webpack/ForemanTasks/Components/TaskActions/index.js +1 -1
  77. data/webpack/ForemanTasks/Components/TaskDetails/Components/RunningSteps.js +17 -3
  78. data/webpack/ForemanTasks/Components/TaskDetails/Components/Task.js +8 -153
  79. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskButtons.js +168 -0
  80. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskInfo.js +6 -7
  81. data/webpack/ForemanTasks/Components/TaskDetails/Components/TaskSkeleton.js +48 -0
  82. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/RunningSteps.test.js +8 -1
  83. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/Task.test.js +13 -70
  84. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/TaskButtons.test.js +95 -0
  85. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/RunningSteps.test.js.snap +1 -1
  86. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/Task.test.js.snap +78 -208
  87. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskButtons.test.js.snap +212 -0
  88. data/webpack/ForemanTasks/Components/TaskDetails/Components/__tests__/__snapshots__/TaskInfo.test.js.snap +8 -4
  89. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.js +100 -53
  90. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetails.scss +13 -14
  91. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsActions.js +57 -95
  92. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsConstants.js +3 -12
  93. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsSelectors.js +57 -28
  94. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.fixtures.js +8 -0
  95. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetails.test.js +8 -1
  96. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsActions.test.js +6 -6
  97. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetails.test.js.snap +84 -12
  98. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsActions.test.js.snap +25 -21
  99. data/webpack/ForemanTasks/Components/TaskDetails/index.js +8 -3
  100. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/ScheduledTasksCard/ScheduledTasksCard.scss +4 -0
  101. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/OtherInfo.js +53 -0
  102. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/OtherInfo.test.js +14 -0
  103. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.js +27 -19
  104. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.scss +14 -0
  105. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCard.test.js +1 -34
  106. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/{StoppedTasksCardHelper.js → StoppedTasksCardTable.js} +28 -1
  107. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/StoppedTasksCardTable.test.js +54 -0
  108. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/OtherInfo.test.js.snap +48 -0
  109. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCard.test.js.snap +60 -1367
  110. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/Components/StoppedTasksCard/__snapshots__/StoppedTasksCardTable.test.js.snap +960 -0
  111. data/webpack/ForemanTasks/Components/TasksDashboard/Components/TasksCardsGrid/__snapshots__/TasksCardsGrid.test.js.snap +14 -11
  112. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardActions.js +1 -1
  113. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardConstants.js +2 -0
  114. data/webpack/ForemanTasks/Components/TasksDashboard/TasksDashboardSelectors.js +17 -11
  115. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardActions.test.js +2 -2
  116. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/TasksDashboardSelectors.test.js +26 -14
  117. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboard.test.js.snap +14 -11
  118. data/webpack/ForemanTasks/Components/TasksDashboard/__tests__/__snapshots__/TasksDashboardSelectors.test.js.snap +38 -22
  119. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/ConfirmModalSelectors.js +1 -0
  120. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/ConfirmModalSelectors.test.js +1 -0
  121. data/webpack/ForemanTasks/Components/TasksTable/Components/ConfirmModal/__test__/__snapshots__/ConfirmModalSelectors.test.js.snap +2 -0
  122. data/webpack/ForemanTasks/Components/TasksTable/TasksBulkActions.js +25 -8
  123. data/webpack/ForemanTasks/Components/TasksTable/TasksTableActions.js +3 -3
  124. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.js +6 -3
  125. data/webpack/ForemanTasks/Components/TasksTable/TasksTablePage.scss +0 -10
  126. data/webpack/ForemanTasks/Components/TasksTable/TasksTableSelectors.js +1 -0
  127. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksBulkActions.test.js +15 -2
  128. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTable.fixtures.js +1 -0
  129. data/webpack/ForemanTasks/Components/TasksTable/__tests__/TasksTablePage.test.js +2 -1
  130. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/SubTasksPage.test.js.snap +1 -0
  131. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksBulkActions.test.js.snap +48 -0
  132. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksIndexPage.test.js.snap +1 -0
  133. data/webpack/ForemanTasks/Components/TasksTable/__tests__/__snapshots__/TasksTablePage.test.js.snap +39 -7
  134. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/actionCellFormatter.test.js.snap +1 -0
  135. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/__snapshots__/selectionCellFormatter.test.js.snap +2 -0
  136. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/actionCellFormatter.test.js +1 -1
  137. data/webpack/ForemanTasks/Components/TasksTable/formatters/__test__/selectionCellFormatter.test.js +1 -1
  138. data/webpack/ForemanTasks/Components/TasksTable/formatters/actionCellFormatter.js +10 -7
  139. data/webpack/ForemanTasks/Components/TasksTable/formatters/selectionCellFormatter.js +7 -0
  140. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.js +39 -31
  141. data/webpack/ForemanTasks/Components/common/ActionButtons/ActionButton.test.js +17 -8
  142. data/webpack/ForemanTasks/Components/common/ActionButtons/__snapshots__/ActionButton.test.js.snap +8 -0
  143. data/webpack/ForemanTasks/Components/common/urlHelpers.js +7 -0
  144. data/webpack/ForemanTasks/ForemanTasksReducers.js +0 -2
  145. data/webpack/__mocks__/foremanReact/common/helpers.js +2 -0
  146. data/webpack/__mocks__/foremanReact/redux/API/APISelectors.js +10 -0
  147. data/webpack/__mocks__/foremanReact/redux/API/index.js +10 -0
  148. data/webpack/__mocks__/foremanReact/redux/middlewares/IntervalMiddleware.js +5 -0
  149. metadata +35 -17
  150. data/.travis.yml +0 -5
  151. data/app/assets/stylesheets/foreman_tasks/tasks.scss +0 -9
  152. data/script/travis_run_js_tests.sh +0 -7
  153. data/webpack/ForemanTasks/Components/TaskDetails/TaskDetailsReducer.js +0 -38
  154. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/TaskDetailsReducer.test.js +0 -33
  155. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/TaskDetailsReducer.test.js.snap +0 -26
  156. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/__snapshots__/integration.test.js.snap +0 -122
  157. data/webpack/ForemanTasks/Components/TaskDetails/__tests__/integration.test.js +0 -67
  158. data/webpack/__mocks__/foremanReact/API.js +0 -7
@@ -14,16 +14,6 @@
14
14
  }
15
15
  }
16
16
 
17
- .param-name {
18
- display: inline-block;
19
- width: 10em;
20
- }
21
-
22
- .task-details pre {
23
- white-space: pre;
24
- word-break: normal;
25
- }
26
-
27
17
  .tasks-time-row .time-label {
28
18
  float: left;
29
19
  }
@@ -39,6 +39,7 @@ export const selectResults = createSelector(
39
39
  ...result.available_actions,
40
40
  stoppable: result.state !== 'stopped',
41
41
  },
42
+ canEdit: result.can_edit,
42
43
  }))
43
44
  );
44
45
 
@@ -1,5 +1,5 @@
1
1
  import { testActionSnapshotWithFixtures } from '@theforeman/test';
2
- import API from 'foremanReact/API';
2
+ import { API } from 'foremanReact/redux/API';
3
3
  import {
4
4
  bulkCancelById,
5
5
  bulkCancelBySearch,
@@ -13,11 +13,12 @@ jest.mock('foremanReact/components/common/table', () => ({
13
13
  getTableItemsAction: jest.fn(controller => controller),
14
14
  }));
15
15
 
16
- jest.mock('foremanReact/API');
16
+ jest.mock('foremanReact/redux/API');
17
17
 
18
18
  const task = {
19
19
  id: 'some-id',
20
20
  name: 'some-name',
21
+ canEdit: true,
21
22
  };
22
23
 
23
24
  const fixtures = {
@@ -140,6 +141,18 @@ const fixtures = {
140
141
  url: 'some-url',
141
142
  parentTaskID: 'parent',
142
143
  }),
144
+ 'handles bulkCancelById requests with canEdit false': () => {
145
+ const selected = [{ ...task, isCancellable: true, canEdit: false }];
146
+ return bulkCancelById({ selected, url: 'some-url' });
147
+ },
148
+ 'handles bulkResumeById requests with canEdit false': () => {
149
+ const selected = [{ ...task, isResumable: false, canEdit: false }];
150
+ return bulkResumeById({ selected, url: 'some-url' });
151
+ },
152
+ 'handles bulkForceCancelById requests with canEdit false': () => {
153
+ const selected = [{ ...task, isResumable: false, canEdit: false }];
154
+ return bulkForceCancelById({ selected, url: 'some-url' });
155
+ },
143
156
  };
144
157
 
145
158
  describe('TasksTable bulk actions', () => {
@@ -9,6 +9,7 @@ export const minProps = {
9
9
  unselectAllRows: jest.fn(),
10
10
  selectRow: jest.fn(),
11
11
  unselectRow: jest.fn(),
12
+ reloadPage: jest.fn(),
12
13
  selectedRows: [],
13
14
  pagination: {
14
15
  page: 1,
@@ -12,9 +12,10 @@ const history = {
12
12
  const fixtures = {
13
13
  'render with minimal props': { ...minProps, history },
14
14
 
15
- 'render with Breadcrubs': {
15
+ 'render with Breadcrubs and edit permissions': {
16
16
  ...minProps,
17
17
  history,
18
+ results: [{ action: 'a', canEdit: true }],
18
19
  getBreadcrumbs: () => ({
19
20
  breadcrumbItems: [
20
21
  { caption: 'Tasks', url: `/foreman_tasks/tasks` },
@@ -30,6 +30,7 @@ exports[`SubTasksPage rendering render with minimal props 1`] = `
30
30
  }
31
31
  }
32
32
  parentTaskID="some-id"
33
+ reloadPage={[MockFunction]}
33
34
  results={
34
35
  Array [
35
36
  "a",
@@ -48,6 +48,22 @@ Array [
48
48
  ]
49
49
  `;
50
50
 
51
+ exports[`TasksTable bulk actions handles bulkCancelById requests with canEdit false 1`] = `
52
+ Array [
53
+ Array [
54
+ Object {
55
+ "payload": Object {
56
+ "message": Object {
57
+ "message": "Not all the selected tasks can be cancelled",
58
+ "type": "warning",
59
+ },
60
+ },
61
+ "type": "TOASTS_ADD",
62
+ },
63
+ ],
64
+ ]
65
+ `;
66
+
51
67
  exports[`TasksTable bulk actions handles bulkCancelBySearch requests 1`] = `
52
68
  Array [
53
69
  Array [
@@ -155,6 +171,22 @@ Array [
155
171
  ]
156
172
  `;
157
173
 
174
+ exports[`TasksTable bulk actions handles bulkForceCancelById requests with canEdit false 1`] = `
175
+ Array [
176
+ Array [
177
+ Object {
178
+ "payload": Object {
179
+ "message": Object {
180
+ "message": "User has no permission for 1 task(s)",
181
+ "type": "warning",
182
+ },
183
+ },
184
+ "type": "TOASTS_ADD",
185
+ },
186
+ ],
187
+ ]
188
+ `;
189
+
158
190
  exports[`TasksTable bulk actions handles bulkForceCancelBySearch requests 1`] = `
159
191
  Array [
160
192
  Array [
@@ -219,6 +251,22 @@ Array [
219
251
  ]
220
252
  `;
221
253
 
254
+ exports[`TasksTable bulk actions handles bulkResumeById requests with canEdit false 1`] = `
255
+ Array [
256
+ Array [
257
+ Object {
258
+ "payload": Object {
259
+ "message": Object {
260
+ "message": "Not all the selected tasks can be resumed",
261
+ "type": "warning",
262
+ },
263
+ },
264
+ "type": "TOASTS_ADD",
265
+ },
266
+ ],
267
+ ]
268
+ `;
269
+
222
270
  exports[`TasksTable bulk actions handles bulkResumeBySearch requests 1`] = `
223
271
  Array [
224
272
  Array [
@@ -21,6 +21,7 @@ exports[`TasksIndexPage rendering render with minimal props 1`] = `
21
21
  "perPage": 10,
22
22
  }
23
23
  }
24
+ reloadPage={[MockFunction]}
24
25
  results={
25
26
  Array [
26
27
  "a",
@@ -1,6 +1,6 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`TasksTablePage rendering render with Breadcrubs 1`] = `
3
+ exports[`TasksTablePage rendering render with Breadcrubs and edit permissions 1`] = `
4
4
  <div
5
5
  className="tasks-table-wrapper"
6
6
  >
@@ -66,15 +66,29 @@ exports[`TasksTablePage rendering render with Breadcrubs 1`] = `
66
66
  }
67
67
  searchQuery="a=b"
68
68
  searchable={true}
69
- toastNotifications="foreman-tasks-cancel"
70
69
  toolbarButtons={
71
70
  <React.Fragment>
71
+ <Button
72
+ active={false}
73
+ block={false}
74
+ bsClass="btn"
75
+ bsStyle="default"
76
+ disabled={false}
77
+ onClick={[Function]}
78
+ >
79
+ <Icon
80
+ name="refresh"
81
+ type="fa"
82
+ />
83
+
84
+ Refresh Data
85
+ </Button>
72
86
  <Spinner
73
87
  className=""
74
88
  inline={false}
75
89
  inverse={false}
76
90
  loading={true}
77
- size="lg"
91
+ size="md"
78
92
  />
79
93
  <ExportButton
80
94
  title="Export All"
@@ -112,10 +126,13 @@ exports[`TasksTablePage rendering render with Breadcrubs 1`] = `
112
126
  }
113
127
  }
114
128
  parentTaskID={null}
129
+ reloadPage={[MockFunction]}
115
130
  results={
116
131
  Array [
117
- "a",
118
- "b",
132
+ Object {
133
+ "action": "a",
134
+ "canEdit": true,
135
+ },
119
136
  ]
120
137
  }
121
138
  selectPage={[MockFunction]}
@@ -184,15 +201,29 @@ exports[`TasksTablePage rendering render with minimal props 1`] = `
184
201
  }
185
202
  searchQuery="a=b"
186
203
  searchable={true}
187
- toastNotifications="foreman-tasks-cancel"
188
204
  toolbarButtons={
189
205
  <React.Fragment>
206
+ <Button
207
+ active={false}
208
+ block={false}
209
+ bsClass="btn"
210
+ bsStyle="default"
211
+ disabled={false}
212
+ onClick={[Function]}
213
+ >
214
+ <Icon
215
+ name="refresh"
216
+ type="fa"
217
+ />
218
+
219
+ Refresh Data
220
+ </Button>
190
221
  <Spinner
191
222
  className=""
192
223
  inline={false}
193
224
  inverse={false}
194
225
  loading={true}
195
- size="lg"
226
+ size="md"
196
227
  />
197
228
  <ExportButton
198
229
  title="Export All"
@@ -230,6 +261,7 @@ exports[`TasksTablePage rendering render with minimal props 1`] = `
230
261
  }
231
262
  }
232
263
  parentTaskID={null}
264
+ reloadPage={[MockFunction]}
233
265
  results={
234
266
  Array [
235
267
  "a",
@@ -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
  />
@@ -4,45 +4,48 @@ import { translate as __ } from 'foremanReact/common/I18n';
4
4
  import { ActionButtons } from 'foremanReact/components/common/ActionButtons/ActionButtons';
5
5
 
6
6
  export const ActionButton = ({
7
+ canEdit,
7
8
  id,
8
9
  name,
9
10
  availableActions: { resumable, cancellable, stoppable },
10
11
  taskActions,
11
12
  }) => {
12
13
  const buttons = [];
13
- const isTitle = !(resumable || cancellable || stoppable);
14
+ const isTitle = canEdit && !(resumable || cancellable || stoppable);
14
15
  const title = isTitle ? __('Task cannot be canceled') : undefined;
15
- if (resumable) {
16
- buttons.push({
17
- title: __('Resume'),
18
- action: {
19
- disabled: !resumable,
20
- onClick: () => taskActions.resumeTask(id, name),
21
- id: `task-resume-button-${id}`,
22
- },
23
- });
24
- }
25
- if (cancellable || (!stoppable && !resumable)) {
26
- // Cancel is the default button that should be shown if no task action can be done
27
- buttons.push({
28
- title: __('Cancel'),
29
- action: {
30
- disabled: !cancellable,
31
- onClick: () => taskActions.cancelTask(id, name),
32
- id: `task-cancel-button-${id}`,
33
- },
34
- });
35
- }
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
+ }
36
38
 
37
- if (stoppable) {
38
- buttons.push({
39
- title: __('Force Cancel'),
40
- action: {
41
- disabled: !stoppable,
42
- onClick: () => taskActions.forceCancelTask(id, name),
43
- id: `task-force-cancel-button-${id}`,
44
- },
45
- });
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
+ }
46
49
  }
47
50
  return (
48
51
  <span title={title}>
@@ -52,6 +55,7 @@ export const ActionButton = ({
52
55
  };
53
56
 
54
57
  ActionButton.propTypes = {
58
+ canEdit: PropTypes.bool,
55
59
  id: PropTypes.string.isRequired,
56
60
  name: PropTypes.string.isRequired,
57
61
  availableActions: PropTypes.shape({
@@ -65,3 +69,7 @@ ActionButton.propTypes = {
65
69
  forceCancelTask: PropTypes.func,
66
70
  }).isRequired,
67
71
  };
72
+
73
+ ActionButton.defaultProps = {
74
+ canEdit: false,
75
+ };
@@ -7,6 +7,7 @@ const resumeTask = jest.fn();
7
7
  const cancelTask = jest.fn();
8
8
  const forceCancelTask = jest.fn();
9
9
  const taskActions = { resumeTask, cancelTask, forceCancelTask };
10
+ const minProps = { canEdit: true, id: 'id', name: 'some-name' };
10
11
  const fixtures = {
11
12
  'render with cancellable true props': {
12
13
  availableActions: {
@@ -14,8 +15,7 @@ const fixtures = {
14
15
  resumable: false,
15
16
  },
16
17
  taskActions,
17
- id: 'id',
18
- name: 'some-name',
18
+ ...minProps,
19
19
  },
20
20
  'render with resumable true props': {
21
21
  availableActions: {
@@ -23,8 +23,7 @@ const fixtures = {
23
23
  resumable: true,
24
24
  },
25
25
  taskActions,
26
- id: 'id',
27
- name: 'some-name',
26
+ ...minProps,
28
27
  },
29
28
  'render with stoppable and cancellable true props': {
30
29
  availableActions: {
@@ -32,8 +31,7 @@ const fixtures = {
32
31
  stoppable: true,
33
32
  },
34
33
  taskActions,
35
- id: 'id',
36
- name: 'some-name',
34
+ ...minProps,
37
35
  },
38
36
  'render with cancellable false props': {
39
37
  availableActions: {
@@ -41,8 +39,16 @@ const fixtures = {
41
39
  resumable: false,
42
40
  },
43
41
  taskActions,
44
- id: 'id',
45
- name: 'some-name',
42
+ ...minProps,
43
+ },
44
+ 'render with canEdit false': {
45
+ availableActions: {
46
+ cancellable: false,
47
+ resumable: false,
48
+ },
49
+ taskActions,
50
+ ...minProps,
51
+ canEdit: false,
46
52
  },
47
53
  };
48
54
 
@@ -57,6 +63,7 @@ describe('ActionButton', () => {
57
63
  <ActionButton
58
64
  id={id}
59
65
  name={name}
66
+ canEdit
60
67
  availableActions={{ cancellable: true }}
61
68
  taskActions={taskActions}
62
69
  />
@@ -69,6 +76,7 @@ describe('ActionButton', () => {
69
76
  <ActionButton
70
77
  id={id}
71
78
  name={name}
79
+ canEdit
72
80
  availableActions={{ resumable: true }}
73
81
  taskActions={taskActions}
74
82
  />
@@ -81,6 +89,7 @@ describe('ActionButton', () => {
81
89
  <ActionButton
82
90
  id={id}
83
91
  name={name}
92
+ canEdit
84
93
  availableActions={{ stoppable: true }}
85
94
  taskActions={taskActions}
86
95
  />