katello 4.10.0.rc2 → 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 (418) 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/remove_content.rb +9 -1
  76. data/app/lib/actions/katello/repository/sync.rb +11 -0
  77. data/app/lib/actions/pulp3/capsule_content/reclaim_space.rb +5 -0
  78. data/app/lib/actions/pulp3/content_view_version/create_export_history.rb +6 -1
  79. data/app/lib/actions/pulp3/content_view_version/export.rb +8 -0
  80. data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +1 -1
  81. data/app/lib/katello/concerns/base_template_scope_extensions.rb +14 -1
  82. data/app/lib/katello/errors.rb +1 -0
  83. data/app/lib/katello/repo_discovery.rb +78 -5
  84. data/app/lib/katello/validators/content_view_environment_coherent_default_validator.rb +22 -0
  85. data/app/lib/katello/validators/content_view_environment_validator.rb +1 -0
  86. data/app/mailers/katello/task_mailer.rb +54 -0
  87. data/app/models/katello/concerns/host_managed_extensions.rb +41 -1
  88. data/app/models/katello/concerns/organization_extensions.rb +1 -1
  89. data/app/models/katello/concerns/smart_proxy_extensions.rb +75 -3
  90. data/app/models/katello/concerns/subscription_facet_host_extensions.rb +6 -0
  91. data/app/models/katello/content_view.rb +21 -0
  92. data/app/models/katello/content_view_environment.rb +6 -1
  93. data/app/models/katello/docker_meta_tag.rb +1 -1
  94. data/app/models/katello/docker_tag.rb +1 -1
  95. data/app/models/katello/erratum.rb +1 -1
  96. data/app/models/katello/host/content_facet.rb +10 -7
  97. data/app/models/katello/product.rb +8 -0
  98. data/app/models/katello/repository.rb +31 -6
  99. data/app/models/katello/rhel_lifecycle_status.rb +214 -0
  100. data/app/models/katello/sync_plan.rb +19 -1
  101. data/app/models/katello/yum_metadata_file.rb +1 -1
  102. data/app/services/katello/applicability/applicable_content_helper.rb +1 -1
  103. data/app/services/katello/event_queue.rb +10 -2
  104. data/app/services/katello/host_status_manager.rb +1 -0
  105. data/app/services/katello/product_content_importer.rb +45 -3
  106. data/app/services/katello/pulp3/ansible_collection.rb +1 -0
  107. data/app/services/katello/pulp3/api/core.rb +1 -1
  108. data/app/services/katello/pulp3/deb.rb +1 -0
  109. data/app/services/katello/pulp3/docker_manifest.rb +1 -0
  110. data/app/services/katello/pulp3/docker_manifest_list.rb +9 -4
  111. data/app/services/katello/pulp3/docker_tag.rb +1 -0
  112. data/app/services/katello/pulp3/erratum.rb +1 -0
  113. data/app/services/katello/pulp3/file_unit.rb +1 -0
  114. data/app/services/katello/pulp3/module_stream.rb +1 -0
  115. data/app/services/katello/pulp3/package_group.rb +1 -0
  116. data/app/services/katello/pulp3/pulp_content_unit.rb +39 -0
  117. data/app/services/katello/pulp3/repository_mirror.rb +21 -2
  118. data/app/services/katello/pulp3/rpm.rb +1 -0
  119. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +1 -1
  120. data/app/services/katello/pulp3/srpm.rb +3 -2
  121. data/app/services/katello/registration_manager.rb +6 -3
  122. data/app/services/katello/repository_type.rb +2 -1
  123. data/app/services/katello/ui_notifications/hosts/lifecycle_expire_soon.rb +58 -0
  124. data/app/views/foreman/job_templates/resolve_traces.erb +1 -1
  125. data/app/views/foreman/smart_proxies/_content_tab.html.erb +1 -3
  126. data/app/views/katello/api/v2/capsule_content/sync_status.json.rabl +39 -1
  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/katello.po +236 -197
  249. data/locale/bn_IN/katello.po +236 -197
  250. data/locale/ca/LC_MESSAGES/katello.mo +0 -0
  251. data/locale/ca/katello.po +236 -197
  252. data/locale/cs/katello.po +236 -206
  253. data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
  254. data/locale/cs_CZ/katello.po +236 -197
  255. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  256. data/locale/de/katello.po +241 -202
  257. data/locale/de_AT/katello.po +236 -197
  258. data/locale/de_DE/katello.po +236 -197
  259. data/locale/el/katello.po +236 -197
  260. data/locale/en/katello.po +236 -197
  261. data/locale/en_GB/katello.po +236 -197
  262. data/locale/en_US/katello.po +236 -197
  263. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  264. data/locale/es/katello.po +238 -199
  265. data/locale/et_EE/katello.po +236 -197
  266. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  267. data/locale/fr/katello.po +247 -208
  268. data/locale/gl/katello.po +236 -197
  269. data/locale/gu/katello.po +236 -197
  270. data/locale/he_IL/katello.po +236 -197
  271. data/locale/hi/katello.po +236 -197
  272. data/locale/id/katello.po +236 -197
  273. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  274. data/locale/it/katello.po +236 -197
  275. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  276. data/locale/ja/katello.po +247 -208
  277. data/locale/ka/LC_MESSAGES/katello.mo +0 -0
  278. data/locale/ka/katello.po +241 -202
  279. data/locale/katello.pot +1427 -1296
  280. data/locale/kn/katello.po +236 -197
  281. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  282. data/locale/ko/katello.po +236 -197
  283. data/locale/ml_IN/katello.po +236 -197
  284. data/locale/mr/katello.po +236 -197
  285. data/locale/nl_NL/katello.po +236 -197
  286. data/locale/or/katello.po +236 -197
  287. data/locale/pa/katello.po +236 -197
  288. data/locale/pl/katello.po +236 -197
  289. data/locale/pl_PL/katello.po +236 -197
  290. data/locale/pt/katello.po +236 -197
  291. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  292. data/locale/pt_BR/katello.po +238 -199
  293. data/locale/ro/katello.po +236 -197
  294. data/locale/ro_RO/katello.po +236 -197
  295. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  296. data/locale/ru/katello.po +236 -197
  297. data/locale/sl/katello.po +236 -197
  298. data/locale/sv_SE/katello.po +236 -197
  299. data/locale/ta/katello.po +236 -197
  300. data/locale/ta_IN/katello.po +236 -197
  301. data/locale/te/katello.po +236 -197
  302. data/locale/tr/katello.po +236 -197
  303. data/locale/vi/katello.po +236 -197
  304. data/locale/vi_VN/katello.po +236 -197
  305. data/locale/zh/katello.po +236 -197
  306. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  307. data/locale/zh_CN/katello.po +247 -208
  308. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  309. data/locale/zh_TW/katello.po +236 -197
  310. data/webpack/components/Table/EmptyStateMessage.js +7 -4
  311. data/webpack/components/Table/MainTable.scss +18 -17
  312. data/webpack/components/Table/TableWrapper.js +4 -1
  313. data/webpack/components/extensions/HostDetails/ActionsBar/index.js +45 -4
  314. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.scss +9 -7
  315. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.js +1 -1
  316. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsModal.js +1 -1
  317. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeActions.js +29 -7
  318. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.js +106 -66
  319. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.scss +6 -0
  320. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeConstants.js +2 -0
  321. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeEditModal.js +53 -29
  322. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeSelectors.js +7 -6
  323. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/__tests__/SystemPurposeCard.test.js +24 -5
  324. data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/__tests__/SystemPurposeEditModal.test.js +137 -7
  325. data/webpack/components/extensions/HostDetails/DetailsTabCards/HwPropertiesCard.js +11 -10
  326. data/webpack/components/extensions/HostDetails/DetailsTabCards/RegistrationCard.js +8 -2
  327. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +27 -10
  328. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/HostErrataActions.js +3 -22
  329. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/HostErrataConstants.js +0 -1
  330. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +3 -2
  331. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js +2 -2
  332. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +48 -12
  333. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +22 -10
  334. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionHooks.js +1 -1
  335. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +2 -2
  336. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerModal.js +71 -5
  337. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerModal.scss +16 -0
  338. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesEnabler.js +4 -1
  339. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesTab.js +6 -2
  340. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +2 -1
  341. data/webpack/components/extensions/HostDetails/Tabs/__tests__/tracesTab.test.js +25 -0
  342. data/webpack/components/extensions/Hosts/ActionsBar/index.js +36 -0
  343. data/webpack/components/extensions/Hosts/constants.js +2 -0
  344. data/webpack/components/extensions/RegistrationCommands/RegistrationCommandsPageHelpers.js +13 -7
  345. data/webpack/components/extensions/RegistrationCommands/__tests__/__snapshots__/ActivationKeys.test.js.snap +9 -1
  346. data/webpack/components/extensions/RegistrationCommands/fields/ActivationKeys.js +87 -22
  347. data/webpack/components/extensions/RegistrationCommands/index.js +17 -41
  348. data/webpack/global_index.js +11 -2
  349. data/webpack/redux/reducers/RedHatRepositories/enabled.fixtures.js +4 -0
  350. data/webpack/redux/reducers/RedHatRepositories/enabled.js +1 -0
  351. data/webpack/scenes/ActivationKeys/Details/ActivationKeyDetails.js +10 -1
  352. data/webpack/scenes/ActivationKeys/Details/ActivationKeyDetails.scss +33 -31
  353. data/webpack/scenes/AlternateContentSources/MainTable/ACSTable.js +3 -1
  354. data/webpack/scenes/Content/ContentConfig.js +3 -0
  355. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +6 -4
  356. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.scss +8 -6
  357. data/webpack/scenes/ContentViews/Delete/ContentViewDeleteWizard.js +1 -0
  358. data/webpack/scenes/ContentViews/Delete/Steps/CVEnvironmentSelectionForm.scss +4 -2
  359. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +3 -4
  360. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +2 -2
  361. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +5 -5
  362. data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/compositeCVDetails.fixtures.json +393 -0
  363. data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/contentViewComponents.test.js +30 -4
  364. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +3 -1
  365. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/CVRpmMatchContentModal.js +18 -4
  366. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/matchContentModal.scss +3 -0
  367. data/webpack/scenes/ContentViews/Details/Filters/Rules/Package/AddEditPackageRuleModal.js +15 -1
  368. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +3 -3
  369. data/webpack/scenes/ContentViews/Details/Repositories/RepoIcon.js +2 -1
  370. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareTable.js +1 -1
  371. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +1 -1
  372. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveCVVersionWizard.js +1 -1
  373. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsTable.js +1 -1
  374. data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +24 -1
  375. data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +1 -0
  376. data/webpack/scenes/ContentViews/Publish/__tests__/publishContentView.test.js +42 -0
  377. data/webpack/scenes/ContentViews/Publish/cvPublishForm.scss +13 -11
  378. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +2 -1
  379. data/webpack/scenes/ContentViews/__tests__/mockDetails.fixtures.json +2 -1
  380. data/webpack/scenes/Hosts/ChangeContentSource/index.js +4 -3
  381. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetails.js +1 -2
  382. data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetails.test.js.snap +1 -1
  383. data/webpack/scenes/RedHatRepositories/RedHatRepositoriesPage.js +2 -1
  384. data/webpack/scenes/RedHatRepositories/__tests__/__snapshots__/RedHatRepositoriesPage.test.js.snap +6 -0
  385. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepository.js +4 -1
  386. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepositoryContent.js +13 -4
  387. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/EnabledRepositoryContent.test.js +1 -0
  388. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/__snapshots__/EnabledRepository.test.js.snap +1 -0
  389. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/__snapshots__/EnabledRepositoryContent.test.js.snap +3 -2
  390. data/webpack/scenes/SmartProxy/AdditionalCapsuleContent.js +93 -0
  391. data/webpack/scenes/SmartProxy/Content.js +12 -4
  392. data/webpack/scenes/SmartProxy/ExpandableCvDetails.js +107 -0
  393. data/webpack/scenes/SmartProxy/ExpandedSmartProxyRepositories.js +139 -0
  394. data/webpack/scenes/SmartProxy/SmartProxyContentActions.js +17 -4
  395. data/webpack/scenes/SmartProxy/SmartProxyContentConstants.js +1 -0
  396. data/webpack/scenes/SmartProxy/SmartProxyExpandableTable.js +150 -0
  397. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.fixtures.json +799 -0
  398. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentTest.js +29 -17
  399. data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.js +16 -19
  400. data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.scss +12 -8
  401. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +21 -18
  402. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnConfigurationForm.scss +4 -2
  403. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.scss +38 -19
  404. data/webpack/scenes/Subscriptions/Manifest/index.js +0 -2
  405. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +38 -12
  406. data/webpack/scenes/Subscriptions/SubscriptionsPage.scss +38 -36
  407. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +16 -13
  408. data/webpack/utils/helpers.js +0 -1
  409. metadata +58 -39
  410. data/app/controllers/katello/concerns/api/v2/bulk_hosts_extensions.rb +0 -47
  411. data/webpack/components/Table/TableHooks.js +0 -315
  412. data/webpack/components/Table/__test__/useBulkSelect.test.js +0 -99
  413. data/webpack/components/extensions/RegistrationCommands/__tests__/LifeCycleEnvironment.test.js +0 -11
  414. data/webpack/components/extensions/RegistrationCommands/__tests__/__snapshots__/LifeCycleEnvironment.test.js.snap +0 -29
  415. data/webpack/components/extensions/RegistrationCommands/fields/LifecycleEnvironment.js +0 -57
  416. data/webpack/scenes/SmartProxy/SmartProxyContentTable.js +0 -164
  417. data/webpack/scenes/SmartProxy/__tests__/SmartProxyContentResult.fixtures.json +0 -140
  418. data/webpack/scenes/Subscriptions/Manifest/Manifest.scss +0 -16
@@ -4,10 +4,10 @@ import {
4
4
  } from 'react-redux';
5
5
  import PropTypes from 'prop-types';
6
6
  import { translate as __ } from 'foremanReact/common/I18n';
7
+ import { useTableSort } from 'foremanReact/components/PF4/Helpers/useTableSort';
7
8
  import { TableVariant, Tr, Th, Tbody, Td, Thead } from '@patternfly/react-table';
8
9
  import { TableType } from './CVVersionCompareConfig';
9
10
  import TableWrapper from '../../../../../components/Table/TableWrapper';
10
- import { useTableSort } from '../../../../../components/Table/TableHooks';
11
11
  import './CVVersionCompare.scss';
12
12
 
13
13
  const CVVersionCompareTable = ({
@@ -8,7 +8,7 @@ import { STATUS } from 'foremanReact/constants';
8
8
  import { Link } from 'react-router-dom';
9
9
  import PropTypes from 'prop-types';
10
10
  import { first } from 'lodash';
11
- import { useSelectionSet } from '../../../../components/Table/TableHooks';
11
+ import { useSelectionSet } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
12
12
  import TableWrapper from '../../../../components/Table/TableWrapper';
13
13
  import InactiveText from '../../components/InactiveText';
14
14
  import ContentViewVersionEnvironments from './ContentViewVersionEnvironments';
@@ -3,6 +3,7 @@ import { useDispatch } from 'react-redux';
3
3
  import PropTypes from 'prop-types';
4
4
  import { Wizard } from '@patternfly/react-core';
5
5
  import { translate as __ } from 'foremanReact/common/I18n';
6
+ import { useSet } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
6
7
  import getEnvironmentPaths from '../../../components/EnvironmentPaths/EnvironmentPathActions';
7
8
  import CVEnvironmentSelectionForm from './RemoveSteps/CVEnvironmentSelectionForm';
8
9
  import CVReassignActivationKeysForm from './RemoveSteps/CVReassignActivationKeysForm';
@@ -12,7 +13,6 @@ import CVVersionDeleteFinish from './RemoveSteps/CVVersionDeleteFinish';
12
13
  import getContentViewDetails from '../../ContentViewDetailActions';
13
14
  import getContentViews from '../../../ContentViewsActions';
14
15
  import DeleteContext from './DeleteContext';
15
- import { useSet } from '../../../../../components/Table/TableHooks';
16
16
 
17
17
  const RemoveCVVersionWizard = ({
18
18
  cvId, versionIdToRemove, versionNameToRemove,
@@ -21,7 +21,7 @@ import {
21
21
  Thead,
22
22
  Tr,
23
23
  } from '@patternfly/react-table';
24
- import { useUrlParams } from '../../../../../components/Table/TableHooks';
24
+ import { useUrlParams } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
25
25
  import TableWrapper from '../../../../../components/Table/TableWrapper';
26
26
  import { TableType } from './ContentViewVersionDetailConfig';
27
27
 
@@ -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;