katello 4.10.0 → 4.11.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 (449) 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_facet/show.json.rabl +4 -0
  127. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -1
  128. data/app/views/katello/api/v2/docker_tags/_base.json.rabl +28 -6
  129. data/app/views/katello/hosts/_errata_counts.html.erb +2 -2
  130. data/app/views/katello/task_mailer/cv_promote_failure.html.erb +31 -0
  131. data/app/views/katello/task_mailer/cv_promote_failure.text.erb +13 -0
  132. data/app/views/katello/task_mailer/cv_publish_failure.html.erb +31 -0
  133. data/app/views/katello/task_mailer/cv_publish_failure.text.erb +13 -0
  134. data/app/views/katello/task_mailer/proxy_sync_failure.html.erb +45 -0
  135. data/app/views/katello/task_mailer/proxy_sync_failure.text.erb +25 -0
  136. data/app/views/katello/task_mailer/repo_sync_failure.html.erb +35 -0
  137. data/app/views/katello/task_mailer/repo_sync_failure.text.erb +15 -0
  138. data/app/views/overrides/organizations/_edit_override.html.erb +4 -0
  139. data/config/routes/api/v2.rb +2 -0
  140. data/db/migrate/20230825180856_add_content_counts_to_smart_proxy.rb +7 -0
  141. data/db/migrate/20231020153017_create_indexes_for_nvra_and_epoch.rb +6 -0
  142. data/db/seeds.d/106-mail_notifications.rb +32 -0
  143. data/db/seeds.d/109-katello-notification-blueprints.rb +6 -0
  144. data/engines/bastion/app/assets/javascripts/bastion/components/views/bst-alert.html +1 -1
  145. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/activation-keys.controller.js +4 -0
  146. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-add-host-collections.controller.js +3 -0
  147. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-add-subscriptions.controller.js +3 -0
  148. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-associations.controller.js +4 -0
  149. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-copy.controller.js +7 -2
  150. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-host-collections.controller.js +3 -0
  151. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-repository-sets.controller.js +3 -0
  152. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-subscriptions.controller.js +3 -0
  153. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/new/new-activation-key.controller.js +6 -2
  154. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.controller.js +16 -1
  155. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/common/views/rhel-lifecycle-notice.html +5 -0
  156. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credentials.controller.js +7 -2
  157. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-acs.controller.js +7 -2
  158. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-products.controller.js +7 -2
  159. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-repositories.controller.js +7 -2
  160. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/new/new-content-credential.controller.js +3 -0
  161. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-errata-modal.controller.js +5 -1
  162. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-debs-actions.controller.js +5 -1
  163. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-debs-applicable.controller.js +3 -0
  164. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-debs-installed.controller.js +3 -0
  165. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-errata.controller.js +4 -0
  166. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-module-streams.controller.js +3 -0
  167. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages-applicable.controller.js +3 -0
  168. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages-installed.controller.js +3 -0
  169. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages.controller.js +3 -0
  170. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-traces.controller.js +4 -0
  171. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-debs-actions.html +1 -1
  172. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-debs-applicable.html +1 -1
  173. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-debs-installed.html +1 -1
  174. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-errata.html +3 -3
  175. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-module-streams.html +1 -1
  176. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-actions.html +1 -1
  177. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-applicable.html +1 -1
  178. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-installed.html +1 -1
  179. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-traces.html +3 -3
  180. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +5 -0
  181. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.routes.js +1 -1
  182. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-add-host-collections.controller.js +4 -1
  183. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-add-subscriptions.controller.js +3 -0
  184. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-host-collections.controller.js +4 -1
  185. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-repository-sets.controller.js +3 -0
  186. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-subscriptions.controller.js +3 -0
  187. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-add-subscriptions.html +1 -1
  188. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-details.html +4 -3
  189. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-host-collections.html +1 -1
  190. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-info.html +3 -3
  191. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-provisioning-info.html +2 -2
  192. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-subscriptions-list.html +1 -1
  193. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-subscriptions.html +1 -1
  194. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +3 -3
  195. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/debs.controller.js +7 -0
  196. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/details/deb-content-views.controller.js +8 -1
  197. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/details/deb-repositories.controller.js +10 -2
  198. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/details/docker-tag-environments.controller.js +5 -2
  199. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/details/docker-tag-repositories.controller.js +6 -2
  200. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/docker-tags/docker-tags.controller.js +6 -3
  201. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/environment-content.controller.js +13 -0
  202. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/environment.controller.js +6 -0
  203. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/new-environment.controller.js +8 -2
  204. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/apply-errata.controller.js +4 -0
  205. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/erratum-content-hosts.controller.js +7 -2
  206. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/erratum-repositories.controller.js +7 -2
  207. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/erratum.controller.js +6 -2
  208. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum-info.html +2 -2
  209. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/errata.controller.js +5 -0
  210. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/views/errata.html +1 -1
  211. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/files/details/file-content-views.controller.js +10 -2
  212. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/files/details/file-repositories.controller.js +8 -1
  213. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/files/files.controller.js +9 -2
  214. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/host-collection-add-hosts.controller.js +3 -0
  215. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/host-collection-copy.controller.js +7 -2
  216. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/host-collection-hosts.controller.js +3 -0
  217. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/host-collections.controller.js +4 -0
  218. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/new/new-host-collection.controller.js +6 -2
  219. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host.factory.js +4 -0
  220. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +166 -43
  221. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/fr.po +4 -0
  222. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/translations.js +1 -1
  223. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/packages.controller.js +7 -0
  224. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/product-repositories.controller.js +5 -0
  225. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-advanced-sync.controller.js +6 -2
  226. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-manage-content.controller.js +11 -0
  227. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +3 -0
  228. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/views/product-repositories.html +2 -2
  229. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery-create.controller.js +3 -0
  230. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery.controller.js +3 -0
  231. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/new/product-form.controller.js +6 -2
  232. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.controller.js +4 -0
  233. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/views/content-access-mode-banner.html +1 -1
  234. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/sync-plan-add-products.controller.js +5 -1
  235. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/details/sync-plan-products.controller.js +4 -0
  236. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/new/new-sync-plan.controller.js +3 -0
  237. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/sync-plans/sync-plans.controller.js +4 -0
  238. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/task-details.controller.js +6 -2
  239. data/lib/katello/engine.rb +2 -3
  240. data/lib/katello/permission_creator.rb +2 -2
  241. data/lib/katello/plugin.rb +4 -0
  242. data/lib/katello/repository_types/ostree.rb +1 -0
  243. data/lib/katello/repository_types/python.rb +1 -0
  244. data/lib/katello/scheduled_jobs.rb +1 -1
  245. data/lib/katello/version.rb +1 -1
  246. data/locale/action_names.rb +1 -3
  247. data/locale/bn/LC_MESSAGES/katello.mo +0 -0
  248. data/locale/bn/katello.po +236 -197
  249. data/locale/bn_IN/LC_MESSAGES/katello.mo +0 -0
  250. data/locale/bn_IN/katello.po +236 -197
  251. data/locale/ca/LC_MESSAGES/katello.mo +0 -0
  252. data/locale/ca/katello.po +236 -197
  253. data/locale/cs/LC_MESSAGES/katello.mo +0 -0
  254. data/locale/cs/katello.po +236 -206
  255. data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
  256. data/locale/cs_CZ/katello.po +236 -197
  257. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  258. data/locale/de/katello.po +241 -202
  259. data/locale/de_AT/LC_MESSAGES/katello.mo +0 -0
  260. data/locale/de_AT/katello.po +236 -197
  261. data/locale/de_DE/LC_MESSAGES/katello.mo +0 -0
  262. data/locale/de_DE/katello.po +236 -197
  263. data/locale/el/LC_MESSAGES/katello.mo +0 -0
  264. data/locale/el/katello.po +236 -197
  265. data/locale/en/LC_MESSAGES/katello.mo +0 -0
  266. data/locale/en/katello.po +236 -197
  267. data/locale/en_GB/LC_MESSAGES/katello.mo +0 -0
  268. data/locale/en_GB/katello.po +236 -197
  269. data/locale/en_US/LC_MESSAGES/katello.mo +0 -0
  270. data/locale/en_US/katello.po +236 -197
  271. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  272. data/locale/es/katello.po +238 -199
  273. data/locale/et_EE/LC_MESSAGES/katello.mo +0 -0
  274. data/locale/et_EE/katello.po +236 -197
  275. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  276. data/locale/fr/katello.po +247 -208
  277. data/locale/gl/LC_MESSAGES/katello.mo +0 -0
  278. data/locale/gl/katello.po +236 -197
  279. data/locale/gu/LC_MESSAGES/katello.mo +0 -0
  280. data/locale/gu/katello.po +236 -197
  281. data/locale/he_IL/LC_MESSAGES/katello.mo +0 -0
  282. data/locale/he_IL/katello.po +236 -197
  283. data/locale/hi/LC_MESSAGES/katello.mo +0 -0
  284. data/locale/hi/katello.po +236 -197
  285. data/locale/id/LC_MESSAGES/katello.mo +0 -0
  286. data/locale/id/katello.po +236 -197
  287. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  288. data/locale/it/katello.po +236 -197
  289. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  290. data/locale/ja/katello.po +247 -208
  291. data/locale/ka/LC_MESSAGES/katello.mo +0 -0
  292. data/locale/ka/katello.po +241 -202
  293. data/locale/katello.pot +1427 -1296
  294. data/locale/kn/LC_MESSAGES/katello.mo +0 -0
  295. data/locale/kn/katello.po +236 -197
  296. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  297. data/locale/ko/katello.po +236 -197
  298. data/locale/ml_IN/LC_MESSAGES/katello.mo +0 -0
  299. data/locale/ml_IN/katello.po +236 -197
  300. data/locale/mr/LC_MESSAGES/katello.mo +0 -0
  301. data/locale/mr/katello.po +236 -197
  302. data/locale/nl_NL/LC_MESSAGES/katello.mo +0 -0
  303. data/locale/nl_NL/katello.po +236 -197
  304. data/locale/or/LC_MESSAGES/katello.mo +0 -0
  305. data/locale/or/katello.po +236 -197
  306. data/locale/pa/LC_MESSAGES/katello.mo +0 -0
  307. data/locale/pa/katello.po +236 -197
  308. data/locale/pl/LC_MESSAGES/katello.mo +0 -0
  309. data/locale/pl/katello.po +236 -197
  310. data/locale/pl_PL/LC_MESSAGES/katello.mo +0 -0
  311. data/locale/pl_PL/katello.po +236 -197
  312. data/locale/pt/LC_MESSAGES/katello.mo +0 -0
  313. data/locale/pt/katello.po +236 -197
  314. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  315. data/locale/pt_BR/katello.po +238 -199
  316. data/locale/ro/LC_MESSAGES/katello.mo +0 -0
  317. data/locale/ro/katello.po +236 -197
  318. data/locale/ro_RO/LC_MESSAGES/katello.mo +0 -0
  319. data/locale/ro_RO/katello.po +236 -197
  320. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  321. data/locale/ru/katello.po +236 -197
  322. data/locale/sl/LC_MESSAGES/katello.mo +0 -0
  323. data/locale/sl/katello.po +236 -197
  324. data/locale/sv_SE/LC_MESSAGES/katello.mo +0 -0
  325. data/locale/sv_SE/katello.po +236 -197
  326. data/locale/ta/LC_MESSAGES/katello.mo +0 -0
  327. data/locale/ta/katello.po +236 -197
  328. data/locale/ta_IN/LC_MESSAGES/katello.mo +0 -0
  329. data/locale/ta_IN/katello.po +236 -197
  330. data/locale/te/LC_MESSAGES/katello.mo +0 -0
  331. data/locale/te/katello.po +236 -197
  332. data/locale/tr/LC_MESSAGES/katello.mo +0 -0
  333. data/locale/tr/katello.po +236 -197
  334. data/locale/vi/LC_MESSAGES/katello.mo +0 -0
  335. data/locale/vi/katello.po +236 -197
  336. data/locale/vi_VN/LC_MESSAGES/katello.mo +0 -0
  337. data/locale/vi_VN/katello.po +236 -197
  338. data/locale/zh/LC_MESSAGES/katello.mo +0 -0
  339. data/locale/zh/katello.po +236 -197
  340. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  341. data/locale/zh_CN/katello.po +247 -208
  342. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  343. data/locale/zh_TW/katello.po +236 -197
  344. data/webpack/components/Table/EmptyStateMessage.js +7 -4
  345. data/webpack/components/Table/MainTable.scss +18 -17
  346. data/webpack/components/Table/TableWrapper.js +4 -1
  347. data/webpack/components/extensions/HostDetails/ActionsBar/index.js +45 -4
  348. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.scss +9 -7
  349. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.js +1 -1
  350. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsModal.js +1 -1
  351. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeActions.js +29 -7
  352. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.js +106 -66
  353. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.scss +6 -0
  354. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeConstants.js +2 -0
  355. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeEditModal.js +53 -29
  356. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeSelectors.js +7 -6
  357. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/__tests__/SystemPurposeCard.test.js +24 -5
  358. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/__tests__/SystemPurposeEditModal.test.js +137 -7
  359. data/webpack/components/extensions/HostDetails/DetailsTabCards/HwPropertiesCard.js +11 -10
  360. data/webpack/components/extensions/HostDetails/DetailsTabCards/RegistrationCard.js +8 -2
  361. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +27 -10
  362. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/HostErrataActions.js +3 -22
  363. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/HostErrataConstants.js +0 -1
  364. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +3 -2
  365. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js +2 -2
  366. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +48 -12
  367. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +22 -10
  368. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionHooks.js +1 -1
  369. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +2 -2
  370. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerModal.js +71 -5
  371. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerModal.scss +16 -0
  372. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesEnabler.js +4 -1
  373. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesTab.js +6 -2
  374. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +2 -1
  375. data/webpack/components/extensions/HostDetails/Tabs/__tests__/tracesTab.test.js +25 -0
  376. data/webpack/components/extensions/Hosts/ActionsBar/index.js +36 -0
  377. data/webpack/components/extensions/Hosts/constants.js +2 -0
  378. data/webpack/components/extensions/RegistrationCommands/RegistrationCommandsPageHelpers.js +13 -7
  379. data/webpack/components/extensions/RegistrationCommands/__tests__/__snapshots__/ActivationKeys.test.js.snap +9 -1
  380. data/webpack/components/extensions/RegistrationCommands/fields/ActivationKeys.js +87 -22
  381. data/webpack/components/extensions/RegistrationCommands/index.js +17 -41
  382. data/webpack/global_index.js +11 -2
  383. data/webpack/redux/reducers/RedHatRepositories/enabled.fixtures.js +4 -0
  384. data/webpack/redux/reducers/RedHatRepositories/enabled.js +1 -0
  385. data/webpack/scenes/ActivationKeys/Details/ActivationKeyDetails.js +10 -1
  386. data/webpack/scenes/ActivationKeys/Details/ActivationKeyDetails.scss +33 -31
  387. data/webpack/scenes/AlternateContentSources/MainTable/ACSTable.js +3 -1
  388. data/webpack/scenes/Content/ContentConfig.js +3 -0
  389. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +6 -4
  390. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.scss +8 -6
  391. data/webpack/scenes/ContentViews/Delete/ContentViewDeleteWizard.js +1 -0
  392. data/webpack/scenes/ContentViews/Delete/Steps/CVEnvironmentSelectionForm.scss +4 -2
  393. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +3 -4
  394. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +2 -2
  395. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +5 -5
  396. data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/compositeCVDetails.fixtures.json +393 -0
  397. data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/contentViewComponents.test.js +30 -4
  398. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +3 -1
  399. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +3 -3
  400. data/webpack/scenes/ContentViews/Details/Repositories/RepoIcon.js +2 -1
  401. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareTable.js +1 -1
  402. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +1 -1
  403. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveCVVersionWizard.js +1 -1
  404. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsTable.js +1 -1
  405. data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +24 -1
  406. data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +1 -0
  407. data/webpack/scenes/ContentViews/Publish/__tests__/publishContentView.test.js +42 -0
  408. data/webpack/scenes/ContentViews/Publish/cvPublishForm.scss +13 -11
  409. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +2 -1
  410. data/webpack/scenes/ContentViews/__tests__/mockDetails.fixtures.json +2 -1
  411. data/webpack/scenes/Hosts/ChangeContentSource/index.js +4 -3
  412. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetails.js +1 -2
  413. data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetails.test.js.snap +1 -1
  414. data/webpack/scenes/RedHatRepositories/RedHatRepositoriesPage.js +2 -1
  415. data/webpack/scenes/RedHatRepositories/__tests__/__snapshots__/RedHatRepositoriesPage.test.js.snap +6 -0
  416. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepository.js +4 -1
  417. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepositoryContent.js +13 -4
  418. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/EnabledRepositoryContent.test.js +1 -0
  419. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/__snapshots__/EnabledRepository.test.js.snap +1 -0
  420. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/__snapshots__/EnabledRepositoryContent.test.js.snap +3 -2
  421. data/webpack/scenes/SmartProxy/AdditionalCapsuleContent.js +93 -0
  422. data/webpack/scenes/SmartProxy/Content.js +12 -4
  423. data/webpack/scenes/SmartProxy/ExpandableCvDetails.js +107 -0
  424. data/webpack/scenes/SmartProxy/ExpandedSmartProxyRepositories.js +139 -0
  425. data/webpack/scenes/SmartProxy/SmartProxyContentActions.js +17 -4
  426. data/webpack/scenes/SmartProxy/SmartProxyContentConstants.js +1 -0
  427. data/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js +150 -0
  428. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.fixtures.json +799 -0
  429. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js +29 -17
  430. data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.js +16 -19
  431. data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.scss +12 -8
  432. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +21 -18
  433. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnConfigurationForm.scss +4 -2
  434. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.scss +38 -19
  435. data/webpack/scenes/Subscriptions/Manifest/index.js +0 -2
  436. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +38 -12
  437. data/webpack/scenes/Subscriptions/SubscriptionsPage.scss +38 -36
  438. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +16 -13
  439. data/webpack/utils/helpers.js +0 -1
  440. metadata +99 -33
  441. data/app/controllers/katello/concerns/api/v2/bulk_hosts_extensions.rb +0 -47
  442. data/webpack/components/Table/TableHooks.js +0 -315
  443. data/webpack/components/Table/__test__/useBulkSelect.test.js +0 -99
  444. data/webpack/components/extensions/RegistrationCommands/__tests__/LifeCycleEnvironment.test.js +0 -11
  445. data/webpack/components/extensions/RegistrationCommands/__tests__/__snapshots__/LifeCycleEnvironment.test.js.snap +0 -29
  446. data/webpack/components/extensions/RegistrationCommands/fields/LifecycleEnvironment.js +0 -57
  447. data/webpack/scenes/SmartProxy/SmartProxyContentTable.js +0 -164
  448. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentResult.fixtures.json +0 -140
  449. data/webpack/scenes/Subscriptions/Manifest/Manifest.scss +0 -16
@@ -17,7 +17,10 @@ const CVPublishForm = ({
17
17
  description,
18
18
  setDescription,
19
19
  details: {
20
- name, composite, next_version: nextVersion, needs_publish: needsPublish,
20
+ name, composite,
21
+ next_version: nextVersion,
22
+ needs_publish: needsPublish,
23
+ duplicate_repositories_to_publish: duplicateRepos,
21
24
  },
22
25
  userCheckedItems,
23
26
  setUserCheckedItems,
@@ -27,6 +30,7 @@ const CVPublishForm = ({
27
30
  }) => {
28
31
  const [alertDismissed, setAlertDismissed] = useState(false);
29
32
  const [needsPublishAlertDismissed, setNeedsPublishAlertDismissed] = useState(false);
33
+ const [duplicateReposAlertDismissed, setDuplicateReposAlertDismissed] = useState(false);
30
34
  const needsPublishLocal = useSelector(state => selectCVNeedsPublish(state));
31
35
 
32
36
  const checkPromote = (checked) => {
@@ -61,6 +65,24 @@ const CVPublishForm = ({
61
65
  <TextContent>{__('Newly published version will be the same as the previous version.')}</TextContent>
62
66
  </Alert>)
63
67
  }
68
+ {!duplicateReposAlertDismissed && composite &&
69
+ (duplicateRepos !== null || duplicateRepos.length > 0) &&
70
+ (
71
+ <Alert
72
+ ouiaId="duplicate-repos-alert"
73
+ variant="info"
74
+ isInline
75
+ title={__('Duplicate repositories in content view versions')}
76
+ actionClose={
77
+ <AlertActionCloseButton
78
+ onClose={() => setDuplicateReposAlertDismissed(true)}
79
+ />
80
+ }
81
+ style={{ marginBottom: '24px' }}
82
+ >
83
+ <TextContent>{__('Repositories common to the selected content view versions will merge, resulting in a composite content view that is a union of all content from each of the content view versions.')}</TextContent>
84
+ </Alert>)
85
+ }
64
86
  {__('A new version of ')}<b>{composite ? <RegistryIcon /> : <EnterpriseIcon />} {name}</b>
65
87
  {__(' will be created and automatically promoted to the ' +
66
88
  'Library environment. You can promote to other environments as well. ')
@@ -142,6 +164,7 @@ CVPublishForm.propTypes = {
142
164
  PropTypes.string,
143
165
  ]).isRequired,
144
166
  needs_publish: PropTypes.bool,
167
+ duplicate_repositories_to_publish: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
145
168
  }).isRequired,
146
169
  };
147
170
 
@@ -122,6 +122,7 @@ const PublishContentViewWizard = ({
122
122
  } else onClose();
123
123
  }}
124
124
  isOpen={show}
125
+ id="content-view-publish-wizard"
125
126
  />
126
127
  );
127
128
  };
@@ -38,6 +38,48 @@ test('Can call API and show Wizard', async (done) => {
38
38
  assertNockRequest(filterScope, done);
39
39
  });
40
40
 
41
+ test('Can show wizard with duplicate repository warning for composite CV', async (done) => {
42
+ const cvCompositeDetailsData = cvDetailData;
43
+ cvCompositeDetailsData.composite = true;
44
+ cvCompositeDetailsData.duplicate_repositories_to_publish = [
45
+ {
46
+ id: 1,
47
+ name: 'repo1',
48
+ components: [
49
+ {
50
+ content_view_name: 'test',
51
+ content_view_version: '2.0',
52
+ },
53
+ {
54
+ content_view_name: 'dev',
55
+ content_view_version: '3.0',
56
+ },
57
+ ],
58
+ },
59
+ ];
60
+ const scope = nockInstance
61
+ .get(environmentPathsPath)
62
+ .query(true)
63
+ .reply(200, environmentPathsData);
64
+ const filterScope = nockInstance
65
+ .get(cvFiltersPath)
66
+ .reply(200, contentViewFilterData);
67
+
68
+ const { getByText } = renderWithRedux(<PublishContentViewWizard
69
+ details={cvCompositeDetailsData}
70
+ show
71
+ onClose={() => { }}
72
+ />);
73
+
74
+ await patientlyWaitFor(() => {
75
+ expect(getByText('Publish new version - 6.0')).toBeInTheDocument();
76
+ expect(getByText('Repositories common to the selected content view versions will merge, resulting in a composite content view that is a union of all content from each of the content view versions.')).toBeTruthy();
77
+ });
78
+
79
+ assertNockRequest(scope);
80
+ assertNockRequest(filterScope, done);
81
+ });
82
+
41
83
  test('Can show Wizard and show environment paths', async (done) => {
42
84
  const scope = nockInstance
43
85
  .get(environmentPathsPath)
@@ -1,13 +1,15 @@
1
- .pf-c-switch {
2
- --pf-c-switch__input--focus__toggle--OutlineWidth: 0;
3
- }
1
+ #content-view-publish-wizard {
2
+ .pf-c-switch {
3
+ --pf-c-switch__input--focus__toggle--OutlineWidth: 0;
4
+ }
4
5
 
5
- .pf-c-wizard__main-body {
6
- display: flex;
7
- grid-gap: 16px;
8
- flex-direction: column;
9
- }
6
+ .pf-c-wizard__main-body {
7
+ display: flex;
8
+ grid-gap: 16px;
9
+ flex-direction: column;
10
+ }
10
11
 
11
- .pf-c-content h4 {
12
- margin-top: 0px;
13
- }
12
+ .pf-c-content h4 {
13
+ margin-top: 0px;
14
+ }
15
+ }
@@ -4,6 +4,8 @@ import { Link } from 'react-router-dom';
4
4
  import { omit } from 'lodash';
5
5
  import { translate as __ } from 'foremanReact/common/I18n';
6
6
  import LongDateTime from 'foremanReact/components/common/dates/LongDateTime';
7
+ import { useSet } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
8
+ import { useTableSort } from 'foremanReact/components/PF4/Helpers/useTableSort';
7
9
  import { Button } from '@patternfly/react-core';
8
10
  import { TableVariant, Thead, Tbody, Th, Tr, Td, ExpandableRowContent } from '@patternfly/react-table';
9
11
  import TableWrapper from '../../../components/Table/TableWrapper';
@@ -15,7 +17,6 @@ import { selectContentViews, selectContentViewStatus, selectContentViewError } f
15
17
  import ContentViewVersionPromote from '../Details/Promote/ContentViewVersionPromote';
16
18
  import getEnvironmentPaths from '../components/EnvironmentPaths/EnvironmentPathActions';
17
19
  import { hasPermission } from '../helpers';
18
- import { useSet, useTableSort } from '../../../components/Table/TableHooks';
19
20
  import ContentViewIcon from '../components/ContentViewIcon';
20
21
  import { urlBuilder } from '../../../__mocks__/foremanReact/common/urlHelpers';
21
22
  import LastSync from '../Details/Repositories/LastSync';
@@ -12,5 +12,6 @@
12
12
  "next_version": "1.0",
13
13
  "id": "5",
14
14
  "version_count": 0,
15
- "filtered": true
15
+ "filtered": true,
16
+ "duplicate_repositories_to_publish": []
16
17
  }
@@ -8,6 +8,8 @@ import { foremanUrl } from 'foremanReact/common/helpers';
8
8
  import { STATUS } from 'foremanReact/constants';
9
9
  import BreadcrumbBar from 'foremanReact/components/BreadcrumbBar';
10
10
  import Head from 'foremanReact/components/Head';
11
+ import { useForemanHostsPageUrl } from 'foremanReact/Root/Context/ForemanContext';
12
+ import { useUrlParams } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
11
13
 
12
14
  import { selectApiDataStatus,
13
15
  selectApiContentViewStatus,
@@ -20,7 +22,6 @@ import { selectApiDataStatus,
20
22
  selectTemplate } from './selectors';
21
23
 
22
24
  import { getHostIds, formIsLoading } from './helpers';
23
- import { useUrlParams } from '../../../components/Table/TableHooks';
24
25
  import {
25
26
  getFormData,
26
27
  getProxy,
@@ -96,14 +97,14 @@ const ChangeContentSourcePage = () => {
96
97
  setShouldShowTemplate(true);
97
98
  };
98
99
 
100
+ const hostIndexUrl = useForemanHostsPageUrl();
99
101
  const breadcrumbItems = () => {
100
- const linkHosts = { caption: __('Hosts'), url: foremanUrl('/hosts') };
102
+ const linkHosts = { caption: __('Hosts'), url: hostIndexUrl };
101
103
  const linkContent = { caption: __('Change host content source') };
102
104
 
103
105
  if (urlParams.host_id) {
104
106
  const hostName = contentHosts.concat(hostsWithoutContent)
105
107
  .find(h => `${h.id}` === urlParams.host_id)?.name;
106
-
107
108
  return ([linkHosts, { caption: hostName, url: foremanUrl(`/new/hosts/${hostName}`) }, linkContent]);
108
109
  }
109
110
  return ([linkHosts, linkContent]);
@@ -50,8 +50,7 @@ class ModuleStreamDetails extends Component {
50
50
  breadcrumbItems={[
51
51
  {
52
52
  caption: __('Module Streams'),
53
- onClick: () =>
54
- this.props.history.push('/module_streams'),
53
+ url: '/module_streams/',
55
54
  },
56
55
  {
57
56
  caption: `${name} ${stream}`,
@@ -109,7 +109,7 @@ exports[`Module stream details page rendering renders with module stream provide
109
109
  Array [
110
110
  Object {
111
111
  "caption": "Module Streams",
112
- "onClick": [Function],
112
+ "url": "/module_streams/",
113
113
  },
114
114
  Object {
115
115
  "caption": "avocado latest",
@@ -7,7 +7,7 @@ import PropTypes from 'prop-types';
7
7
  import { isEmpty } from 'lodash';
8
8
  import { Grid, Row, Col } from 'react-bootstrap';
9
9
  import { Skeleton, Alert } from '@patternfly/react-core';
10
- import { Button } from 'patternfly-react';
10
+ import { Button, FieldLevelHelp } from 'patternfly-react';
11
11
  import { translate as __ } from 'foremanReact/common/I18n';
12
12
  import PermissionDenied from 'foremanReact/components/PermissionDenied';
13
13
  import { LoadingState } from '../../components/LoadingState';
@@ -96,6 +96,7 @@ class RedHatRepositoriesPage extends Component {
96
96
  <Col sm={6} className="enabled-repositories-container">
97
97
  <h2>
98
98
  {__('Enabled Repositories')}
99
+ <FieldLevelHelp content={__('Only repositories not published in a content view can be disabled. Published repositories must be deleted from the repository details page.')} />
99
100
  <Button
100
101
  ouiaId="export-csv-button"
101
102
  className="pull-right"
@@ -81,6 +81,12 @@ exports[`RedHatRepositories page should render 1`] = `
81
81
  >
82
82
  <h2>
83
83
  Enabled Repositories
84
+ <FieldLevelHelp
85
+ buttonClass=""
86
+ content="Only repositories not published in a content view can be disabled. Published repositories must be deleted from the repository details page."
87
+ placement="top"
88
+ rootClose={true}
89
+ />
84
90
  <Button
85
91
  active={false}
86
92
  block={false}
@@ -62,7 +62,7 @@ class EnabledRepository extends Component {
62
62
 
63
63
  render() {
64
64
  const {
65
- name, id, type, orphaned, label,
65
+ name, id, type, orphaned, label, canDisable,
66
66
  } = this.props;
67
67
 
68
68
  return (
@@ -73,6 +73,7 @@ class EnabledRepository extends Component {
73
73
  loading={this.props.loading}
74
74
  disableTooltipId={this.disableTooltipId}
75
75
  disableRepository={this.disableRepository}
76
+ canDisable={canDisable}
76
77
  />
77
78
  }
78
79
  leftContent={<RepositoryTypeIcon id={id} type={type} />}
@@ -106,6 +107,7 @@ EnabledRepository.propTypes = {
106
107
  loading: PropTypes.bool,
107
108
  releasever: PropTypes.string,
108
109
  orphaned: PropTypes.bool,
110
+ canDisable: PropTypes.bool,
109
111
  setRepositoryDisabled: PropTypes.func.isRequired,
110
112
  loadEnabledRepos: PropTypes.func.isRequired,
111
113
  disableRepository: PropTypes.func.isRequired,
@@ -116,6 +118,7 @@ EnabledRepository.defaultProps = {
116
118
  orphaned: false,
117
119
  search: {},
118
120
  loading: false,
121
+ canDisable: true,
119
122
  };
120
123
 
121
124
  export default EnabledRepository;
@@ -4,21 +4,29 @@ import cx from 'classnames';
4
4
  import { Spinner, OverlayTrigger, Tooltip } from 'patternfly-react';
5
5
  import { translate as __ } from 'foremanReact/common/I18n';
6
6
 
7
- const EnabledRepositoryContent = ({ loading, disableTooltipId, disableRepository }) => (
7
+ const EnabledRepositoryContent = ({
8
+ loading, disableTooltipId, disableRepository, canDisable,
9
+ }) => (
8
10
  <Spinner loading={loading} inline>
9
11
  <OverlayTrigger
10
- overlay={<Tooltip id={disableTooltipId}>{__('Disable')}</Tooltip>}
12
+ overlay={<Tooltip id={disableTooltipId}>{canDisable ? __('Disable') : __('Cannot be disabled because it is part of a published content view')}</Tooltip>}
11
13
  placement="bottom"
12
14
  trigger={['hover', 'focus']}
13
15
  rootClose={false}
14
16
  >
15
17
  <button
16
18
  onClick={disableRepository}
17
- style={{
19
+ style={canDisable ? {
18
20
  backgroundColor: 'initial',
19
21
  border: 'none',
20
22
  color: '#0388ce',
21
- }}
23
+ } : {
24
+ backgroundColor: 'initial',
25
+ border: 'none',
26
+ color: '#d2d2d2',
27
+ }
28
+ }
29
+ disabled={!canDisable}
22
30
  >
23
31
  <i className={cx('fa-2x', 'fa fa-minus-circle')} />
24
32
  </button>
@@ -30,6 +38,7 @@ EnabledRepositoryContent.propTypes = {
30
38
  loading: PropTypes.bool.isRequired,
31
39
  disableTooltipId: PropTypes.string.isRequired,
32
40
  disableRepository: PropTypes.func.isRequired,
41
+ canDisable: PropTypes.bool.isRequired,
33
42
  };
34
43
 
35
44
  export default EnabledRepositoryContent;
@@ -12,6 +12,7 @@ describe('Enabled Repositories Content Component', () => {
12
12
  loading
13
13
  disableTooltipId="disable-1"
14
14
  disableRepository={mockCallBack}
15
+ canDisable={false}
15
16
  />);
16
17
  });
17
18
 
@@ -4,6 +4,7 @@ exports[`Enabled Repositories Component should render 1`] = `
4
4
  <ListViewItem
5
5
  actions={
6
6
  <EnabledRepositoryContent
7
+ canDisable={true}
7
8
  disableRepository={[Function]}
8
9
  disableTooltipId="disable-1"
9
10
  loading={false}
@@ -16,7 +16,7 @@ exports[`Enabled Repositories Content Component should render 1`] = `
16
16
  id="disable-1"
17
17
  placement="right"
18
18
  >
19
- Disable
19
+ Cannot be disabled because it is part of a published content view
20
20
  </Tooltip>
21
21
  }
22
22
  placement="bottom"
@@ -29,12 +29,13 @@ exports[`Enabled Repositories Content Component should render 1`] = `
29
29
  }
30
30
  >
31
31
  <button
32
+ disabled={true}
32
33
  onClick={[MockFunction]}
33
34
  style={
34
35
  Object {
35
36
  "backgroundColor": "initial",
36
37
  "border": "none",
37
- "color": "#0388ce",
38
+ "color": "#d2d2d2",
38
39
  }
39
40
  }
40
41
  >
@@ -0,0 +1,93 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import ContentConfig from '../Content/ContentConfig';
4
+
5
+ const AdditionalCapsuleContent = ({ counts }) => {
6
+ const {
7
+ deb: debPackageCount = 0,
8
+ docker_manifest: dockerManifestCount = 0,
9
+ docker_tag: dockerTagCount = 0,
10
+ file: fileCount = 0,
11
+ erratum: errataCount = 0,
12
+ package_group: packageGroup = 0,
13
+ 'rpm.modulemd': moduleStreamCount = 0,
14
+ } = counts;
15
+
16
+ const contentConfigTypes = ContentConfig.filter(({ names: { capsuleCountLabel } }) =>
17
+ !!counts[`${capsuleCountLabel}`])
18
+ .map(({
19
+ names: {
20
+ capsuleCountLabel, pluralLowercase,
21
+ },
22
+ }) => {
23
+ const countParam = `${capsuleCountLabel}`;
24
+ const count = counts[countParam];
25
+ return {
26
+ pluralLowercase,
27
+ count,
28
+ };
29
+ });
30
+
31
+ return (
32
+ <>
33
+ {errataCount > 0 &&
34
+ <>
35
+ {`${errataCount} Errata`}<br />
36
+ </>
37
+ }
38
+ {moduleStreamCount > 0 &&
39
+ <>
40
+ {`${moduleStreamCount} Module streams`}<br />
41
+ </>
42
+ }
43
+ {packageGroup > 0 &&
44
+ <>
45
+ {`${packageGroup} Package groups`}<br />
46
+ </>
47
+ }
48
+ {dockerTagCount > 0 &&
49
+ <>
50
+ {`${dockerTagCount} Container tags`}<br />
51
+ </>
52
+ }
53
+ {dockerManifestCount > 0 &&
54
+ <>
55
+ {`${dockerManifestCount} Container manifests`}<br />
56
+ </>
57
+ }
58
+ {fileCount > 0 &&
59
+ <>
60
+ {`${fileCount} Files`}<br />
61
+ </>
62
+ }
63
+ {debPackageCount > 0 &&
64
+ <>
65
+ {`${debPackageCount} Debian packages`}<br />
66
+ </>}
67
+ {contentConfigTypes?.length > 0 &&
68
+ contentConfigTypes.map(({ count, pluralLowercase }) => (
69
+ <React.Fragment key={pluralLowercase}>
70
+ {`${count} ${pluralLowercase}`}<br />
71
+ </React.Fragment>))
72
+ }
73
+ </>
74
+ );
75
+ };
76
+
77
+ AdditionalCapsuleContent.propTypes = {
78
+ counts: PropTypes.shape({
79
+ deb: PropTypes.number,
80
+ docker_manifest: PropTypes.number,
81
+ docker_tag: PropTypes.number,
82
+ file: PropTypes.number,
83
+ erratum: PropTypes.number,
84
+ package_group: PropTypes.number,
85
+ 'rpm.modulemd': PropTypes.number,
86
+ }),
87
+ };
88
+
89
+ AdditionalCapsuleContent.defaultProps = {
90
+ counts: {},
91
+ };
92
+
93
+ export default AdditionalCapsuleContent;
@@ -1,17 +1,25 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import SmartProxyContentTable from './SmartProxyContentTable';
3
+ import SmartProxyExpandableTable from './SmartProxyExpandableTable';
4
4
 
5
- const Content = ({ smartProxyId }) => (
6
- <SmartProxyContentTable smartProxyId={smartProxyId} />
5
+ const Content = ({ smartProxyId, organizationId }) => (
6
+ <SmartProxyExpandableTable smartProxyId={smartProxyId} organizationId={organizationId} />
7
7
  );
8
8
 
9
9
  Content.propTypes = {
10
- smartProxyId: PropTypes.number,
10
+ smartProxyId: PropTypes.oneOfType([
11
+ PropTypes.number,
12
+ PropTypes.string, // The API can sometimes return strings
13
+ ]),
14
+ organizationId: PropTypes.oneOfType([
15
+ PropTypes.number,
16
+ PropTypes.string, // The API can sometimes return strings
17
+ ]),
11
18
  };
12
19
 
13
20
  Content.defaultProps = {
14
21
  smartProxyId: null,
22
+ organizationId: null,
15
23
  };
16
24
 
17
25
  export default Content;
@@ -0,0 +1,107 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { translate as __ } from 'foremanReact/common/I18n';
4
+ import { TableComposable, Thead, Tr, Th, Tbody, Td } from '@patternfly/react-table';
5
+ import { CheckCircleIcon, TimesCircleIcon } from '@patternfly/react-icons';
6
+ import LongDateTime from 'foremanReact/components/common/dates/LongDateTime';
7
+ import { urlBuilder } from 'foremanReact/common/urlHelpers';
8
+ import { useSet } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
9
+ import ContentViewIcon from '../ContentViews/components/ContentViewIcon';
10
+ import ExpandedSmartProxyRepositories from './ExpandedSmartProxyRepositories';
11
+
12
+ const ExpandableCvDetails = ({ contentViews, contentCounts, envId }) => {
13
+ const columnHeaders = [
14
+ __('Content view'),
15
+ __('Version'),
16
+ __('Last published'),
17
+ __('Synced'),
18
+ ];
19
+ // const { content_counts: contentCounts } = counts;
20
+ const expandedTableRows = useSet([]);
21
+ const tableRowIsExpanded = id => expandedTableRows.has(id);
22
+
23
+ return (
24
+ <TableComposable
25
+ aria-label="expandable-content-views"
26
+ ouiaId="expandable-content-views"
27
+ >
28
+ <Thead>
29
+ <Tr ouiaId="column-headers">
30
+ <Th />
31
+ {columnHeaders.map(col => (
32
+ <Th
33
+ key={col}
34
+ >
35
+ {col}
36
+ </Th>
37
+ ))}
38
+ </Tr>
39
+ </Thead>
40
+ {contentViews.map((cv, rowIndex) => {
41
+ const {
42
+ id, name: cvName, composite, up_to_date: upToDate,
43
+ cvv_id: versionId, cvv_version: version, repositories,
44
+ } = cv;
45
+ const upToDateVal = upToDate ? <CheckCircleIcon style={{ color: 'green' }} /> : <TimesCircleIcon style={{ color: 'red' }} />;
46
+ const isExpanded = tableRowIsExpanded(versionId);
47
+ return (
48
+ <Tbody key={`${id} + ${versionId}`}isExpanded={isExpanded}>
49
+ <Tr key={versionId} ouiaId={cv.name}>
50
+ <Td
51
+ aria-label={`expand-cv-${id}`}
52
+ style={{ paddingTop: 0 }}
53
+ expand={{
54
+ rowIndex,
55
+ isExpanded,
56
+ onToggle: (_event, _rInx, isOpen) =>
57
+ expandedTableRows.onToggle(isOpen, versionId),
58
+ }}
59
+ />
60
+ <Td>
61
+ <ContentViewIcon
62
+ composite={composite}
63
+ description={<a href={cv.default ? urlBuilder('products', '') : urlBuilder('content_views', '', id)}>{cvName}</a>}
64
+ />
65
+ </Td>
66
+ <Td>
67
+ <a href={`/content_views/${id}#/versions/${versionId}/`}>{__('Version ')}{version}</a>
68
+ </Td>
69
+ <Td><LongDateTime date={cv.last_published} showRelativeTimeTooltip /></Td>
70
+ <Td>{upToDateVal}</Td>
71
+ </Tr>
72
+ <Tr key="child_row" ouiaId={`ContentViewTableRowChild-${id}`} isExpanded={isExpanded}>
73
+ <Td colSpan={12}>
74
+ <ExpandedSmartProxyRepositories
75
+ contentCounts={contentCounts?.content_view_versions[versionId]?.repositories}
76
+ repositories={repositories}
77
+ syncedToCapsule={upToDate}
78
+ envId={envId}
79
+ />
80
+ </Td>
81
+ </Tr>
82
+ </Tbody>
83
+ );
84
+ })}
85
+
86
+ </TableComposable>
87
+
88
+ );
89
+ };
90
+
91
+ ExpandableCvDetails.propTypes = {
92
+ contentViews: PropTypes.arrayOf(PropTypes.shape({})),
93
+ contentCounts: PropTypes.shape({
94
+ content_view_versions: PropTypes.shape({}),
95
+ }),
96
+ envId: PropTypes.oneOfType([
97
+ PropTypes.number,
98
+ PropTypes.string, // The API can sometimes return strings
99
+ ]).isRequired,
100
+ };
101
+
102
+ ExpandableCvDetails.defaultProps = {
103
+ contentViews: [],
104
+ contentCounts: {},
105
+ };
106
+
107
+ export default ExpandableCvDetails;