katello 3.7.1.1 → 3.8.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of katello might be problematic. Click here for more details.

Files changed (187) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +8 -7
  3. data/app/assets/javascripts/katello/common/index.js +0 -1
  4. data/app/assets/javascripts/katello/sync_management/index.js +0 -1
  5. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +477 -0
  6. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +1 -1
  7. data/app/controllers/katello/api/v2/activation_keys_controller.rb +2 -2
  8. data/app/controllers/katello/api/v2/api_controller.rb +3 -1
  9. data/app/controllers/katello/api/v2/content_credentials_controller.rb +1 -1
  10. data/app/controllers/katello/api/v2/content_view_filter_rules_controller.rb +1 -1
  11. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +15 -1
  12. data/app/controllers/katello/api/v2/environments_controller.rb +5 -2
  13. data/app/controllers/katello/api/v2/errata_controller.rb +48 -34
  14. data/app/controllers/katello/api/v2/gpg_keys_controller.rb +1 -1
  15. data/app/controllers/katello/api/v2/host_collections_controller.rb +1 -1
  16. data/app/controllers/katello/api/v2/host_packages_controller.rb +5 -1
  17. data/app/controllers/katello/api/v2/organizations_controller.rb +1 -1
  18. data/app/controllers/katello/api/v2/packages_controller.rb +33 -22
  19. data/app/controllers/katello/api/v2/products_controller.rb +1 -1
  20. data/app/controllers/katello/api/v2/repositories_controller.rb +6 -5
  21. data/app/controllers/katello/api/v2/repository_sets_controller.rb +1 -10
  22. data/app/controllers/katello/api/v2/sync_plans_controller.rb +1 -1
  23. data/app/controllers/katello/concerns/api/v2/repository_content_controller.rb +20 -12
  24. data/app/controllers/katello/remote_execution_controller.rb +6 -6
  25. data/app/helpers/katello/hosts_and_hostgroups_helper.rb +9 -37
  26. data/app/lib/actions/katello/content_view/promote.rb +6 -2
  27. data/app/lib/actions/katello/content_view_version/after_promote_hook.rb +11 -0
  28. data/app/lib/actions/katello/content_view_version/before_promote_hook.rb +11 -0
  29. data/app/lib/actions/katello/host/remove_subscriptions.rb +1 -1
  30. data/app/lib/actions/pulp/consumer/abstract_content_action.rb +0 -12
  31. data/app/lib/actions/pulp/consumer/content_install.rb +1 -1
  32. data/app/lib/actions/pulp/consumer/content_uninstall.rb +1 -1
  33. data/app/lib/actions/pulp/consumer/content_update.rb +1 -1
  34. data/app/lib/katello/resources/registry.rb +40 -0
  35. data/app/lib/katello/util/package.rb +9 -4
  36. data/app/models/katello/concerns/subscription_facet_host_extensions.rb +1 -1
  37. data/app/models/katello/content_view.rb +4 -12
  38. data/app/models/katello/content_view_version.rb +26 -0
  39. data/app/models/katello/glue/candlepin/owner.rb +8 -0
  40. data/app/models/katello/glue/candlepin/pool.rb +11 -11
  41. data/app/models/katello/glue/candlepin/repository.rb +1 -1
  42. data/app/models/katello/glue/pulp/repos.rb +1 -0
  43. data/app/models/katello/host/content_facet.rb +1 -2
  44. data/app/models/katello/kt_environment.rb +6 -0
  45. data/app/models/katello/product_content.rb +1 -4
  46. data/app/models/katello/repository.rb +2 -0
  47. data/app/models/katello/rpm.rb +118 -14
  48. data/app/services/katello/puppet_class_importer_extensions.rb +17 -20
  49. data/app/services/katello/ui_notifications/pulp/proxy_disk_space.rb +1 -3
  50. data/app/views/katello/api/v2/common/copy.json.rabl +3 -0
  51. data/app/views/katello/api/v2/environments/show.json.rabl +1 -1
  52. data/app/views/katello/api/v2/repositories/base.json.rabl +1 -0
  53. data/app/views/katello/api/v2/repositories/show.json.rabl +4 -2
  54. data/app/views/overrides/activation_keys/_host_environment_select.html.erb +3 -2
  55. data/config/katello.yaml +89 -0
  56. data/config/routes.rb +0 -1
  57. data/config/routes/api/registry.rb +29 -0
  58. data/config/routes/api/v2.rb +1 -1
  59. data/db/migrate/20180612163403_add_foreign_key_to_hypervisor_id.rb +0 -3
  60. data/db/migrate/20180614184822_add_unauthenticated_pull.rb +9 -0
  61. data/db/migrate/20180618195941_add_description_to_repository.rb +5 -0
  62. data/db/seeds.d/75-job_templates.rb +2 -5
  63. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-repository-sets-modal.controller.js +3 -4
  64. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-subscriptions-modal.controller.js +1 -4
  65. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-subscriptions-modal.html +1 -1
  66. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-host-register.controller.js +1 -1
  67. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages-installed.controller.js +1 -1
  68. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-add-subscriptions.controller.js +1 -1
  69. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/content-views.routes.js +1 -0
  70. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/content-view-version.controller.js +32 -18
  71. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version-details.html +1 -1
  72. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version-docker.html +2 -0
  73. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-details.html +32 -23
  74. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +6 -0
  75. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +8 -0
  76. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery.controller.js +1 -1
  77. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/views/discovery-create.html +1 -1
  78. data/engines/bastion_katello/app/assets/stylesheets/bastion_katello/bastion_katello.scss +0 -5
  79. data/lib/katello/engine.rb +1 -0
  80. data/lib/katello/permission_creator.rb +2 -0
  81. data/lib/katello/permissions/registry_permissions.rb +20 -0
  82. data/lib/katello/plugin.rb +1 -0
  83. data/lib/katello/tasks/clean_backend_objects.rake +3 -12
  84. data/lib/katello/version.rb +1 -1
  85. data/package.json +7 -10
  86. data/webpack/components/Search/Search.test.js +1 -3
  87. data/webpack/containers/Application/config.js +2 -9
  88. data/webpack/containers/Application/index.js +2 -4
  89. data/webpack/mockRequest.js +3 -3
  90. data/webpack/move_to_foreman/common/helpers.js +8 -45
  91. data/webpack/move_to_foreman/components/common/{EmptyState → emptyState}/index.js +3 -16
  92. data/webpack/move_to_foreman/components/common/table/components/Table.js +1 -1
  93. data/webpack/move_to_foreman/components/common/table/components/__snapshots__/CollapseSubscriptionGroupButton.test.js.snap +2 -2
  94. data/webpack/move_to_foreman/components/common/table/components/__snapshots__/TableSelectionCell.test.js.snap +1 -1
  95. data/webpack/move_to_foreman/components/common/table/components/__snapshots__/TableSelectionHeaderCell.test.js.snap +1 -1
  96. data/webpack/move_to_pf/LoadingState/LoadingState.js +14 -27
  97. data/webpack/move_to_pf/LoadingState/LoadingState.test.js +4 -8
  98. data/webpack/move_to_pf/react-bootstrap-select/index.js +1 -12
  99. data/webpack/redux/actions/RedHatRepositories/enabled.js +1 -0
  100. data/webpack/redux/actions/RedHatRepositories/helpers.js +5 -5
  101. data/webpack/redux/actions/RedHatRepositories/sets.js +1 -1
  102. data/webpack/redux/consts.js +0 -6
  103. data/webpack/redux/reducers/index.js +0 -2
  104. data/webpack/scenes/RedHatRepositories/components/EnabledRepository.js +23 -14
  105. data/webpack/scenes/RedHatRepositories/components/RepositorySetRepository.js +1 -1
  106. data/webpack/scenes/RedHatRepositories/components/SearchBar.js +0 -1
  107. data/webpack/scenes/RedHatRepositories/components/__tests__/__snapshots__/RecommendedRepositorySetsToggler.test.js.snap +1 -3
  108. data/webpack/scenes/RedHatRepositories/index.js +3 -7
  109. data/webpack/scenes/RedHatRepositories/index.scss +0 -1
  110. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailActions.js +8 -3
  111. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailReducer.js +1 -30
  112. data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.js +28 -111
  113. data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailReducer.test.js +1 -3
  114. data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetails.test.js +1 -6
  115. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +424 -519
  116. data/webpack/scenes/Subscriptions/Details/__tests__/subscriptionDetails.fixtures.js +4 -7
  117. data/webpack/scenes/Subscriptions/Details/index.js +3 -5
  118. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +34 -78
  119. data/webpack/scenes/Subscriptions/Manifest/ManifestActions.js +24 -5
  120. data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryReducer.js +1 -9
  121. data/webpack/scenes/Subscriptions/Manifest/__tests__/ManageManifestModal.test.js +0 -3
  122. data/webpack/scenes/Subscriptions/Manifest/__tests__/ManifestActions.test.js +8 -20
  123. data/webpack/scenes/Subscriptions/Manifest/__tests__/ManifestHistoryReducer.test.js +1 -3
  124. data/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap +7 -34
  125. data/webpack/scenes/Subscriptions/Manifest/__tests__/manifest.fixtures.js +16 -9
  126. data/webpack/scenes/Subscriptions/Manifest/index.js +0 -1
  127. data/webpack/scenes/Subscriptions/SubscriptionActions.js +26 -5
  128. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +0 -1
  129. data/webpack/scenes/Subscriptions/SubscriptionHelpers.js +0 -3
  130. data/webpack/scenes/Subscriptions/SubscriptionReducer.js +4 -11
  131. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +36 -31
  132. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsActions.js +12 -3
  133. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +27 -57
  134. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsReducer.js +3 -2
  135. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsTableSchema.js +5 -10
  136. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsActions.test.js +5 -10
  137. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsPage.test.js +4 -49
  138. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsReducer.test.js +3 -8
  139. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/__snapshots__/UpstreamSubscriptionsPage.test.js.snap +11 -21
  140. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/upstreamSubscriptions.fixtures.js +8 -5
  141. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +0 -2
  142. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsReducer.test.js +3 -9
  143. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +2 -14
  144. data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +17 -11
  145. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/EntitlementsInlineEditFormatter.js +5 -8
  146. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTable.js +58 -45
  147. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableHelpers.js +4 -11
  148. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableSchema.js +2 -2
  149. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js +3 -16
  150. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +365 -392
  151. data/webpack/scenes/Subscriptions/index.js +0 -1
  152. data/webpack/services/api/fixtures.js +353 -0
  153. data/webpack/services/api/index.js +1 -17
  154. data/webpack/test_setup.js +0 -2
  155. metadata +16 -37
  156. data/config/katello.yml +0 -59
  157. data/webpack/__mocks__/foremanReact/components/BreadcrumbBar.js +0 -3
  158. data/webpack/__mocks__/foremanReact/redux.js +0 -3
  159. data/webpack/__mocks__/foremanReact/redux/actions/toasts.js +0 -8
  160. data/webpack/components/SelectOrg/SelectOrg.scss +0 -3
  161. data/webpack/components/SelectOrg/SelectOrgAction.js +0 -41
  162. data/webpack/components/SelectOrg/SelectOrgReducer.js +0 -33
  163. data/webpack/components/SelectOrg/SetOrganization.js +0 -116
  164. data/webpack/components/WithOrganization/withOrganization.js +0 -28
  165. data/webpack/global_test_setup.js +0 -6
  166. data/webpack/helpers/caret.js +0 -6
  167. data/webpack/move_to_pf/Select/Select.js +0 -40
  168. data/webpack/scenes/Products/ProductActions.js +0 -24
  169. data/webpack/scenes/Products/ProductConstants.js +0 -3
  170. data/webpack/scenes/Products/__tests__/ProductActions.test.js +0 -40
  171. data/webpack/scenes/Products/__tests__/products.fixtures.js +0 -90
  172. data/webpack/scenes/RedHatRepositories/components/EnabledRepositoryContent.js +0 -34
  173. data/webpack/scenes/RedHatRepositories/components/__tests__/EnabledRepository.test.js +0 -36
  174. data/webpack/scenes/RedHatRepositories/components/__tests__/EnabledRepositoryContent.test.js +0 -27
  175. data/webpack/scenes/RedHatRepositories/components/__tests__/__snapshots__/EnabledRepository.test.js.snap +0 -25
  176. data/webpack/scenes/RedHatRepositories/components/__tests__/__snapshots__/EnabledRepositoryContent.test.js.snap +0 -47
  177. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailEnabledProducts.js +0 -54
  178. data/webpack/scenes/Subscriptions/Details/SubscriptionDetailProduct.js +0 -29
  179. data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.scss +0 -9
  180. data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailEnabledProducts.test.js +0 -18
  181. data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailProduct.test.js +0 -13
  182. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailEnabledProducts.test.js.snap +0 -45
  183. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailProduct.test.js.snap +0 -67
  184. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/EntitlementsInlineEditFormatter.test.js +0 -110
  185. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/EntitlementsInlineEditFormatter.test.js.snap +0 -228
  186. data/webpack/scenes/Tasks/helpers.js +0 -52
  187. data/webpack/services/api/testHelpers.js +0 -28
@@ -10,11 +10,9 @@ jest.mock('../../../move_to_foreman/foreman_toast_notifications');
10
10
 
11
11
  describe('subscriptions page', () => {
12
12
  const noop = () => {};
13
- const organization = { owner_details: { upstreamConsumer: 'blah' } };
14
13
 
15
14
  it('should render', async () => {
16
15
  const page = shallow(<SubscriptionsPage
17
- organization={organization}
18
16
  subscriptions={successState}
19
17
  loadSetting={loadSetting}
20
18
  loadSubscriptions={loadSubscriptions}
@@ -34,18 +34,14 @@ describe('subscriptions reducer', () => {
34
34
  it('should have error on SUBSCRIPTIONS_FAILURE', () => {
35
35
  expect(reducer(initialState, {
36
36
  type: types.SUBSCRIPTIONS_FAILURE,
37
- payload: {
38
- message: 'Unable to process request.',
39
- },
37
+ error: 'Unable to process request.',
40
38
  })).toEqual(errorState);
41
39
  });
42
40
 
43
41
  it('should have error on UPDATE_QUANTITY_FAILURE', () => {
44
42
  expect(reducer(initialState, {
45
43
  type: types.UPDATE_QUANTITY_FAILURE,
46
- payload: {
47
- message: 'Unable to process request.',
48
- },
44
+ error: 'Unable to process request.',
49
45
  })).toEqual(errorState);
50
46
  });
51
47
 
@@ -65,9 +61,7 @@ describe('subscriptions reducer', () => {
65
61
  it('should have error on SUBSCRIPTIONS_QUANTITIES_FAILURE', () => {
66
62
  expect(reducer(successState, {
67
63
  type: types.SUBSCRIPTIONS_QUANTITIES_FAILURE,
68
- payload: {
69
- message: 'Unable to process request.',
70
- },
64
+ error: 'Unable to process request.',
71
65
  })).toEqual(quantitiesErrorState);
72
66
  });
73
67
  });
@@ -53,7 +53,6 @@ exports[`subscriptions page should render 1`] = `
53
53
  >
54
54
  <LinkContainer
55
55
  activeClassName="active"
56
- disabled={false}
57
56
  exact={false}
58
57
  replace={false}
59
58
  strict={false}
@@ -94,7 +93,7 @@ exports[`subscriptions page should render 1`] = `
94
93
  title="Delete"
95
94
  tooltipId="delete-subscriptions-button-tooltip"
96
95
  tooltipPlacement="top"
97
- tooltipText="This is disabled because no subscriptions are selected."
96
+ tooltipText="This is disabled because no subscriptions are selected"
98
97
  />
99
98
  </FormGroup>
100
99
  </div>
@@ -112,23 +111,13 @@ exports[`subscriptions page should render 1`] = `
112
111
  id="subscriptions-table"
113
112
  >
114
113
  <SubscriptionsTable
115
- emptyState={
116
- Object {
117
- "action": Object {
118
- "onClick": [Function],
119
- "title": "Import a Manifest",
120
- },
121
- "description": "Import a Manifest to manage your Entitlements.",
122
- "header": "There are no Subscriptions to display",
123
- }
124
- }
125
114
  loadSubscriptions={[Function]}
126
115
  onDeleteSubscriptions={[Function]}
127
116
  onSubscriptionDeleteModalClose={[Function]}
128
117
  subscriptionDeleteModalOpen={false}
129
118
  subscriptions={
130
119
  Object {
131
- "availableQuantities": null,
120
+ "availableQuantities": Object {},
132
121
  "itemCount": 81,
133
122
  "loading": false,
134
123
  "pagination": Object {
@@ -195,7 +184,6 @@ exports[`subscriptions page should render 1`] = `
195
184
  "tasks": Array [],
196
185
  }
197
186
  }
198
- task={null}
199
187
  toggleDeleteButton={[Function]}
200
188
  updateQuantity={[Function]}
201
189
  />
@@ -1,5 +1,4 @@
1
1
  import Immutable from 'seamless-immutable';
2
- import { toastErrorAction, failureAction } from '../../../services/api/testHelpers';
3
2
 
4
3
  export const initialState = Immutable({
5
4
  loading: true,
@@ -10,7 +9,7 @@ export const initialState = Immutable({
10
9
  },
11
10
  itemCount: 0,
12
11
  quantitiesLoading: false,
13
- availableQuantities: null,
12
+ availableQuantities: {},
14
13
  tasks: [],
15
14
  });
16
15
 
@@ -243,12 +242,13 @@ export const successState = Immutable({
243
242
  },
244
243
  itemCount: 81,
245
244
  quantitiesLoading: false,
246
- availableQuantities: null,
245
+ availableQuantities: {},
247
246
  tasks: [],
248
247
  });
249
248
 
250
249
  export const errorState = Immutable({
251
250
  loading: false,
251
+ error: 'Unable to process request.',
252
252
  pagination: {
253
253
  page: 0,
254
254
  perPage: 20,
@@ -256,7 +256,7 @@ export const errorState = Immutable({
256
256
  itemCount: 0,
257
257
  results: [],
258
258
  quantitiesLoading: false,
259
- availableQuantities: null,
259
+ availableQuantities: {},
260
260
  tasks: [],
261
261
  });
262
262
 
@@ -278,7 +278,7 @@ export const loadingQuantitiesState = Immutable({
278
278
  export const quantitiesErrorState = Immutable({
279
279
  ...successState,
280
280
  quantitiesLoading: false,
281
- availableQuantities: {},
281
+ quantitiesError: 'Unable to process request.',
282
282
  });
283
283
 
284
284
  export const successActions = [
@@ -310,8 +310,10 @@ export const failureActions = [
310
310
  {
311
311
  type: 'SUBSCRIPTIONS_REQUEST',
312
312
  },
313
- failureAction('SUBSCRIPTIONS_FAILURE'),
314
- toastErrorAction(),
313
+ {
314
+ error: 'Request failed with status code 422',
315
+ type: 'SUBSCRIPTIONS_FAILURE',
316
+ },
315
317
  ];
316
318
 
317
319
  export const poolsUpdate = [{
@@ -338,16 +340,20 @@ export const updateQuantityFailureActions = [
338
340
  type: 'UPDATE_QUANTITY_REQUEST',
339
341
  quantities: poolsUpdate,
340
342
  },
341
- failureAction('UPDATE_QUANTITY_FAILURE'),
342
- toastErrorAction(),
343
+ {
344
+ error: 'Request failed with status code 422',
345
+ type: 'UPDATE_QUANTITY_FAILURE',
346
+ },
343
347
  ];
344
348
 
345
349
  export const loadQuantitiesFailureActions = [
346
350
  {
347
351
  type: 'SUBSCRIPTIONS_QUANTITIES_REQUEST',
348
352
  },
349
- failureAction('SUBSCRIPTIONS_QUANTITIES_FAILURE', 'Request failed with status code 500'),
350
- toastErrorAction('Request failed with status code 500'),
353
+ {
354
+ error: 'Request failed with status code 500',
355
+ type: 'SUBSCRIPTIONS_QUANTITIES_FAILURE',
356
+ },
351
357
  ];
352
358
 
353
359
  export const loadQuantitiesSuccessActions = [
@@ -34,18 +34,15 @@ export const entitlementsInlineEditFormatter =
34
34
  );
35
35
  },
36
36
  renderEdit: (value, additionalData) => {
37
- const { availableQuantity, availableQuantityLoaded } = additionalData.rowData;
37
+ const { availableQuantity } = additionalData.rowData;
38
38
 
39
39
  const className = inlineEditController.hasChanged(additionalData)
40
40
  ? 'editable editing changed'
41
41
  : 'editable editing';
42
42
 
43
- let maxMessage;
44
- if (availableQuantityLoaded && (availableQuantity !== undefined)) {
45
- maxMessage = (availableQuantity < 1)
46
- ? __('Unlimited')
47
- : sprintf(__('Max %(availableQuantity)s'), { availableQuantity });
48
- }
43
+ const maxMessage = (availableQuantity < 1)
44
+ ? __('Unlimited')
45
+ : sprintf(__('Max %(availableQuantity)s'), { availableQuantity });
49
46
 
50
47
  const validation = validateQuantity(value, availableQuantity);
51
48
 
@@ -58,7 +55,7 @@ export const entitlementsInlineEditFormatter =
58
55
  // The same issue prevents from correct switching inputs on TAB.
59
56
  // See the reactabular code for details:
60
57
  // https://github.com/reactabular/reactabular/blob/master/packages/reactabular-table/src/body-row.js#L58
61
- <Spinner loading={!availableQuantityLoaded} size="xs">
58
+ <Spinner loading={availableQuantity === undefined} size="xs">
62
59
  <FormGroup
63
60
  validationState={validation.state}
64
61
  >
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
3
3
  import classNames from 'classnames';
4
4
  import { sprintf } from 'jed';
5
5
  import { cloneDeep, findIndex, isEqual } from 'lodash';
6
- import { Table } from 'patternfly-react';
6
+ import { Table, Alert } from 'patternfly-react';
7
7
  import { LoadingState } from '../../../../move_to_pf/LoadingState';
8
8
  import { Table as ForemanTable, TableBody as ForemanTableBody } from '../../../../move_to_foreman/components/common/table';
9
9
  import ConfirmDialog from '../../../../move_to_foreman/components/common/ConfirmDialog';
@@ -11,11 +11,36 @@ import Dialog from '../../../../move_to_foreman/components/common/Dialog';
11
11
  import { recordsValid } from '../../SubscriptionValidations';
12
12
  import { createSubscriptionsTableSchema } from './SubscriptionsTableSchema';
13
13
  import { buildTableRows, groupSubscriptionsByProductId, buildPools } from './SubscriptionsTableHelpers';
14
- import { renderTaskStartedToast } from '../../../Tasks/helpers';
15
- import {
16
- BLOCKING_FOREMAN_TASK_TYPES,
17
- MANIFEST_TASKS_BULK_SEARCH_ID,
18
- } from '../../SubscriptionConstants';
14
+
15
+ const emptyStateData = {
16
+ header: __('There are no Subscriptions to display'),
17
+ description: __('Add Subscriptions to this Allocation to manage your Entitlements.'),
18
+ documentation: {
19
+ title: __('Learn more about adding Subscriptions to Allocations'),
20
+ url: 'http://redhat.com',
21
+ },
22
+ action: {
23
+ title: __('Add Subscriptions'),
24
+ url: 'subscriptions/add',
25
+ },
26
+ };
27
+
28
+ const ErrorAlerts = ({ errors }) => {
29
+ const alerts = errors.filter(Boolean).map(e => (
30
+ <Alert type={Alert.ALERT_TYPE_ERROR} key={e}>
31
+ <span>{e}</span>
32
+ </Alert>
33
+ ));
34
+
35
+ return (
36
+ <div>
37
+ {alerts}
38
+ </div>
39
+ );
40
+ };
41
+ ErrorAlerts.propTypes = {
42
+ errors: PropTypes.arrayOf(PropTypes.string).isRequired,
43
+ };
19
44
 
20
45
  class SubscriptionsTable extends Component {
21
46
  constructor(props) {
@@ -24,7 +49,7 @@ class SubscriptionsTable extends Component {
24
49
  this.state = {
25
50
  rows: undefined,
26
51
  subscriptions: undefined,
27
- groupedSubscriptions: undefined,
52
+ groupdSubscriptions: undefined,
28
53
  updatedQuantity: {},
29
54
  editing: false,
30
55
  showUpdateConfirmDialog: false,
@@ -39,14 +64,14 @@ class SubscriptionsTable extends Component {
39
64
  nextProps.subscriptions !== undefined &&
40
65
  !isEqual(nextProps.subscriptions, prevState.subscriptions)
41
66
  ) {
42
- const groupedSubscriptions = groupSubscriptionsByProductId(nextProps.subscriptions);
67
+ const groupdSubscriptions = groupSubscriptionsByProductId(nextProps.subscriptions);
43
68
  const rows = buildTableRows(
44
- groupedSubscriptions,
69
+ groupdSubscriptions,
45
70
  nextProps.subscriptions.availableQuantities,
46
71
  prevState.updatedQuantity,
47
72
  );
48
73
 
49
- return { rows, groupedSubscriptions, subscriptions: nextProps.subscriptions };
74
+ return { rows, groupdSubscriptions, subscriptions: nextProps.subscriptions };
50
75
  }
51
76
 
52
77
  return null;
@@ -54,19 +79,19 @@ class SubscriptionsTable extends Component {
54
79
 
55
80
  toggleSubscriptionGroup(groupId) {
56
81
  const { subscriptions } = this.props;
57
- const { groupedSubscriptions, updatedQuantity } = this.state;
58
- const { open } = groupedSubscriptions[groupId];
82
+ const { groupdSubscriptions, updatedQuantity } = this.state;
83
+ const { open } = groupdSubscriptions[groupId];
59
84
 
60
- groupedSubscriptions[groupId].open = !open;
85
+ groupdSubscriptions[groupId].open = !open;
61
86
 
62
87
 
63
88
  const rows = buildTableRows(
64
- groupedSubscriptions,
89
+ groupdSubscriptions,
65
90
  subscriptions.availableQuantities,
66
91
  updatedQuantity,
67
92
  );
68
93
 
69
- this.setState({ rows, groupedSubscriptions });
94
+ this.setState({ rows, groupdSubscriptions });
70
95
  }
71
96
 
72
97
  enableEditing(editingState) {
@@ -77,11 +102,11 @@ class SubscriptionsTable extends Component {
77
102
  }
78
103
 
79
104
  updateRows(updatedQuantity) {
80
- const { groupedSubscriptions } = this.state;
105
+ const { groupdSubscriptions } = this.state;
81
106
  const { subscriptions } = this.props;
82
107
 
83
108
  const rows = buildTableRows(
84
- groupedSubscriptions,
109
+ groupdSubscriptions,
85
110
  subscriptions.availableQuantities,
86
111
  updatedQuantity,
87
112
  );
@@ -109,15 +134,7 @@ class SubscriptionsTable extends Component {
109
134
  confirmEdit() {
110
135
  this.showUpdateConfirm(false);
111
136
  if (Object.keys(this.state.updatedQuantity).length > 0) {
112
- this.props.updateQuantity(buildPools(this.state.updatedQuantity))
113
- .then(() =>
114
- this.props.bulkSearch({
115
- search_id: MANIFEST_TASKS_BULK_SEARCH_ID,
116
- type: 'all',
117
- active_only: true,
118
- action_types: BLOCKING_FOREMAN_TASK_TYPES,
119
- }))
120
- .then(() => renderTaskStartedToast(this.props.task));
137
+ this.props.updateQuantity(buildPools(this.state.updatedQuantity));
121
138
  }
122
139
  this.enableEditing(false);
123
140
  }
@@ -140,17 +157,16 @@ class SubscriptionsTable extends Component {
140
157
  }
141
158
 
142
159
  render() {
143
- const { subscriptions, emptyState } = this.props;
144
- const { groupedSubscriptions } = this.state;
145
- const allSubscriptionResults = subscriptions.results;
160
+ const { subscriptions } = this.props;
161
+ const { groupdSubscriptions } = this.state;
146
162
 
147
163
  const groupingController = {
148
164
  isCollapseable: ({ rowData }) =>
149
165
  // it is the first subscription in the group
150
- rowData.id === groupedSubscriptions[rowData.product_id].subscriptions[0].id &&
166
+ rowData.id === groupdSubscriptions[rowData.product_id].subscriptions[0].id &&
151
167
  // the group contains more then one subscription
152
- groupedSubscriptions[rowData.product_id].subscriptions.length > 1,
153
- isCollapsed: ({ rowData }) => !groupedSubscriptions[rowData.product_id].open,
168
+ groupdSubscriptions[rowData.product_id].subscriptions.length > 1,
169
+ isCollapsed: ({ rowData }) => !groupdSubscriptions[rowData.product_id].open,
154
170
  toggle: ({ rowData }) => this.toggleSubscriptionGroup(rowData.product_id),
155
171
  };
156
172
 
@@ -186,8 +202,7 @@ class SubscriptionsTable extends Component {
186
202
  },
187
203
  };
188
204
 
189
- const checkAllRowsSelected = () =>
190
- allSubscriptionResults.length === this.state.selectedRows.length;
205
+ const checkAllRowsSelected = () => this.state.rows.length === this.state.selectedRows.length;
191
206
 
192
207
  const updateDeleteButton = () => {
193
208
  this.props.toggleDeleteButton(this.state.selectedRows.length > 0);
@@ -203,7 +218,7 @@ class SubscriptionsTable extends Component {
203
218
  );
204
219
  } else {
205
220
  this.setState(
206
- { selectedRows: allSubscriptionResults.map(row => row.id) },
221
+ { selectedRows: this.state.rows.map(row => row.id) },
207
222
  updateDeleteButton,
208
223
  );
209
224
  }
@@ -231,7 +246,7 @@ class SubscriptionsTable extends Component {
231
246
  };
232
247
 
233
248
  let bodyMessage;
234
- if (allSubscriptionResults.length === 0 && subscriptions.searchIsActive) {
249
+ if (subscriptions.results.length === 0 && subscriptions.searchIsActive) {
235
250
  bodyMessage = __('No subscriptions match your search criteria.');
236
251
  }
237
252
 
@@ -243,9 +258,15 @@ class SubscriptionsTable extends Component {
243
258
 
244
259
  return (
245
260
  <LoadingState loading={subscriptions.loading} loadingText={__('Loading')}>
261
+ <ErrorAlerts
262
+ errors={[
263
+ subscriptions.error,
264
+ subscriptions.quantitiesError,
265
+ ]}
266
+ />
246
267
  <ForemanTable
247
268
  columns={columnsDefinition}
248
- emptyState={emptyState}
269
+ emptyState={emptyStateData}
249
270
  bodyMessage={bodyMessage}
250
271
  rows={this.state.rows}
251
272
  components={{
@@ -331,7 +352,6 @@ class SubscriptionsTable extends Component {
331
352
  SubscriptionsTable.propTypes = {
332
353
  loadSubscriptions: PropTypes.func.isRequired,
333
354
  updateQuantity: PropTypes.func.isRequired,
334
- emptyState: PropTypes.shape({}).isRequired,
335
355
  subscriptions: PropTypes.shape({
336
356
  results: PropTypes.array,
337
357
  }).isRequired,
@@ -339,13 +359,6 @@ SubscriptionsTable.propTypes = {
339
359
  onDeleteSubscriptions: PropTypes.func.isRequired,
340
360
  onSubscriptionDeleteModalClose: PropTypes.func.isRequired,
341
361
  toggleDeleteButton: PropTypes.func.isRequired,
342
- task: PropTypes.shape({}),
343
- bulkSearch: PropTypes.func,
344
- };
345
-
346
- SubscriptionsTable.defaultProps = {
347
- task: { humanized: {} },
348
- bulkSearch: undefined,
349
362
  };
350
363
 
351
364
  export default SubscriptionsTable;
@@ -1,22 +1,15 @@
1
1
  const buildTableRow = (subscription, availableQuantities, updatedQuantity) => {
2
- const availableQuantityLoaded = !!availableQuantities;
3
- const availableQuantity = availableQuantityLoaded
4
- ? availableQuantities[subscription.id]
5
- : null;
6
-
7
2
  if (updatedQuantity[subscription.id]) {
8
3
  return {
9
4
  ...subscription,
10
5
  entitlementsChanged: true,
11
6
  quantity: updatedQuantity[subscription.id],
12
- availableQuantity,
13
- availableQuantityLoaded,
7
+ availableQuantity: availableQuantities[subscription.id],
14
8
  };
15
9
  }
16
10
  return {
17
11
  ...subscription,
18
- availableQuantity,
19
- availableQuantityLoaded,
12
+ availableQuantity: availableQuantities[subscription.id],
20
13
  };
21
14
  };
22
15
 
@@ -34,10 +27,10 @@ const buildTableRowsFromGroup = (subscriptionGroup, availableQuantities, updated
34
27
  return [buildTableRow(firstSubscription, availableQuantities, updatedQuantity)];
35
28
  };
36
29
 
37
- export const buildTableRows = (groupedSubscriptions, availableQuantities, updatedQuantity) => {
30
+ export const buildTableRows = (groupdSubscriptions, availableQuantities, updatedQuantity) => {
38
31
  const rows = [];
39
32
 
40
- Object.values(groupedSubscriptions).forEach(subscriptionGroup =>
33
+ Object.values(groupdSubscriptions).forEach(subscriptionGroup =>
41
34
  rows.push(...buildTableRowsFromGroup(subscriptionGroup, availableQuantities, updatedQuantity)));
42
35
 
43
36
  return rows;