katello 4.10.0 → 4.11.0.rc2

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 (498) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/locale/bn/katello.js +254 -215
  3. data/app/assets/javascripts/katello/locale/bn_IN/katello.js +254 -215
  4. data/app/assets/javascripts/katello/locale/ca/katello.js +254 -215
  5. data/app/assets/javascripts/katello/locale/cs/katello.js +254 -215
  6. data/app/assets/javascripts/katello/locale/cs_CZ/katello.js +254 -215
  7. data/app/assets/javascripts/katello/locale/de/katello.js +260 -245
  8. data/app/assets/javascripts/katello/locale/de_AT/katello.js +254 -215
  9. data/app/assets/javascripts/katello/locale/de_DE/katello.js +254 -215
  10. data/app/assets/javascripts/katello/locale/el/katello.js +254 -215
  11. data/app/assets/javascripts/katello/locale/en/katello.js +254 -215
  12. data/app/assets/javascripts/katello/locale/en_GB/katello.js +254 -215
  13. data/app/assets/javascripts/katello/locale/en_US/katello.js +254 -215
  14. data/app/assets/javascripts/katello/locale/es/katello.js +257 -233
  15. data/app/assets/javascripts/katello/locale/et_EE/katello.js +254 -215
  16. data/app/assets/javascripts/katello/locale/fr/katello.js +268 -268
  17. data/app/assets/javascripts/katello/locale/gl/katello.js +254 -215
  18. data/app/assets/javascripts/katello/locale/gu/katello.js +254 -215
  19. data/app/assets/javascripts/katello/locale/he_IL/katello.js +254 -215
  20. data/app/assets/javascripts/katello/locale/hi/katello.js +254 -215
  21. data/app/assets/javascripts/katello/locale/id/katello.js +254 -215
  22. data/app/assets/javascripts/katello/locale/it/katello.js +254 -221
  23. data/app/assets/javascripts/katello/locale/ja/katello.js +268 -268
  24. data/app/assets/javascripts/katello/locale/ka/katello.js +261 -231
  25. data/app/assets/javascripts/katello/locale/kn/katello.js +254 -215
  26. data/app/assets/javascripts/katello/locale/ko/katello.js +255 -222
  27. data/app/assets/javascripts/katello/locale/locale/katello.js +1049 -1012
  28. data/app/assets/javascripts/katello/locale/ml_IN/katello.js +254 -215
  29. data/app/assets/javascripts/katello/locale/mr/katello.js +254 -215
  30. data/app/assets/javascripts/katello/locale/nl_NL/katello.js +254 -215
  31. data/app/assets/javascripts/katello/locale/or/katello.js +254 -215
  32. data/app/assets/javascripts/katello/locale/pa/katello.js +254 -215
  33. data/app/assets/javascripts/katello/locale/pl/katello.js +254 -215
  34. data/app/assets/javascripts/katello/locale/pl_PL/katello.js +254 -215
  35. data/app/assets/javascripts/katello/locale/pt/katello.js +254 -215
  36. data/app/assets/javascripts/katello/locale/pt_BR/katello.js +257 -233
  37. data/app/assets/javascripts/katello/locale/ro/katello.js +254 -215
  38. data/app/assets/javascripts/katello/locale/ro_RO/katello.js +254 -215
  39. data/app/assets/javascripts/katello/locale/ru/katello.js +255 -222
  40. data/app/assets/javascripts/katello/locale/sl/katello.js +254 -215
  41. data/app/assets/javascripts/katello/locale/sv_SE/katello.js +254 -215
  42. data/app/assets/javascripts/katello/locale/ta/katello.js +254 -215
  43. data/app/assets/javascripts/katello/locale/ta_IN/katello.js +254 -215
  44. data/app/assets/javascripts/katello/locale/te/katello.js +254 -215
  45. data/app/assets/javascripts/katello/locale/tr/katello.js +254 -215
  46. data/app/assets/javascripts/katello/locale/vi/katello.js +254 -215
  47. data/app/assets/javascripts/katello/locale/vi_VN/katello.js +254 -215
  48. data/app/assets/javascripts/katello/locale/zh/katello.js +254 -215
  49. data/app/assets/javascripts/katello/locale/zh_CN/katello.js +268 -268
  50. data/app/assets/javascripts/katello/locale/zh_TW/katello.js +255 -222
  51. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +15 -2
  52. data/app/controllers/katello/api/v2/capsule_content_controller.rb +21 -4
  53. data/app/controllers/katello/api/v2/capsules_controller.rb +11 -1
  54. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +1 -1
  55. data/app/controllers/katello/api/v2/docker_tags_controller.rb +2 -0
  56. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +2 -1
  57. data/app/controllers/katello/api/v2/organizations_controller.rb +2 -2
  58. data/app/controllers/katello/api/v2/repositories_controller.rb +1 -0
  59. data/app/controllers/katello/api/v2/simple_content_access_controller.rb +5 -5
  60. data/app/controllers/katello/api/v2/sync_plans_controller.rb +11 -3
  61. data/app/controllers/katello/concerns/api/api_controller.rb +6 -0
  62. data/app/controllers/katello/concerns/api/v2/hosts_bulk_actions_controller_extensions.rb +23 -0
  63. data/app/controllers/katello/concerns/filtered_auto_complete_search.rb +1 -1
  64. data/app/controllers/katello/concerns/organizations_controller_extensions.rb +2 -0
  65. data/app/controllers/katello/remote_execution_controller.rb +1 -1
  66. data/app/jobs/create_host_lifecycle_expire_soon_notifications.rb +11 -0
  67. data/app/lib/actions/katello/applicability/hosts/bulk_generate.rb +10 -0
  68. data/app/lib/actions/katello/capsule_content/refresh_repos.rb +8 -2
  69. data/app/lib/actions/katello/capsule_content/sync.rb +30 -10
  70. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +13 -0
  71. data/app/lib/actions/katello/capsule_content/update_content_counts.rb +24 -0
  72. data/app/lib/actions/katello/content_view/promote.rb +9 -0
  73. data/app/lib/actions/katello/content_view/publish.rb +9 -0
  74. data/app/lib/actions/katello/orphan_cleanup/remove_orphans.rb +8 -0
  75. data/app/lib/actions/katello/repository/sync.rb +11 -0
  76. data/app/lib/actions/pulp3/capsule_content/reclaim_space.rb +5 -0
  77. data/app/lib/actions/pulp3/content_view_version/create_export_history.rb +6 -1
  78. data/app/lib/actions/pulp3/content_view_version/export.rb +8 -0
  79. data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +1 -1
  80. data/app/lib/katello/concerns/base_template_scope_extensions.rb +14 -1
  81. data/app/lib/katello/errors.rb +1 -0
  82. data/app/lib/katello/repo_discovery.rb +2 -2
  83. data/app/lib/katello/validators/content_view_environment_coherent_default_validator.rb +22 -0
  84. data/app/lib/katello/validators/content_view_environment_validator.rb +1 -0
  85. data/app/mailers/katello/task_mailer.rb +54 -0
  86. data/app/models/katello/concerns/host_managed_extensions.rb +41 -1
  87. data/app/models/katello/concerns/organization_extensions.rb +1 -1
  88. data/app/models/katello/concerns/smart_proxy_extensions.rb +75 -3
  89. data/app/models/katello/concerns/subscription_facet_host_extensions.rb +6 -0
  90. data/app/models/katello/content_view.rb +21 -0
  91. data/app/models/katello/content_view_environment.rb +6 -1
  92. data/app/models/katello/docker_meta_tag.rb +1 -1
  93. data/app/models/katello/docker_tag.rb +1 -1
  94. data/app/models/katello/erratum.rb +1 -1
  95. data/app/models/katello/host/content_facet.rb +10 -7
  96. data/app/models/katello/product.rb +8 -0
  97. data/app/models/katello/repository.rb +31 -6
  98. data/app/models/katello/rhel_lifecycle_status.rb +214 -0
  99. data/app/models/katello/sync_plan.rb +19 -1
  100. data/app/models/katello/yum_metadata_file.rb +1 -1
  101. data/app/services/katello/applicability/applicable_content_helper.rb +1 -1
  102. data/app/services/katello/event_queue.rb +10 -2
  103. data/app/services/katello/host_status_manager.rb +1 -0
  104. data/app/services/katello/product_content_importer.rb +45 -3
  105. data/app/services/katello/pulp3/ansible_collection.rb +1 -0
  106. data/app/services/katello/pulp3/api/core.rb +1 -1
  107. data/app/services/katello/pulp3/deb.rb +1 -0
  108. data/app/services/katello/pulp3/docker_manifest.rb +1 -0
  109. data/app/services/katello/pulp3/docker_manifest_list.rb +9 -4
  110. data/app/services/katello/pulp3/docker_tag.rb +1 -0
  111. data/app/services/katello/pulp3/erratum.rb +1 -0
  112. data/app/services/katello/pulp3/file_unit.rb +1 -0
  113. data/app/services/katello/pulp3/module_stream.rb +1 -0
  114. data/app/services/katello/pulp3/package_group.rb +1 -0
  115. data/app/services/katello/pulp3/pulp_content_unit.rb +39 -0
  116. data/app/services/katello/pulp3/repository_mirror.rb +21 -2
  117. data/app/services/katello/pulp3/rpm.rb +1 -0
  118. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +1 -1
  119. data/app/services/katello/pulp3/srpm.rb +3 -2
  120. data/app/services/katello/registration_manager.rb +6 -3
  121. data/app/services/katello/repository_type.rb +2 -1
  122. data/app/services/katello/ui_notifications/hosts/lifecycle_expire_soon.rb +58 -0
  123. data/app/views/foreman/job_templates/resolve_traces.erb +1 -1
  124. data/app/views/foreman/smart_proxies/_content_tab.html.erb +1 -3
  125. data/app/views/katello/api/v2/capsule_content/sync_status.json.rabl +39 -1
  126. data/app/views/katello/api/v2/content_export_incrementals/repository.json.rabl +13 -0
  127. data/app/views/katello/api/v2/content_facet/show.json.rabl +4 -0
  128. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -1
  129. data/app/views/katello/api/v2/docker_tags/_base.json.rabl +28 -6
  130. data/app/views/katello/hosts/_errata_counts.html.erb +2 -2
  131. data/app/views/katello/task_mailer/cv_promote_failure.html.erb +31 -0
  132. data/app/views/katello/task_mailer/cv_promote_failure.text.erb +13 -0
  133. data/app/views/katello/task_mailer/cv_publish_failure.html.erb +31 -0
  134. data/app/views/katello/task_mailer/cv_publish_failure.text.erb +13 -0
  135. data/app/views/katello/task_mailer/proxy_sync_failure.html.erb +45 -0
  136. data/app/views/katello/task_mailer/proxy_sync_failure.text.erb +25 -0
  137. data/app/views/katello/task_mailer/repo_sync_failure.html.erb +35 -0
  138. data/app/views/katello/task_mailer/repo_sync_failure.text.erb +15 -0
  139. data/app/views/overrides/organizations/_edit_override.html.erb +4 -0
  140. data/config/routes/api/v2.rb +2 -0
  141. data/db/migrate/20230825180856_add_content_counts_to_smart_proxy.rb +7 -0
  142. data/db/migrate/20231020153017_create_indexes_for_nvra_and_epoch.rb +6 -0
  143. data/db/seeds.d/106-mail_notifications.rb +32 -0
  144. data/db/seeds.d/109-katello-notification-blueprints.rb +6 -0
  145. data/engines/bastion/app/assets/javascripts/bastion/components/views/bst-alert.html +1 -1
  146. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/activation-keys.controller.js +4 -0
  147. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-add-host-collections.controller.js +3 -0
  148. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-add-subscriptions.controller.js +3 -0
  149. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-associations.controller.js +4 -0
  150. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-copy.controller.js +7 -2
  151. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-host-collections.controller.js +3 -0
  152. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-repository-sets.controller.js +3 -0
  153. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-subscriptions.controller.js +3 -0
  154. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/new/new-activation-key.controller.js +6 -2
  155. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.controller.js +16 -1
  156. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/rhel-lifecycle-notice.html +5 -0
  157. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credentials.controller.js +7 -2
  158. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-acs.controller.js +7 -2
  159. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-products.controller.js +7 -2
  160. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-repositories.controller.js +7 -2
  161. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/new/new-content-credential.controller.js +3 -0
  162. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-errata-modal.controller.js +5 -1
  163. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-debs-actions.controller.js +5 -1
  164. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-debs-applicable.controller.js +3 -0
  165. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-debs-installed.controller.js +3 -0
  166. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-errata.controller.js +4 -0
  167. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-module-streams.controller.js +3 -0
  168. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages-applicable.controller.js +3 -0
  169. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages-installed.controller.js +3 -0
  170. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages.controller.js +3 -0
  171. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-traces.controller.js +4 -0
  172. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-debs-actions.html +1 -1
  173. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-debs-applicable.html +1 -1
  174. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-debs-installed.html +1 -1
  175. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-errata.html +3 -3
  176. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-module-streams.html +1 -1
  177. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-actions.html +1 -1
  178. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-applicable.html +1 -1
  179. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-installed.html +1 -1
  180. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-traces.html +3 -3
  181. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +5 -0
  182. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.routes.js +1 -1
  183. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-add-host-collections.controller.js +4 -1
  184. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-add-subscriptions.controller.js +3 -0
  185. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-host-collections.controller.js +4 -1
  186. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-repository-sets.controller.js +3 -0
  187. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-subscriptions.controller.js +3 -0
  188. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-add-subscriptions.html +1 -1
  189. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-details.html +4 -3
  190. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-host-collections.html +1 -1
  191. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-info.html +3 -3
  192. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-provisioning-info.html +2 -2
  193. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-subscriptions-list.html +1 -1
  194. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-subscriptions.html +1 -1
  195. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +3 -3
  196. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/debs.controller.js +7 -0
  197. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/details/deb-content-views.controller.js +8 -1
  198. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/details/deb-repositories.controller.js +10 -2
  199. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/details/docker-tag-environments.controller.js +5 -2
  200. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/details/docker-tag-repositories.controller.js +6 -2
  201. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/docker-tags.controller.js +6 -3
  202. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/environment-content.controller.js +13 -0
  203. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/environment.controller.js +6 -0
  204. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/new-environment.controller.js +8 -2
  205. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/apply-errata.controller.js +4 -0
  206. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/erratum-content-hosts.controller.js +7 -2
  207. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/erratum-repositories.controller.js +7 -2
  208. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/erratum.controller.js +6 -2
  209. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum-info.html +2 -2
  210. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/errata.controller.js +5 -0
  211. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/views/errata.html +1 -1
  212. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/files/details/file-content-views.controller.js +10 -2
  213. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/files/details/file-repositories.controller.js +8 -1
  214. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/files/files.controller.js +9 -2
  215. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/host-collection-add-hosts.controller.js +3 -0
  216. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/host-collection-copy.controller.js +7 -2
  217. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/host-collection-hosts.controller.js +3 -0
  218. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/host-collections.controller.js +4 -0
  219. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/new/new-host-collection.controller.js +6 -2
  220. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host.factory.js +4 -0
  221. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +166 -43
  222. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/fr.po +4 -0
  223. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/translations.js +1 -1
  224. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/packages.controller.js +7 -0
  225. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/product-repositories.controller.js +5 -0
  226. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-advanced-sync.controller.js +6 -2
  227. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-manage-content.controller.js +11 -0
  228. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +3 -0
  229. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/views/product-repositories.html +2 -2
  230. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery-create.controller.js +3 -0
  231. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery.controller.js +3 -0
  232. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/new/product-form.controller.js +6 -2
  233. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.controller.js +4 -0
  234. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/views/content-access-mode-banner.html +1 -1
  235. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/sync-plan-add-products.controller.js +5 -1
  236. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/sync-plan-products.controller.js +4 -0
  237. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/new/new-sync-plan.controller.js +3 -0
  238. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/sync-plans.controller.js +4 -0
  239. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/task-details.controller.js +6 -2
  240. data/lib/katello/engine.rb +2 -3
  241. data/lib/katello/permission_creator.rb +2 -2
  242. data/lib/katello/plugin.rb +4 -0
  243. data/lib/katello/repository_types/ostree.rb +1 -0
  244. data/lib/katello/repository_types/python.rb +1 -0
  245. data/lib/katello/scheduled_jobs.rb +1 -1
  246. data/lib/katello/version.rb +1 -1
  247. data/locale/action_names.rb +1 -3
  248. data/locale/bn/LC_MESSAGES/katello.mo +0 -0
  249. data/locale/bn/katello.po +236 -197
  250. data/locale/bn/katello.po.time_stamp +0 -0
  251. data/locale/bn_IN/LC_MESSAGES/katello.mo +0 -0
  252. data/locale/bn_IN/katello.po +236 -197
  253. data/locale/bn_IN/katello.po.time_stamp +0 -0
  254. data/locale/ca/LC_MESSAGES/katello.mo +0 -0
  255. data/locale/ca/katello.po +236 -197
  256. data/locale/ca/katello.po.time_stamp +0 -0
  257. data/locale/cs/LC_MESSAGES/katello.mo +0 -0
  258. data/locale/cs/katello.po +236 -206
  259. data/locale/cs/katello.po.time_stamp +0 -0
  260. data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
  261. data/locale/cs_CZ/katello.po +236 -197
  262. data/locale/cs_CZ/katello.po.time_stamp +0 -0
  263. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  264. data/locale/de/katello.po +241 -202
  265. data/locale/de/katello.po.time_stamp +0 -0
  266. data/locale/de_AT/LC_MESSAGES/katello.mo +0 -0
  267. data/locale/de_AT/katello.po +236 -197
  268. data/locale/de_AT/katello.po.time_stamp +0 -0
  269. data/locale/de_DE/LC_MESSAGES/katello.mo +0 -0
  270. data/locale/de_DE/katello.po +236 -197
  271. data/locale/de_DE/katello.po.time_stamp +0 -0
  272. data/locale/el/LC_MESSAGES/katello.mo +0 -0
  273. data/locale/el/katello.po +236 -197
  274. data/locale/el/katello.po.time_stamp +0 -0
  275. data/locale/en/LC_MESSAGES/katello.mo +0 -0
  276. data/locale/en/katello.po +236 -197
  277. data/locale/en/katello.po.time_stamp +0 -0
  278. data/locale/en_GB/LC_MESSAGES/katello.mo +0 -0
  279. data/locale/en_GB/katello.po +236 -197
  280. data/locale/en_GB/katello.po.time_stamp +0 -0
  281. data/locale/en_US/LC_MESSAGES/katello.mo +0 -0
  282. data/locale/en_US/katello.po +236 -197
  283. data/locale/en_US/katello.po.time_stamp +0 -0
  284. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  285. data/locale/es/katello.po +238 -199
  286. data/locale/es/katello.po.time_stamp +0 -0
  287. data/locale/et_EE/LC_MESSAGES/katello.mo +0 -0
  288. data/locale/et_EE/katello.po +236 -197
  289. data/locale/et_EE/katello.po.time_stamp +0 -0
  290. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  291. data/locale/fr/katello.po +247 -208
  292. data/locale/fr/katello.po.time_stamp +0 -0
  293. data/locale/gl/LC_MESSAGES/katello.mo +0 -0
  294. data/locale/gl/katello.po +236 -197
  295. data/locale/gl/katello.po.time_stamp +0 -0
  296. data/locale/gu/LC_MESSAGES/katello.mo +0 -0
  297. data/locale/gu/katello.po +236 -197
  298. data/locale/gu/katello.po.time_stamp +0 -0
  299. data/locale/he_IL/LC_MESSAGES/katello.mo +0 -0
  300. data/locale/he_IL/katello.po +236 -197
  301. data/locale/he_IL/katello.po.time_stamp +0 -0
  302. data/locale/hi/LC_MESSAGES/katello.mo +0 -0
  303. data/locale/hi/katello.po +236 -197
  304. data/locale/hi/katello.po.time_stamp +0 -0
  305. data/locale/id/LC_MESSAGES/katello.mo +0 -0
  306. data/locale/id/katello.po +236 -197
  307. data/locale/id/katello.po.time_stamp +0 -0
  308. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  309. data/locale/it/katello.po +236 -197
  310. data/locale/it/katello.po.time_stamp +0 -0
  311. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  312. data/locale/ja/katello.po +247 -208
  313. data/locale/ja/katello.po.time_stamp +0 -0
  314. data/locale/ka/LC_MESSAGES/katello.mo +0 -0
  315. data/locale/ka/katello.po +241 -202
  316. data/locale/ka/katello.po.time_stamp +0 -0
  317. data/locale/katello.pot +1427 -1296
  318. data/locale/kn/LC_MESSAGES/katello.mo +0 -0
  319. data/locale/kn/katello.po +236 -197
  320. data/locale/kn/katello.po.time_stamp +0 -0
  321. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  322. data/locale/ko/katello.po +236 -197
  323. data/locale/ko/katello.po.time_stamp +0 -0
  324. data/locale/ml_IN/LC_MESSAGES/katello.mo +0 -0
  325. data/locale/ml_IN/katello.po +236 -197
  326. data/locale/ml_IN/katello.po.time_stamp +0 -0
  327. data/locale/mr/LC_MESSAGES/katello.mo +0 -0
  328. data/locale/mr/katello.po +236 -197
  329. data/locale/mr/katello.po.time_stamp +0 -0
  330. data/locale/nl_NL/LC_MESSAGES/katello.mo +0 -0
  331. data/locale/nl_NL/katello.po +236 -197
  332. data/locale/nl_NL/katello.po.time_stamp +0 -0
  333. data/locale/or/LC_MESSAGES/katello.mo +0 -0
  334. data/locale/or/katello.po +236 -197
  335. data/locale/or/katello.po.time_stamp +0 -0
  336. data/locale/pa/LC_MESSAGES/katello.mo +0 -0
  337. data/locale/pa/katello.po +236 -197
  338. data/locale/pa/katello.po.time_stamp +0 -0
  339. data/locale/pl/LC_MESSAGES/katello.mo +0 -0
  340. data/locale/pl/katello.po +236 -197
  341. data/locale/pl/katello.po.time_stamp +0 -0
  342. data/locale/pl_PL/LC_MESSAGES/katello.mo +0 -0
  343. data/locale/pl_PL/katello.po +236 -197
  344. data/locale/pl_PL/katello.po.time_stamp +0 -0
  345. data/locale/pt/LC_MESSAGES/katello.mo +0 -0
  346. data/locale/pt/katello.po +236 -197
  347. data/locale/pt/katello.po.time_stamp +0 -0
  348. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  349. data/locale/pt_BR/katello.po +238 -199
  350. data/locale/pt_BR/katello.po.time_stamp +0 -0
  351. data/locale/ro/LC_MESSAGES/katello.mo +0 -0
  352. data/locale/ro/katello.po +236 -197
  353. data/locale/ro/katello.po.time_stamp +0 -0
  354. data/locale/ro_RO/LC_MESSAGES/katello.mo +0 -0
  355. data/locale/ro_RO/katello.po +236 -197
  356. data/locale/ro_RO/katello.po.time_stamp +0 -0
  357. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  358. data/locale/ru/katello.po +236 -197
  359. data/locale/ru/katello.po.time_stamp +0 -0
  360. data/locale/sl/LC_MESSAGES/katello.mo +0 -0
  361. data/locale/sl/katello.po +236 -197
  362. data/locale/sl/katello.po.time_stamp +0 -0
  363. data/locale/sv_SE/LC_MESSAGES/katello.mo +0 -0
  364. data/locale/sv_SE/katello.po +236 -197
  365. data/locale/sv_SE/katello.po.time_stamp +0 -0
  366. data/locale/ta/LC_MESSAGES/katello.mo +0 -0
  367. data/locale/ta/katello.po +236 -197
  368. data/locale/ta/katello.po.time_stamp +0 -0
  369. data/locale/ta_IN/LC_MESSAGES/katello.mo +0 -0
  370. data/locale/ta_IN/katello.po +236 -197
  371. data/locale/ta_IN/katello.po.time_stamp +0 -0
  372. data/locale/te/LC_MESSAGES/katello.mo +0 -0
  373. data/locale/te/katello.po +236 -197
  374. data/locale/te/katello.po.time_stamp +0 -0
  375. data/locale/tr/LC_MESSAGES/katello.mo +0 -0
  376. data/locale/tr/katello.po +236 -197
  377. data/locale/tr/katello.po.time_stamp +0 -0
  378. data/locale/vi/LC_MESSAGES/katello.mo +0 -0
  379. data/locale/vi/katello.po +236 -197
  380. data/locale/vi/katello.po.time_stamp +0 -0
  381. data/locale/vi_VN/LC_MESSAGES/katello.mo +0 -0
  382. data/locale/vi_VN/katello.po +236 -197
  383. data/locale/vi_VN/katello.po.time_stamp +0 -0
  384. data/locale/zh/LC_MESSAGES/katello.mo +0 -0
  385. data/locale/zh/katello.po +236 -197
  386. data/locale/zh/katello.po.time_stamp +0 -0
  387. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  388. data/locale/zh_CN/katello.po +247 -208
  389. data/locale/zh_CN/katello.po.time_stamp +0 -0
  390. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  391. data/locale/zh_TW/katello.po +236 -197
  392. data/locale/zh_TW/katello.po.time_stamp +0 -0
  393. data/webpack/components/Table/EmptyStateMessage.js +7 -4
  394. data/webpack/components/Table/MainTable.scss +18 -17
  395. data/webpack/components/Table/TableWrapper.js +4 -1
  396. data/webpack/components/extensions/HostDetails/ActionsBar/index.js +45 -4
  397. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.scss +9 -7
  398. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.js +1 -1
  399. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsModal.js +1 -1
  400. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeActions.js +29 -7
  401. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.js +106 -66
  402. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.scss +6 -0
  403. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeConstants.js +2 -0
  404. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeEditModal.js +53 -29
  405. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeSelectors.js +7 -6
  406. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/__tests__/SystemPurposeCard.test.js +24 -5
  407. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/__tests__/SystemPurposeEditModal.test.js +137 -7
  408. data/webpack/components/extensions/HostDetails/DetailsTabCards/HwPropertiesCard.js +11 -10
  409. data/webpack/components/extensions/HostDetails/DetailsTabCards/RegistrationCard.js +8 -2
  410. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +27 -10
  411. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/HostErrataActions.js +3 -22
  412. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/HostErrataConstants.js +0 -1
  413. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +3 -2
  414. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js +2 -2
  415. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +48 -12
  416. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +22 -10
  417. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionHooks.js +1 -1
  418. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +2 -2
  419. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerModal.js +71 -5
  420. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerModal.scss +16 -0
  421. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesEnabler.js +4 -1
  422. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesTab.js +6 -2
  423. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +2 -1
  424. data/webpack/components/extensions/HostDetails/Tabs/__tests__/tracesTab.test.js +25 -0
  425. data/webpack/components/extensions/Hosts/ActionsBar/index.js +36 -0
  426. data/webpack/components/extensions/Hosts/constants.js +2 -0
  427. data/webpack/components/extensions/RegistrationCommands/RegistrationCommandsPageHelpers.js +13 -7
  428. data/webpack/components/extensions/RegistrationCommands/__tests__/__snapshots__/ActivationKeys.test.js.snap +9 -1
  429. data/webpack/components/extensions/RegistrationCommands/fields/ActivationKeys.js +87 -22
  430. data/webpack/components/extensions/RegistrationCommands/index.js +17 -41
  431. data/webpack/global_index.js +11 -2
  432. data/webpack/redux/reducers/RedHatRepositories/enabled.fixtures.js +4 -0
  433. data/webpack/redux/reducers/RedHatRepositories/enabled.js +1 -0
  434. data/webpack/scenes/ActivationKeys/Details/ActivationKeyDetails.js +10 -1
  435. data/webpack/scenes/ActivationKeys/Details/ActivationKeyDetails.scss +33 -31
  436. data/webpack/scenes/AlternateContentSources/MainTable/ACSTable.js +3 -1
  437. data/webpack/scenes/Content/ContentConfig.js +3 -0
  438. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +6 -4
  439. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.scss +8 -6
  440. data/webpack/scenes/ContentViews/Delete/ContentViewDeleteWizard.js +1 -0
  441. data/webpack/scenes/ContentViews/Delete/Steps/CVEnvironmentSelectionForm.scss +4 -2
  442. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +3 -4
  443. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +2 -2
  444. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +5 -5
  445. data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/compositeCVDetails.fixtures.json +393 -0
  446. data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/contentViewComponents.test.js +30 -4
  447. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +3 -1
  448. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +3 -3
  449. data/webpack/scenes/ContentViews/Details/Repositories/RepoIcon.js +2 -1
  450. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareTable.js +1 -1
  451. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +1 -1
  452. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveCVVersionWizard.js +1 -1
  453. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsTable.js +1 -1
  454. data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +24 -1
  455. data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +1 -0
  456. data/webpack/scenes/ContentViews/Publish/__tests__/publishContentView.test.js +42 -0
  457. data/webpack/scenes/ContentViews/Publish/cvPublishForm.scss +13 -11
  458. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +2 -1
  459. data/webpack/scenes/ContentViews/__tests__/mockDetails.fixtures.json +2 -1
  460. data/webpack/scenes/Hosts/ChangeContentSource/index.js +4 -3
  461. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetails.js +1 -2
  462. data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetails.test.js.snap +1 -1
  463. data/webpack/scenes/RedHatRepositories/RedHatRepositoriesPage.js +2 -1
  464. data/webpack/scenes/RedHatRepositories/__tests__/__snapshots__/RedHatRepositoriesPage.test.js.snap +6 -0
  465. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepository.js +4 -1
  466. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepositoryContent.js +13 -4
  467. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/EnabledRepositoryContent.test.js +1 -0
  468. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/__snapshots__/EnabledRepository.test.js.snap +1 -0
  469. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/__snapshots__/EnabledRepositoryContent.test.js.snap +3 -2
  470. data/webpack/scenes/SmartProxy/AdditionalCapsuleContent.js +93 -0
  471. data/webpack/scenes/SmartProxy/Content.js +12 -4
  472. data/webpack/scenes/SmartProxy/ExpandableCvDetails.js +107 -0
  473. data/webpack/scenes/SmartProxy/ExpandedSmartProxyRepositories.js +139 -0
  474. data/webpack/scenes/SmartProxy/SmartProxyContentActions.js +17 -4
  475. data/webpack/scenes/SmartProxy/SmartProxyContentConstants.js +1 -0
  476. data/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js +150 -0
  477. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.fixtures.json +799 -0
  478. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js +29 -17
  479. data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.js +16 -19
  480. data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.scss +12 -8
  481. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +21 -18
  482. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnConfigurationForm.scss +4 -2
  483. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.scss +38 -19
  484. data/webpack/scenes/Subscriptions/Manifest/index.js +0 -2
  485. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +38 -12
  486. data/webpack/scenes/Subscriptions/SubscriptionsPage.scss +38 -36
  487. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +16 -13
  488. data/webpack/utils/helpers.js +0 -1
  489. metadata +148 -33
  490. data/app/controllers/katello/concerns/api/v2/bulk_hosts_extensions.rb +0 -47
  491. data/webpack/components/Table/TableHooks.js +0 -315
  492. data/webpack/components/Table/__test__/useBulkSelect.test.js +0 -99
  493. data/webpack/components/extensions/RegistrationCommands/__tests__/LifeCycleEnvironment.test.js +0 -11
  494. data/webpack/components/extensions/RegistrationCommands/__tests__/__snapshots__/LifeCycleEnvironment.test.js.snap +0 -29
  495. data/webpack/components/extensions/RegistrationCommands/fields/LifecycleEnvironment.js +0 -57
  496. data/webpack/scenes/SmartProxy/SmartProxyContentTable.js +0 -164
  497. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentResult.fixtures.json +0 -140
  498. data/webpack/scenes/Subscriptions/Manifest/Manifest.scss +0 -16
@@ -17,14 +17,20 @@ import {
17
17
  } from '@patternfly/react-core';
18
18
  import { FormattedMessage } from 'react-intl';
19
19
  import { translate as __ } from 'foremanReact/common/I18n';
20
- import { selectOrganizationStatus, selectOrganization, selectAvailableReleaseVersions, selectAvailableReleaseVersionsStatus } from './SystemPurposeSelectors';
21
- import { getAvailableReleaseVersions, getOrganization, updateSystemPurposeAttributes } from './SystemPurposeActions';
20
+ import {
21
+ selectOrganizationStatus,
22
+ selectOrganization,
23
+ selectAvailableReleaseVersions,
24
+ selectAvailableReleaseVersionsStatus,
25
+ } from './SystemPurposeSelectors';
26
+ import { getHostAvailableReleaseVersions, getAKAvailableReleaseVersions, getOrganization, updateHostSysPurposeAttributes, updateAKSysPurposeAttributes } from './SystemPurposeActions';
22
27
  import HOST_DETAILS_KEY from '../../HostDetailsConstants';
23
28
  import { defaultUsages, defaultRoles, defaultServiceLevels } from './SystemPurposeConstants';
29
+ import { getActivationKey } from '../../../../../scenes/ActivationKeys/Details/ActivationKeyActions';
24
30
 
25
31
  const SystemPurposeEditModal = ({
26
- closeModal, hostName, purposeRole, purposeUsage, purposeAddons,
27
- serviceLevel, releaseVersion, isOpen, orgId, hostId,
32
+ closeModal, name, purposeRole, purposeUsage, purposeAddons,
33
+ serviceLevel, releaseVersion, isOpen, orgId, id, type,
28
34
  }) => {
29
35
  const initialPurposeRole = purposeRole ?? '';
30
36
  const initialServiceLevel = serviceLevel ?? '';
@@ -54,22 +60,24 @@ const SystemPurposeEditModal = ({
54
60
  const availableServiceLevels = orgDetails?.serviceLevels ?? [];
55
61
  const { addons: availableAddons, roles: availableRoles, usage: availableUsages }
56
62
  = availableSyspurposeAttributes;
63
+ const selectorAPIKey = type === 'host' ? 'AVAILABLE_RELEASE_VERSIONS' : 'RELEASES';
57
64
 
58
65
  const availableReleaseVersionsStatus
59
- = useSelector(state => selectAvailableReleaseVersionsStatus(state, orgId));
66
+ = useSelector(state => selectAvailableReleaseVersionsStatus(state, id, selectorAPIKey));
60
67
  const availableReleaseVersions = useSelector(state =>
61
- selectAvailableReleaseVersions(state, hostId))?.results ?? [];
68
+ selectAvailableReleaseVersions(state, id, selectorAPIKey))?.results ?? [];
62
69
  useEffect(() => {
63
70
  if (orgId && orgStatus !== STATUS.RESOLVED) {
64
71
  dispatch(getOrganization({ orgId }));
65
72
  }
66
73
  }, [orgId, orgStatus, dispatch]);
67
74
 
75
+ const actionToDispatch = type === 'host' ? getHostAvailableReleaseVersions : getAKAvailableReleaseVersions;
68
76
  useEffect(() => {
69
- if (hostId && availableReleaseVersionsStatus !== STATUS.RESOLVED) {
70
- dispatch(getAvailableReleaseVersions({ hostId }));
77
+ if (id && availableReleaseVersionsStatus !== STATUS.RESOLVED) {
78
+ dispatch(actionToDispatch({ id }));
71
79
  }
72
- }, [hostId, availableReleaseVersionsStatus, dispatch]);
80
+ }, [type, id, availableReleaseVersionsStatus, actionToDispatch, dispatch]);
73
81
 
74
82
  const toggleAddonSelect = isOpenState => setAddonSelectOpen(isOpenState);
75
83
 
@@ -88,7 +96,7 @@ const SystemPurposeEditModal = ({
88
96
  type: 'API_GET',
89
97
  payload: {
90
98
  key: HOST_DETAILS_KEY,
91
- url: `/api/hosts/${hostName}`,
99
+ url: `/api/hosts/${name}`,
92
100
  },
93
101
  });
94
102
 
@@ -133,18 +141,33 @@ const SystemPurposeEditModal = ({
133
141
  closeModal();
134
142
  const optionsToValue = (options, stateValue) =>
135
143
  options.find(option => option.value === stateValue)?.value;
136
- dispatch(updateSystemPurposeAttributes({
137
- hostId,
138
- attributes: {
139
- autoheal: true,
140
- purpose_role: optionsToValue(roleOptions, selectedRole),
141
- purpose_usage: optionsToValue(usageOptions, selectedUsage),
142
- purpose_addons: selectedAddons,
143
- release_version: optionsToValue(releaseVersionOptions, selectedReleaseVersion),
144
- service_level: optionsToValue(serviceLevelOptions, selectedServiceLevel),
145
- },
146
- refreshHostDetails,
147
- }));
144
+ if (type === 'host') {
145
+ dispatch(updateHostSysPurposeAttributes({
146
+ id,
147
+ attributes: {
148
+ autoheal: true,
149
+ purpose_role: optionsToValue(roleOptions, selectedRole),
150
+ purpose_usage: optionsToValue(usageOptions, selectedUsage),
151
+ purpose_addons: selectedAddons,
152
+ release_version: optionsToValue(releaseVersionOptions, selectedReleaseVersion),
153
+ service_level: optionsToValue(serviceLevelOptions, selectedServiceLevel),
154
+ },
155
+ refreshHostDetails,
156
+ }));
157
+ } else {
158
+ dispatch(updateAKSysPurposeAttributes({
159
+ id,
160
+ attributes: {
161
+ autoheal: true,
162
+ purpose_role: optionsToValue(roleOptions, selectedRole),
163
+ purpose_usage: optionsToValue(usageOptions, selectedUsage),
164
+ purpose_addons: selectedAddons,
165
+ release_version: optionsToValue(releaseVersionOptions, selectedReleaseVersion),
166
+ service_level: optionsToValue(serviceLevelOptions, selectedServiceLevel),
167
+ },
168
+ refreshAKDetails: () => dispatch(getActivationKey(id)),
169
+ }));
170
+ }
148
171
  };
149
172
 
150
173
  const handleCancel = () => {
@@ -180,9 +203,9 @@ const SystemPurposeEditModal = ({
180
203
  <FormattedMessage
181
204
  className="syspurpose-edit-modal-blurb"
182
205
  id="syspurpose-edit-modal-blurb"
183
- defaultMessage={__('Select system purpose attributes for host {hostName}.')}
206
+ defaultMessage={type === 'host' ? __('Select system purpose attributes for host {name}.') : __('Select system purpose attributes for activation key {name}.')}
184
207
  values={{
185
- hostName: <strong>{hostName}</strong>,
208
+ name: <strong>{name}</strong>,
186
209
  }}
187
210
  />
188
211
  <Form isHorizontal style={{ marginTop: '1.3rem' }}>
@@ -239,7 +262,7 @@ const SystemPurposeEditModal = ({
239
262
  </FormGroup>
240
263
  <FormGroup label={__('Release version')} fieldId="releaseVersion">
241
264
  <FormSelect
242
- id="release_version"
265
+ id="releaseVersion"
243
266
  name="release_version"
244
267
  ouiaId="release-version-select"
245
268
  value={selectedReleaseVersion}
@@ -288,7 +311,7 @@ export default SystemPurposeEditModal;
288
311
 
289
312
  SystemPurposeEditModal.propTypes = {
290
313
  closeModal: PropTypes.func.isRequired,
291
- hostName: PropTypes.string,
314
+ name: PropTypes.string,
292
315
  purposeRole: PropTypes.string.isRequired,
293
316
  purposeUsage: PropTypes.string.isRequired,
294
317
  purposeAddons: PropTypes.arrayOf(PropTypes.string).isRequired,
@@ -296,12 +319,13 @@ SystemPurposeEditModal.propTypes = {
296
319
  releaseVersion: PropTypes.string,
297
320
  isOpen: PropTypes.bool.isRequired,
298
321
  orgId: PropTypes.number,
299
- hostId: PropTypes.number,
322
+ id: PropTypes.number,
323
+ type: PropTypes.string.isRequired,
300
324
  };
301
325
 
302
326
  SystemPurposeEditModal.defaultProps = {
303
- hostName: '',
327
+ name: '',
304
328
  orgId: null,
305
- hostId: null,
329
+ id: null,
306
330
  releaseVersion: '',
307
331
  };
@@ -14,12 +14,13 @@ export const selectOrganizationStatus = (state, orgId) =>
14
14
  export const selectOrganizationError = (state, orgId) =>
15
15
  selectAPIError(state, `ORGANIZATION_${orgId}`);
16
16
 
17
- export const selectAvailableReleaseVersions = (state, hostId) =>
18
- selectAPIResponse(state, `AVAILABLE_RELEASE_VERSIONS_${hostId}`) ?? {};
17
+ export const selectAvailableReleaseVersions = (state, id, key = 'AVAILABLE_RELEASE_VERSIONS') =>
18
+ selectAPIResponse(state, `${key}_${id}`) ?? {};
19
19
 
20
- export const selectAvailableReleaseVersionsStatus = (state, hostId) =>
21
- selectAPIStatus(state, `AVAILABLE_RELEASE_VERSIONS_${hostId}`) ??
20
+ export const selectAvailableReleaseVersionsStatus = (state, id, key = 'AVAILABLE_RELEASE_VERSIONS') =>
21
+ selectAPIStatus(state, `${key}_${id}`) ??
22
22
  STATUS.PENDING;
23
23
 
24
- export const selectAvailableReleaseVersionsError = (state, hostId) =>
25
- selectAPIError(state, `AVAILABLE_RELEASE_VERSIONS_${hostId}`);
24
+ export const selectAvailableReleaseVersionsError = (state, id, key = 'AVAILABLE_RELEASE_VERSIONS') =>
25
+ selectAPIError(state, `${key}_${id}`);
26
+
@@ -4,6 +4,7 @@ import HOST_DETAILS from '../../../HostDetailsConstants';
4
4
  import SystemPurposeCard from '../SystemPurposeCard';
5
5
  import katelloApi, { foremanApi } from '../../../../../../services/api';
6
6
  import { assertNockRequest, nockInstance } from '../../../../../../test-utils/nockWrapper';
7
+ import { ACTIVATION_KEY } from '../../../../../../scenes/ActivationKeys/Details/ActivationKeyConstants';
7
8
 
8
9
  const organizationDetails = katelloApi.getApiUrl('/organizations/1');
9
10
  const availableReleaseVersions = foremanApi.getApiUrl('/hosts/1/subscriptions/available_release_versions');
@@ -24,11 +25,17 @@ const baseHostDetails = {
24
25
  },
25
26
  };
26
27
 
27
- const renderOptions = () => ({
28
- apiNamespace: HOST_DETAILS,
28
+ const akHostDetails = {
29
+ ...baseHostDetails,
30
+ subscription_facet_attributes: undefined,
31
+ ...baseHostDetails.subscription_facet_attributes,
32
+ };
33
+
34
+ const renderOptions = (apiNamespace = HOST_DETAILS) => ({
35
+ apiNamespace,
29
36
  initialState: {
30
37
  API: {
31
- HOST_DETAILS: {
38
+ [apiNamespace]: {
32
39
  response: {
33
40
  id: 1,
34
41
  name: 'test-host',
@@ -40,7 +47,7 @@ const renderOptions = () => ({
40
47
  },
41
48
  });
42
49
 
43
- test('shows system purpose details', async (done) => {
50
+ test('shows system purpose details for a host', async (done) => {
44
51
  const orgScope = nockInstance
45
52
  .get(organizationDetails)
46
53
  .reply(200, {
@@ -49,7 +56,6 @@ test('shows system purpose details', async (done) => {
49
56
  const availableReleaseVersionsScope = nockInstance
50
57
  .get(availableReleaseVersions)
51
58
  .reply(200, []);
52
-
53
59
  const { getByText }
54
60
  = renderWithRedux(<SystemPurposeCard hostDetails={baseHostDetails} />, renderOptions());
55
61
  expect(getByText('Red Hat Enterprise Linux Server')).toBeInTheDocument();
@@ -63,6 +69,19 @@ test('shows system purpose details', async (done) => {
63
69
  assertNockRequest(availableReleaseVersionsScope, done);
64
70
  });
65
71
 
72
+ test('shows system purpose details for an activation key', () => {
73
+ const { getByText } = renderWithRedux(
74
+ <SystemPurposeCard akDetails={akHostDetails} />,
75
+ renderOptions(`${ACTIVATION_KEY}_1`),
76
+ );
77
+ expect(getByText('Red Hat Enterprise Linux Server')).toBeInTheDocument();
78
+ expect(getByText('Production')).toBeInTheDocument();
79
+ expect(getByText('Premium')).toBeInTheDocument();
80
+ expect(getByText('Addon1')).toBeInTheDocument();
81
+ expect(getByText('Addon2')).toBeInTheDocument();
82
+ expect(getByText('8')).toBeInTheDocument();
83
+ });
84
+
66
85
 
67
86
  test('shows edit button for a user with edit_hosts permission', async (done) => {
68
87
  const orgScope = nockInstance
@@ -5,10 +5,14 @@ import HOST_DETAILS from '../../../HostDetailsConstants';
5
5
  import SystemPurposeEditModal from '../SystemPurposeEditModal';
6
6
  import { assertNockRequest, nockInstance } from '../../../../../../test-utils/nockWrapper';
7
7
  import katelloApi, { foremanApi } from '../../../../../../services/api';
8
+ import { ACTIVATION_KEY } from '../../../../../../scenes/ActivationKeys/Details/ActivationKeyConstants';
8
9
 
9
10
  const organizationDetails = katelloApi.getApiUrl('/organizations/1');
10
11
  const availableReleaseVersions = foremanApi.getApiUrl('/hosts/1/subscriptions/available_release_versions');
12
+ const akAvailableReleaseVersions = katelloApi.getApiUrl('/activation_keys/1/releases');
11
13
  const hostEditUrl = foremanApi.getApiUrl('/hosts/1');
14
+ const akEditUrl = katelloApi.getApiUrl('/activation_keys/1');
15
+ const akDetailsGetUrl = akEditUrl;
12
16
  const hostDetailsGetUrl = '/api/hosts/test-host';
13
17
 
14
18
  const baseHostDetails = {
@@ -26,24 +30,33 @@ const baseHostDetails = {
26
30
  },
27
31
  };
28
32
 
33
+ const akHostDetails = {
34
+ ...baseHostDetails,
35
+ permissions: {
36
+ edit_activation_keys: true,
37
+ },
38
+ subscription_facet_attributes: undefined,
39
+ ...baseHostDetails.subscription_facet_attributes,
40
+ };
41
+
29
42
  const facetAttributes = propsToCamelCase(baseHostDetails.subscription_facet_attributes);
30
43
  const baseAttributes = {
31
- hostName: 'test-host',
44
+ name: 'test-host',
32
45
  closeModal: jest.fn(),
33
46
  isOpen: true,
34
47
  orgId: 1,
35
- hostId: 1,
48
+ id: 1,
36
49
  };
37
50
 
38
- const renderOptions = () => ({
39
- apiNamespace: HOST_DETAILS,
51
+ const renderOptions = (apiNamespace = HOST_DETAILS) => ({
52
+ apiNamespace,
40
53
  initialState: {
41
54
  API: {
42
- HOST_DETAILS: {
55
+ [apiNamespace]: {
43
56
  response: {
44
57
  id: 1,
45
58
  name: 'test-host',
46
- ...baseHostDetails,
59
+ ...(apiNamespace === HOST_DETAILS ? baseHostDetails : akHostDetails),
47
60
  },
48
61
  status: 'RESOLVED',
49
62
  },
@@ -64,6 +77,7 @@ describe('SystemPurposeEditModal', () => {
64
77
 
65
78
  const { getByText }
66
79
  = renderWithRedux(<SystemPurposeEditModal
80
+ type="host"
67
81
  {...baseAttributes}
68
82
  {...facetAttributes}
69
83
  />, renderOptions());
@@ -90,6 +104,7 @@ describe('SystemPurposeEditModal', () => {
90
104
  .reply(200, []);
91
105
  const { getAllByText }
92
106
  = renderWithRedux(<SystemPurposeEditModal
107
+ type="host"
93
108
  {...
94
109
  {
95
110
  ...baseAttributes,
@@ -103,7 +118,7 @@ describe('SystemPurposeEditModal', () => {
103
118
  assertNockRequest(orgScope);
104
119
  assertNockRequest(availableReleaseVersionsScope);
105
120
  });
106
- test('Calls API and changes syspurpose values', async (done) => {
121
+ test('Calls API and changes syspurpose values for host', async (done) => {
107
122
  const orgScope = nockInstance
108
123
  .get(organizationDetails)
109
124
  .reply(200, {
@@ -134,6 +149,7 @@ describe('SystemPurposeEditModal', () => {
134
149
 
135
150
  const { getByLabelText, getByRole }
136
151
  = renderWithRedux(<SystemPurposeEditModal
152
+ type="host"
137
153
  {...baseAttributes}
138
154
  {...facetAttributes}
139
155
  />, renderOptions());
@@ -158,4 +174,118 @@ describe('SystemPurposeEditModal', () => {
158
174
  });
159
175
  assertNockRequest(hostDetailsScope, done);
160
176
  });
177
+ test('Calls API and changes syspurpose values for activation key', async (done) => {
178
+ const orgScope = nockInstance
179
+ .get(organizationDetails)
180
+ .reply(200, {
181
+ id: 1,
182
+ });
183
+ const availableReleaseVersionsScope = nockInstance
184
+ .get(akAvailableReleaseVersions)
185
+ .reply(200, []);
186
+ const akEditScope = nockInstance
187
+ .put(akEditUrl, {
188
+ id: 1,
189
+ activation_key: {
190
+ // we're going to change role from 'Server' to 'Workstation'
191
+ autoheal: true,
192
+ purpose_role: 'Red Hat Enterprise Linux Workstation',
193
+ purpose_usage: 'Production',
194
+ purpose_addons: ['Addon1', 'Addon2'],
195
+ release_version: '8',
196
+ service_level: 'Premium',
197
+ },
198
+ })
199
+ .reply(200);
200
+ const akDetailsScope = nockInstance
201
+ .get(akDetailsGetUrl)
202
+ .reply(200);
203
+
204
+ const { getByLabelText, getByRole }
205
+ = renderWithRedux(<SystemPurposeEditModal
206
+ type="ak"
207
+ {...baseAttributes}
208
+ {...facetAttributes}
209
+ />, renderOptions(ACTIVATION_KEY));
210
+
211
+ const saveButton = getByRole('button', { name: 'Save' });
212
+ // Save button should be disabled if no values have been changed
213
+ expect(saveButton).toHaveAttribute('aria-disabled', 'true');
214
+
215
+ const roleDropdown = getByLabelText('Role');
216
+ fireEvent.change(roleDropdown, { target: { value: 'Red Hat Enterprise Linux Workstation' } });
217
+
218
+ // Save button should now be enabled
219
+ expect(saveButton).toHaveAttribute('aria-disabled', 'false');
220
+ fireEvent.click(saveButton);
221
+
222
+ await patientlyWaitFor(() => {
223
+ expect(baseAttributes.closeModal).toHaveBeenCalled();
224
+ });
225
+
226
+ [orgScope, availableReleaseVersionsScope, akEditScope].forEach((scope) => {
227
+ assertNockRequest(scope);
228
+ });
229
+ assertNockRequest(akDetailsScope, done);
230
+ });
231
+ test('Retrieves available release versions for host', async (done) => {
232
+ const orgScope = nockInstance
233
+ .get(organizationDetails)
234
+ .reply(200, {
235
+ id: 1,
236
+ });
237
+ const availableReleaseVersionsScope = nockInstance
238
+ .get(availableReleaseVersions)
239
+ .reply(200, { results: ['8', '9'] });
240
+
241
+ const { getByLabelText, getByText }
242
+ = renderWithRedux(<SystemPurposeEditModal
243
+ type="host"
244
+ {...baseAttributes}
245
+ {...facetAttributes}
246
+ />, renderOptions());
247
+
248
+ const releaseVersionDropdown = getByLabelText('Release version');
249
+ fireEvent.click(releaseVersionDropdown);
250
+
251
+ await patientlyWaitFor(() => {
252
+ expect(getByText('8')).toBeInTheDocument();
253
+ expect(getByText('9')).toBeInTheDocument();
254
+ });
255
+
256
+ [orgScope, availableReleaseVersionsScope].forEach((scope) => {
257
+ assertNockRequest(scope);
258
+ });
259
+ done();
260
+ });
261
+ test('Retrieves available release versions for activation key', async (done) => {
262
+ const orgScope = nockInstance
263
+ .get(organizationDetails)
264
+ .reply(200, {
265
+ id: 1,
266
+ });
267
+ const availableReleaseVersionsScope = nockInstance
268
+ .get(akAvailableReleaseVersions)
269
+ .reply(200, { results: ['8', '9'] });
270
+
271
+ const { getByLabelText, getByText }
272
+ = renderWithRedux(<SystemPurposeEditModal
273
+ type="ak"
274
+ {...baseAttributes}
275
+ {...facetAttributes}
276
+ />, renderOptions(ACTIVATION_KEY));
277
+
278
+ const releaseVersionDropdown = getByLabelText('Release version');
279
+ fireEvent.click(releaseVersionDropdown);
280
+
281
+ await patientlyWaitFor(() => {
282
+ expect(getByText('8')).toBeInTheDocument();
283
+ expect(getByText('9')).toBeInTheDocument();
284
+ });
285
+
286
+ [orgScope, availableReleaseVersionsScope].forEach((scope) => {
287
+ assertNockRequest(scope);
288
+ });
289
+ done();
290
+ });
161
291
  });
@@ -1,6 +1,5 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { propsToCamelCase } from 'foremanReact/common/helpers';
4
3
  import { translate as __ } from 'foremanReact/common/I18n';
5
4
  import {
6
5
  DescriptionList,
@@ -14,7 +13,12 @@ import CardTemplate from 'foremanReact/components/HostDetails/Templates/CardItem
14
13
  import { TranslatedPlural } from '../../../Table/components/TranslatedPlural';
15
14
  import { hostIsNotRegistered } from '../hostDetailsHelpers';
16
15
 
17
- const HostDisks = ({ totalDisks }) => {
16
+ const HostDisks = ({ blockDevices }) => {
17
+ if (!blockDevices) return null;
18
+ // blockDevices fact will look like this by default 'sr0,sda' and increment like sdb etc
19
+ const disks = blockDevices.split(',');
20
+ // We are filtering out the CDROM drive that gets added by default a lot of the time
21
+ const totalDisks = disks.filter(e => !e.startsWith('sr')).length;
18
22
  if (!totalDisks) return null;
19
23
  return (
20
24
  <>
@@ -27,11 +31,11 @@ const HostDisks = ({ totalDisks }) => {
27
31
  };
28
32
 
29
33
  HostDisks.propTypes = {
30
- totalDisks: PropTypes.number,
34
+ blockDevices: PropTypes.string,
31
35
  };
32
36
 
33
37
  HostDisks.defaultProps = {
34
- totalDisks: null,
38
+ blockDevices: '',
35
39
  };
36
40
 
37
41
  const HwPropertiesCard = ({ isExpandedGlobal, hostDetails }) => {
@@ -41,8 +45,7 @@ const HwPropertiesCard = ({ isExpandedGlobal, hostDetails }) => {
41
45
  const cpuCount = facts?.['cpu::cpu(s)'];
42
46
  const cpuSockets = facts?.['cpu::cpu_socket(s)'];
43
47
  const coreSocket = facts?.['cpu::core(s)_per_socket'];
44
- const reportedFacts = propsToCamelCase(hostDetails?.reported_data || {});
45
- const totalDisks = reportedFacts?.disksTotal;
48
+ const blockDevices = facts?.blockdevices;
46
49
  const memory = facts?.['dmi::memory::maximum_capacity'];
47
50
 
48
51
  return (
@@ -74,7 +77,7 @@ const HwPropertiesCard = ({ isExpandedGlobal, hostDetails }) => {
74
77
  <DescriptionListDescription>{memory}</DescriptionListDescription>
75
78
  </DescriptionListGroup>
76
79
  <DescriptionListGroup>
77
- <HostDisks totalDisks={totalDisks} />
80
+ <HostDisks blockDevices={blockDevices} />
78
81
  </DescriptionListGroup>
79
82
  </DescriptionList>
80
83
  </CardTemplate>
@@ -90,9 +93,7 @@ HwPropertiesCard.propTypes = {
90
93
  cpuSockets: PropTypes.number,
91
94
  coreSocket: PropTypes.number,
92
95
  memory: PropTypes.string,
93
- }),
94
- reported_data: PropTypes.shape({
95
- totalDisks: PropTypes.number,
96
+ blockdevices: PropTypes.string,
96
97
  }),
97
98
  }),
98
99
  };
@@ -55,9 +55,12 @@ const RegistrationCard = ({ isExpandedGlobal, hostDetails }) => {
55
55
  const subscriptionFacetAttributes
56
56
  = propsToCamelCase(hostDetails?.subscription_facet_attributes || {});
57
57
  const {
58
- registeredAt, registeredThrough, activationKeys, user,
58
+ registeredAt, activationKeys, user,
59
59
  }
60
60
  = subscriptionFacetAttributes;
61
+ const contentFacetAttributes
62
+ = propsToCamelCase(hostDetails?.content_facet_attributes || {});
63
+ const { contentSourceName } = contentFacetAttributes;
61
64
  const login = user?.login;
62
65
  if (!registeredAt) return null;
63
66
  return (
@@ -78,7 +81,7 @@ const RegistrationCard = ({ isExpandedGlobal, hostDetails }) => {
78
81
  </DescriptionListGroup>
79
82
  <DescriptionListGroup>
80
83
  <DescriptionListTerm>{__('Content source')}</DescriptionListTerm>
81
- <DescriptionListDescription>{registeredThrough}</DescriptionListDescription>
84
+ <DescriptionListDescription>{contentSourceName}</DescriptionListDescription>
82
85
  </DescriptionListGroup>
83
86
  </DescriptionList>
84
87
  </CardTemplate>
@@ -99,6 +102,9 @@ RegistrationCard.propTypes = {
99
102
  name: PropTypes.string,
100
103
  })),
101
104
  }),
105
+ content_facet_attributes: PropTypes.shape({
106
+ content_source_name: PropTypes.string,
107
+ }),
102
108
  }),
103
109
  };
104
110
 
@@ -19,15 +19,17 @@ import {
19
19
  } from '@patternfly/react-table';
20
20
  import { isEqual } from 'lodash';
21
21
  import { translate as __ } from 'foremanReact/common/I18n';
22
+ import { HOST_DETAILS_KEY } from 'foremanReact/components/HostDetails/consts';
22
23
  import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
23
24
  import IsoDate from 'foremanReact/components/common/dates/IsoDate';
24
25
  import { urlBuilder } from 'foremanReact/common/urlHelpers';
25
26
  import { propsToCamelCase } from 'foremanReact/common/helpers';
27
+ import { useSet, useBulkSelect, useUrlParams } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
28
+ import { useTableSort } from 'foremanReact/components/PF4/Helpers/useTableSort';
26
29
  import SelectableDropdown from '../../../../SelectableDropdown';
27
- import { useSet, useBulkSelect, useUrlParams, useTableSort } from '../../../../../components/Table/TableHooks';
28
30
  import TableWrapper from '../../../../../components/Table/TableWrapper';
29
31
  import { ErrataType, ErrataSeverity, ErrataToggleGroupItem } from '../../../../../components/Errata';
30
- import { getInstallableErrata, regenerateApplicability } from './HostErrataActions';
32
+ import { getInstallableErrata } from './HostErrataActions';
31
33
  import ErratumExpansionDetail from './ErratumExpansionDetail';
32
34
  import ErratumExpansionContents from './ErratumExpansionContents';
33
35
  import { selectHostErrataStatus } from './HostErrataSelectors';
@@ -42,6 +44,7 @@ import { hasRequiredPermissions as can,
42
44
  import SortableColumnHeaders from '../../../../Table/components/SortableColumnHeaders';
43
45
  import { useRexJobPolling } from '../RemoteExecutionHooks';
44
46
  import { errataStatusContemplation, friendlyErrataStatus } from '../../../../Errata/errataHelpers';
47
+ import { runSubmanRepos } from '../../Cards/ContentViewDetailsCard/HostContentViewActions';
45
48
 
46
49
  const recalculateApplicability = ['edit_hosts'];
47
50
  const invokeRexJobs = ['create_job_invocations'];
@@ -106,6 +109,23 @@ export const ErrataTab = () => {
106
109
  setToggleGroupState(APPLICABLE);
107
110
  };
108
111
 
112
+ const refreshHostDetails = () => dispatch({
113
+ type: 'API_GET',
114
+ payload: {
115
+ key: HOST_DETAILS_KEY,
116
+ url: `/api/hosts/${hostname}`,
117
+ },
118
+ });
119
+
120
+ const {
121
+ triggerJobStart: triggerRecalculate, lastCompletedJob: lastCompletedRecalculate,
122
+ } = useRexJobPolling(() => runSubmanRepos(hostname, refreshHostDetails));
123
+
124
+ const recalculateErrata = () => {
125
+ setIsBulkActionOpen(false);
126
+ triggerRecalculate();
127
+ };
128
+
109
129
  let resetFilters = resetFiltersOnly;
110
130
  let secondaryActionTextOverride;
111
131
  let emptyContentTitle;
@@ -114,6 +134,8 @@ export const ErrataTab = () => {
114
134
  case 'All up to date':
115
135
  emptyContentTitle = __('All up to date');
116
136
  emptyContentBody = __('No action is needed because there are no applicable errata for this host.');
137
+ resetFilters = recalculateErrata;
138
+ secondaryActionTextOverride = __('Refresh errata applicability');
117
139
  break;
118
140
  case 'Needed':
119
141
  emptyContentTitle = __('No matching errata found');
@@ -266,11 +288,6 @@ export const ErrataTab = () => {
266
288
  hostname, search: (selectedCount > 0) ? fetchBulkParams() : '',
267
289
  });
268
290
 
269
- const recalculateErrata = () => {
270
- setIsBulkActionOpen(false);
271
- dispatch(regenerateApplicability(hostId));
272
- };
273
-
274
291
  const showActions = can(invokeRexJobs, userPermissions);
275
292
 
276
293
  const readOnlyBookmarks =
@@ -284,7 +301,7 @@ export const ErrataTab = () => {
284
301
  component="button"
285
302
  onClick={recalculateErrata}
286
303
  >
287
- {__('Recalculate')}
304
+ {__('Refresh errata applicability')}
288
305
  </DropdownItem>,
289
306
  ];
290
307
 
@@ -447,13 +464,13 @@ export const ErrataTab = () => {
447
464
  secondaryActionTextOverride,
448
465
  }
449
466
  }
450
- showSecondaryActionButton={neededErrata}
467
+ showSecondaryActionButton={neededErrata || showRecalculate}
451
468
  happyEmptyContent={allUpToDate}
452
469
  ouiaId="host-errata-table"
453
470
  additionalListeners={[
454
471
  hostId, toggleGroupState, errataTypeSelected,
455
472
  errataSeveritySelected, activeSortColumn, activeSortDirection,
456
- lastCompletedApply, lastCompletedBulkApply]}
473
+ lastCompletedApply, lastCompletedBulkApply, lastCompletedRecalculate]}
457
474
  fetchItems={fetchItems}
458
475
  bookmarkController="katello_errata"
459
476
  readOnlyBookmarks={readOnlyBookmarks}
@@ -1,7 +1,6 @@
1
- import { API_OPERATIONS, get, put } from 'foremanReact/redux/API';
1
+ import { API_OPERATIONS, get } from 'foremanReact/redux/API';
2
2
  import { foremanApi } from '../../../../../services/api';
3
- import { HOST_ERRATA_KEY, HOST_ERRATA_APPLICABILITY_KEY } from './HostErrataConstants';
4
- import { errorToast } from '../../../../../scenes/Tasks/helpers';
3
+ import { HOST_ERRATA_KEY } from './HostErrataConstants';
5
4
 
6
5
  export const getInstallableErrata = (hostId, params) => get({
7
6
  type: API_OPERATIONS.GET,
@@ -10,23 +9,5 @@ export const getInstallableErrata = (hostId, params) => get({
10
9
  params,
11
10
  });
12
11
 
13
- export const regenerateApplicability = (hostId, params) => put({
14
- type: API_OPERATIONS.PUT,
15
- key: HOST_ERRATA_APPLICABILITY_KEY,
16
- url: foremanApi.getApiUrl(`/hosts/${hostId}/errata/applicability`),
17
- // This endpoint doesn't return a task, so can't use renderTaskStartedToast
18
- // also can't use successToast because we want the type to be 'info'
19
- handleSuccess: () => {
20
- window.tfm.toastNotifications.notify({
21
- message: 'Regenerating errata applicability.',
22
- type: 'info',
23
- link: {
24
- children: 'View related tasks',
25
- href: '/foreman_tasks/tasks?search=action+~+applicability&page=1',
26
- },
27
- });
28
- },
29
- errorToast: error => errorToast(error),
30
- params,
31
- });
12
+ export default getInstallableErrata;
32
13