katello 4.13.1 → 4.14.0.rc1.1

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 (423) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/hosts/host_and_hostgroup_edit.js +12 -8
  3. data/app/assets/javascripts/katello/locale/bn/katello.js +274 -22
  4. data/app/assets/javascripts/katello/locale/bn_IN/katello.js +274 -22
  5. data/app/assets/javascripts/katello/locale/ca/katello.js +274 -22
  6. data/app/assets/javascripts/katello/locale/cs/katello.js +274 -22
  7. data/app/assets/javascripts/katello/locale/cs_CZ/katello.js +275 -23
  8. data/app/assets/javascripts/katello/locale/de/katello.js +280 -28
  9. data/app/assets/javascripts/katello/locale/de_AT/katello.js +274 -22
  10. data/app/assets/javascripts/katello/locale/de_DE/katello.js +274 -22
  11. data/app/assets/javascripts/katello/locale/el/katello.js +274 -22
  12. data/app/assets/javascripts/katello/locale/en/katello.js +274 -22
  13. data/app/assets/javascripts/katello/locale/en_GB/katello.js +274 -22
  14. data/app/assets/javascripts/katello/locale/en_US/katello.js +274 -22
  15. data/app/assets/javascripts/katello/locale/es/katello.js +276 -24
  16. data/app/assets/javascripts/katello/locale/et_EE/katello.js +274 -22
  17. data/app/assets/javascripts/katello/locale/fr/katello.js +283 -31
  18. data/app/assets/javascripts/katello/locale/gl/katello.js +274 -22
  19. data/app/assets/javascripts/katello/locale/gu/katello.js +274 -22
  20. data/app/assets/javascripts/katello/locale/he_IL/katello.js +274 -22
  21. data/app/assets/javascripts/katello/locale/hi/katello.js +274 -22
  22. data/app/assets/javascripts/katello/locale/id/katello.js +274 -22
  23. data/app/assets/javascripts/katello/locale/it/katello.js +274 -22
  24. data/app/assets/javascripts/katello/locale/ja/katello.js +283 -31
  25. data/app/assets/javascripts/katello/locale/ka/katello.js +280 -28
  26. data/app/assets/javascripts/katello/locale/kn/katello.js +274 -22
  27. data/app/assets/javascripts/katello/locale/ko/katello.js +274 -22
  28. data/app/assets/javascripts/katello/locale/ml_IN/katello.js +274 -22
  29. data/app/assets/javascripts/katello/locale/mr/katello.js +274 -22
  30. data/app/assets/javascripts/katello/locale/nl_NL/katello.js +274 -22
  31. data/app/assets/javascripts/katello/locale/or/katello.js +274 -22
  32. data/app/assets/javascripts/katello/locale/pa/katello.js +274 -22
  33. data/app/assets/javascripts/katello/locale/pl/katello.js +274 -22
  34. data/app/assets/javascripts/katello/locale/pl_PL/katello.js +274 -22
  35. data/app/assets/javascripts/katello/locale/pt/katello.js +274 -22
  36. data/app/assets/javascripts/katello/locale/pt_BR/katello.js +276 -24
  37. data/app/assets/javascripts/katello/locale/ro/katello.js +274 -22
  38. data/app/assets/javascripts/katello/locale/ro_RO/katello.js +274 -22
  39. data/app/assets/javascripts/katello/locale/ru/katello.js +274 -22
  40. data/app/assets/javascripts/katello/locale/sl/katello.js +274 -22
  41. data/app/assets/javascripts/katello/locale/sv_SE/katello.js +274 -22
  42. data/app/assets/javascripts/katello/locale/ta/katello.js +274 -22
  43. data/app/assets/javascripts/katello/locale/ta_IN/katello.js +274 -22
  44. data/app/assets/javascripts/katello/locale/te/katello.js +274 -22
  45. data/app/assets/javascripts/katello/locale/tr/katello.js +274 -22
  46. data/app/assets/javascripts/katello/locale/vi/katello.js +274 -22
  47. data/app/assets/javascripts/katello/locale/vi_VN/katello.js +274 -22
  48. data/app/assets/javascripts/katello/locale/zh/katello.js +274 -22
  49. data/app/assets/javascripts/katello/locale/zh_CN/katello.js +283 -31
  50. data/app/assets/javascripts/katello/locale/zh_TW/katello.js +274 -22
  51. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +118 -74
  52. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +15 -10
  53. data/app/controllers/katello/api/v2/activation_keys_controller.rb +1 -1
  54. data/app/controllers/katello/api/v2/api_controller.rb +7 -0
  55. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +4 -4
  56. data/app/controllers/katello/api/v2/debs_controller.rb +3 -2
  57. data/app/controllers/katello/api/v2/environments_controller.rb +2 -4
  58. data/app/controllers/katello/api/v2/host_contents_controller.rb +8 -3
  59. data/app/controllers/katello/api/v2/host_errata_controller.rb +4 -4
  60. data/app/controllers/katello/api/v2/host_packages_controller.rb +2 -2
  61. data/app/controllers/katello/api/v2/organizations_controller.rb +1 -1
  62. data/app/controllers/katello/api/v2/packages_controller.rb +13 -3
  63. data/app/controllers/katello/api/v2/repositories_bulk_actions_controller.rb +6 -2
  64. data/app/controllers/katello/api/v2/repositories_controller.rb +3 -4
  65. data/app/controllers/katello/api/v2/repository_sets_controller.rb +13 -14
  66. data/app/controllers/katello/api/v2/subscriptions_controller.rb +15 -9
  67. data/app/controllers/katello/api/v2/sync_controller.rb +2 -2
  68. data/app/controllers/katello/application_controller.rb +1 -1
  69. data/app/controllers/katello/concerns/api/v2/authorization.rb +3 -2
  70. data/app/controllers/katello/concerns/api/v2/hosts_controller_extensions.rb +28 -0
  71. data/app/controllers/katello/concerns/api/v2/registration_commands_controller_extensions.rb +1 -1
  72. data/app/controllers/katello/concerns/api/v2/registration_controller_extensions.rb +4 -0
  73. data/app/controllers/katello/concerns/api/v2/repository_content_controller.rb +4 -3
  74. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +2 -4
  75. data/app/controllers/katello/remote_execution_controller.rb +53 -58
  76. data/app/helpers/katello/hosts_and_hostgroups_helper.rb +19 -2
  77. data/app/helpers/katello/katello_urls_helper.rb +1 -1
  78. data/app/lib/actions/katello/alternate_content_source/alternate_content_source_common.rb +1 -1
  79. data/app/lib/actions/katello/alternate_content_source/update.rb +2 -1
  80. data/app/lib/actions/katello/capsule_content/verify_checksum.rb +1 -2
  81. data/app/lib/actions/katello/content_view/publish.rb +1 -0
  82. data/app/lib/actions/katello/content_view_version/create_repos.rb +1 -0
  83. data/app/lib/actions/katello/content_view_version/incremental_update.rb +3 -2
  84. data/app/lib/actions/katello/environment/{publish_repositories.rb → publish_container_repositories.rb} +10 -8
  85. data/app/lib/actions/katello/foreman/content_update.rb +4 -6
  86. data/app/lib/actions/katello/host/hypervisors_update.rb +6 -4
  87. data/app/lib/actions/katello/repository/create.rb +4 -4
  88. data/app/lib/actions/katello/repository/import_upload.rb +4 -6
  89. data/app/lib/actions/katello/repository/metadata_generate.rb +1 -0
  90. data/app/lib/actions/katello/repository/update.rb +3 -3
  91. data/app/lib/actions/katello/repository_set/enable_repository.rb +5 -6
  92. data/app/lib/actions/middleware/backend_services_check.rb +3 -2
  93. data/app/lib/actions/pulp3/abstract_async_task.rb +2 -4
  94. data/app/lib/actions/pulp3/capsule_content/verify_checksum.rb +1 -2
  95. data/app/lib/actions/pulp3/orchestration/repository/copy_all_units.rb +5 -1
  96. data/app/lib/actions/pulp3/orchestration/repository/delete.rb +5 -2
  97. data/app/lib/actions/pulp3/repository/save_version.rb +3 -5
  98. data/app/lib/katello/concerns/base_template_scope_extensions.rb +5 -9
  99. data/app/lib/katello/errors.rb +1 -0
  100. data/app/lib/katello/http_resource.rb +1 -0
  101. data/app/lib/katello/lazy_accessor.rb +1 -1
  102. data/app/lib/katello/resources/candlepin/candlepin_ping.rb +0 -5
  103. data/app/lib/katello/resources/candlepin/owner.rb +1 -1
  104. data/app/lib/katello/resources/candlepin/pool.rb +1 -2
  105. data/app/lib/katello/resources/candlepin/upstream_job.rb +1 -1
  106. data/app/lib/katello/resources/cdn.rb +3 -2
  107. data/app/lib/katello/resources/discovery/yum.rb +3 -3
  108. data/app/lib/katello/util/cdn_var_substitutor.rb +5 -3
  109. data/app/lib/katello/util/data.rb +3 -2
  110. data/app/lib/katello/util/errata.rb +4 -3
  111. data/app/lib/katello/util/package.rb +3 -3
  112. data/app/lib/katello/util/path_with_substitutions.rb +1 -1
  113. data/app/lib/katello/util/report_table.rb +3 -2
  114. data/app/lib/katello/util/url_matcher.rb +1 -1
  115. data/app/lib/katello/validators/alternate_content_source_path_validator.rb +4 -3
  116. data/app/lib/katello/validators/alternate_content_source_products_validator.rb +5 -7
  117. data/app/lib/katello/validators/container_image_name_validator.rb +1 -1
  118. data/app/lib/katello/validators/katello_name_format_validator.rb +2 -2
  119. data/app/lib/katello/validators/no_trailing_space_validator.rb +2 -2
  120. data/app/lib/katello/validators/prior_validator.rb +2 -2
  121. data/app/lib/katello/validators/product_unique_attribute_validator.rb +2 -4
  122. data/app/models/katello/activation_key.rb +4 -6
  123. data/app/models/katello/alternate_content_source.rb +1 -1
  124. data/app/models/katello/authorization/host_tracer.rb +1 -2
  125. data/app/models/katello/authorization/product.rb +1 -1
  126. data/app/models/katello/candlepin/repository_mapper.rb +2 -2
  127. data/app/models/katello/concerns/host_managed_extensions.rb +41 -10
  128. data/app/models/katello/concerns/hostgroup_extensions.rb +2 -4
  129. data/app/models/katello/concerns/location_extensions.rb +2 -4
  130. data/app/models/katello/concerns/operatingsystem_extensions.rb +84 -16
  131. data/app/models/katello/concerns/smart_proxy_extensions.rb +4 -4
  132. data/app/models/katello/concerns/subscription_facet_host_extensions.rb +2 -0
  133. data/app/models/katello/content_view.rb +5 -1
  134. data/app/models/katello/content_view_environment.rb +19 -4
  135. data/app/models/katello/content_view_environment_content_facet.rb +11 -0
  136. data/app/models/katello/erratum.rb +1 -1
  137. data/app/models/katello/event.rb +1 -1
  138. data/app/models/katello/glue/provider.rb +1 -2
  139. data/app/models/katello/hash_util.rb +1 -1
  140. data/app/models/katello/host/content_facet.rb +16 -3
  141. data/app/models/katello/host/subscription_facet.rb +27 -4
  142. data/app/models/katello/host_collection.rb +12 -8
  143. data/app/models/katello/pool.rb +5 -1
  144. data/app/models/katello/product.rb +7 -4
  145. data/app/models/katello/provider.rb +1 -2
  146. data/app/models/katello/repository.rb +18 -4
  147. data/app/models/katello/root_repository.rb +19 -0
  148. data/app/models/katello/rpm.rb +2 -2
  149. data/app/models/katello/subscription_facet_pool.rb +1 -1
  150. data/app/models/katello/sync_plan.rb +5 -4
  151. data/app/models/katello/task_status.rb +18 -18
  152. data/app/presenters/katello/product_host_count_presenter.rb +10 -0
  153. data/app/services/katello/candlepin/consumer.rb +11 -11
  154. data/app/services/katello/candlepin/message_handler.rb +3 -2
  155. data/app/services/katello/content_unit_indexer.rb +6 -0
  156. data/app/services/katello/pulp3/alternate_content_source.rb +1 -3
  157. data/app/services/katello/pulp3/api/core.rb +1 -1
  158. data/app/services/katello/pulp3/api/docker.rb +10 -0
  159. data/app/services/katello/pulp3/content_view_version/export.rb +1 -0
  160. data/app/services/katello/pulp3/content_view_version/import.rb +6 -4
  161. data/app/services/katello/pulp3/content_view_version/importable_products.rb +1 -3
  162. data/app/services/katello/pulp3/repository/apt.rb +4 -16
  163. data/app/services/katello/pulp3/repository/yum.rb +9 -5
  164. data/app/services/katello/pulp3/repository.rb +2 -2
  165. data/app/services/katello/pulp3/repository_mirror.rb +2 -9
  166. data/app/services/katello/pulp3/task.rb +4 -2
  167. data/app/services/katello/registration_manager.rb +13 -3
  168. data/app/services/katello/smart_proxy_helper.rb +1 -0
  169. data/app/views/dashboard/_host_collection_widget.html.erb +5 -4
  170. data/app/views/foreman/job_templates/install_errata.erb +2 -0
  171. data/app/views/foreman/job_templates/install_errata_-_katello_ansible_default.erb +2 -0
  172. data/app/views/foreman/job_templates/install_errata_by_search_query.erb +2 -0
  173. data/app/views/foreman/job_templates/install_errata_by_search_query_-_katello_ansible_default.erb +3 -1
  174. data/app/views/foreman/job_templates/install_packages_by_search_query_-_katello_ansible_default.erb +1 -1
  175. data/app/views/foreman/job_templates/remove_packages_by_search_query_-_katello_ansible_default.erb +2 -2
  176. data/app/views/foreman/job_templates/resolve_traces.erb +5 -1
  177. data/app/views/foreman/job_templates/update_packages_by_search_query_-_katello_ansible_default.erb +1 -1
  178. data/app/views/foreman/job_templates/upload_profile.erb +2 -0
  179. data/app/views/foreman/smart_proxies/_reclaim_space.html.erb +7 -5
  180. data/app/views/katello/api/v2/content_facet/base.json.rabl +18 -2
  181. data/app/views/katello/api/v2/packages/thindex.json.rabl +6 -0
  182. data/app/views/katello/api/v2/repositories/show.json.rabl +8 -8
  183. data/app/views/katello/api/v2/repository_sets/show.json.rabl +1 -1
  184. data/app/views/katello/api/v2/subscription_facet/base.json.rabl +1 -1
  185. data/app/views/katello/api/v2/subscriptions/index.json.rabl +1 -0
  186. data/app/views/katello/api/v2/subscriptions/show.json.rabl +1 -0
  187. data/app/views/overrides/activation_keys/_host_environment_select.html.erb +14 -11
  188. data/app/views/overrides/activation_keys/_host_synced_content_select.html.erb +4 -4
  189. data/config/routes/api/v2.rb +3 -1
  190. data/config/routes.rb +1 -3
  191. data/db/migrate/20160114200145_add_mirror_on_sync_to_repositories.rb +1 -0
  192. data/db/migrate/20160131182301_add_download_policy_to_katello_repositories.rb +1 -0
  193. data/db/migrate/20210119162528_delete_puppet_and_ostree_repos.rb +3 -0
  194. data/db/migrate/20240522165308_add_priority_to_content_view_environment_content_facet.rb +5 -0
  195. data/db/migrate/20240621121212_katello_repository_debs_id_bigint.rb +6 -0
  196. data/db/migrate/20240729192228_add_convert2rhel_to_host_facets.rb +9 -0
  197. data/db/seeds.d/102-organizations.rb +5 -7
  198. data/db/seeds.d/150-module_job_templates.rb +7 -9
  199. data/db/seeds.d/75-job_templates.rb +9 -16
  200. data/engines/bastion_katello/README.md +3 -0
  201. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-errata.controller.js +3 -3
  202. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/details/views/deb-info.html +6 -6
  203. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum-content-hosts.html +2 -2
  204. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +4 -4
  205. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/details/views/package-info.html +6 -6
  206. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +28 -27
  207. data/engines/bastion_katello/lib/bastion_katello/engine.rb +2 -2
  208. data/lib/katello/engine.rb +1 -8
  209. data/lib/katello/permission_creator.rb +3 -2
  210. data/lib/katello/plugin.rb +31 -27
  211. data/lib/katello/tasks/clean_old_file_repos.rake +2 -4
  212. data/lib/katello/tasks/reset.rake +3 -4
  213. data/lib/katello/version.rb +1 -1
  214. data/lib/katello.rb +0 -2
  215. data/lib/monkeys/ar_postgres_evr_t.rb +2 -0
  216. data/locale/action_names.rb +1 -1
  217. data/locale/bn/katello.po +274 -22
  218. data/locale/bn_IN/katello.po +274 -22
  219. data/locale/ca/katello.po +274 -22
  220. data/locale/cs/katello.po +274 -22
  221. data/locale/cs_CZ/katello.po +275 -23
  222. data/locale/de/katello.po +280 -28
  223. data/locale/de_AT/katello.po +274 -22
  224. data/locale/de_DE/katello.po +274 -22
  225. data/locale/el/katello.po +274 -22
  226. data/locale/en/katello.po +274 -22
  227. data/locale/en_GB/katello.po +274 -22
  228. data/locale/en_US/katello.po +274 -22
  229. data/locale/es/katello.po +276 -24
  230. data/locale/et_EE/katello.po +274 -22
  231. data/locale/fr/katello.po +283 -31
  232. data/locale/gl/katello.po +274 -22
  233. data/locale/gu/katello.po +274 -22
  234. data/locale/he_IL/katello.po +274 -22
  235. data/locale/hi/katello.po +274 -22
  236. data/locale/id/katello.po +274 -22
  237. data/locale/it/katello.po +274 -22
  238. data/locale/ja/katello.po +283 -31
  239. data/locale/ka/katello.po +280 -28
  240. data/locale/katello.pot +1001 -527
  241. data/locale/kn/katello.po +274 -22
  242. data/locale/ko/katello.po +274 -22
  243. data/locale/ml_IN/katello.po +274 -22
  244. data/locale/mr/katello.po +274 -22
  245. data/locale/nl_NL/katello.po +274 -22
  246. data/locale/or/katello.po +274 -22
  247. data/locale/pa/katello.po +274 -22
  248. data/locale/pl/katello.po +274 -22
  249. data/locale/pl_PL/katello.po +274 -22
  250. data/locale/pt/katello.po +274 -22
  251. data/locale/pt_BR/katello.po +276 -24
  252. data/locale/ro/katello.po +274 -22
  253. data/locale/ro_RO/katello.po +274 -22
  254. data/locale/ru/katello.po +274 -22
  255. data/locale/sl/katello.po +274 -22
  256. data/locale/sv_SE/katello.po +274 -22
  257. data/locale/ta/katello.po +274 -22
  258. data/locale/ta_IN/katello.po +274 -22
  259. data/locale/te/katello.po +274 -22
  260. data/locale/tr/katello.po +274 -22
  261. data/locale/vi/katello.po +274 -22
  262. data/locale/vi_VN/katello.po +274 -22
  263. data/locale/zh/katello.po +274 -22
  264. data/locale/zh_CN/katello.po +283 -31
  265. data/locale/zh_TW/katello.po +274 -22
  266. data/webpack/ForemanColumnExtensions/index.js +44 -1
  267. data/webpack/components/Table/TableWrapper.js +6 -0
  268. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ChangeHostCVModal.js +24 -3
  269. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard.js +124 -56
  270. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/HostContentViewActions.js +2 -3
  271. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/__tests__/contentViewDetailsCard.test.js +44 -10
  272. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +83 -31
  273. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionConstants.js +1 -0
  274. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionHooks.js +1 -1
  275. data/webpack/components/extensions/HostDetails/Tabs/__tests__/remoteExecutionActions.test.js +44 -0
  276. data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +22 -7
  277. data/webpack/components/extensions/Hosts/ActionsBar/ActionsBar.scss +14 -0
  278. data/webpack/components/extensions/Hosts/ActionsBar/index.js +82 -23
  279. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCVModal/index.js +5 -2
  280. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/02_BulkErrataTable.js +171 -0
  281. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/04_Review.js +160 -0
  282. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/04_ReviewFooter.js +99 -0
  283. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/BulkErrataWizard.js +157 -0
  284. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/index.js +24 -0
  285. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/02_BulkPackagesTable.js +157 -0
  286. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/04_Review.js +168 -0
  287. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/04_ReviewFooter.js +141 -0
  288. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/BulkPackagesWizard.js +252 -0
  289. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/index.js +24 -0
  290. data/webpack/components/extensions/Hosts/BulkActions/HostReview.js +176 -0
  291. data/webpack/components/extensions/Hosts/TableRowActions/index.js +17 -0
  292. data/webpack/global_index.js +11 -3
  293. data/webpack/redux/actions/RedHatRepositories/repositorySetRepositories.js +5 -6
  294. data/webpack/redux/reducers/RedHatRepositories/__tests__/repositorySetRepositories.test.js +1 -1
  295. data/webpack/redux/reducers/RedHatRepositories/repositorySetRepositories.js +1 -1
  296. data/webpack/scenes/ContentViews/Copy/CopyContentViewModal.js +2 -1
  297. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +2 -1
  298. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +2 -1
  299. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +2 -1
  300. data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +2 -1
  301. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +2 -2
  302. data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +2 -1
  303. data/webpack/scenes/ContentViews/Publish/CVPublishReview.js +3 -2
  304. data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +2 -1
  305. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +2 -1
  306. data/webpack/scenes/ContentViews/components/CVBreadCrumb.js +2 -1
  307. data/webpack/scenes/ContentViews/components/ContentViewSelect/ContentViewSelectOption.js +2 -2
  308. data/webpack/scenes/Subscriptions/Details/SubscriptionAttributes.js +1 -0
  309. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailInfo.test.js.snap +10 -0
  310. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +6 -0
  311. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +2 -0
  312. data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +14 -0
  313. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableHelpers.js +1 -0
  314. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableSchema.js +10 -0
  315. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.fixtures.js +1 -0
  316. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/__snapshots__/SubscriptionsToolbar.test.js.snap +10 -0
  317. data/webpack/scenes/Tasks/helpers.js +1 -1
  318. metadata +25 -111
  319. data/app/assets/javascripts/katello/containers/container.js +0 -304
  320. data/app/lib/katello/util/http_helper.rb +0 -15
  321. data/app/models/732bd3db9f64c621c64d2be4f2a838727aac0845.patch +0 -61
  322. data/app/models/katello/repository.rb.bak +0 -978
  323. data/app/services/katello/pulp3/content_view_version/import_validator.rb.bak +0 -166
  324. data/app/services/katello/pulp3/content_view_version/importable_repositories.rb.bak +0 -164
  325. data/lib/katello/tasks/update_repository_expiry.rake +0 -114
  326. data/locale/bn/LC_MESSAGES/katello.mo +0 -0
  327. data/locale/bn/katello.po.time_stamp +0 -0
  328. data/locale/bn_IN/LC_MESSAGES/katello.mo +0 -0
  329. data/locale/bn_IN/katello.po.time_stamp +0 -0
  330. data/locale/ca/LC_MESSAGES/katello.mo +0 -0
  331. data/locale/ca/katello.po.time_stamp +0 -0
  332. data/locale/cs/LC_MESSAGES/katello.mo +0 -0
  333. data/locale/cs/katello.po.time_stamp +0 -0
  334. data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
  335. data/locale/cs_CZ/katello.po.time_stamp +0 -0
  336. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  337. data/locale/de/katello.po.time_stamp +0 -0
  338. data/locale/de_AT/LC_MESSAGES/katello.mo +0 -0
  339. data/locale/de_AT/katello.po.time_stamp +0 -0
  340. data/locale/de_DE/LC_MESSAGES/katello.mo +0 -0
  341. data/locale/de_DE/katello.po.time_stamp +0 -0
  342. data/locale/el/LC_MESSAGES/katello.mo +0 -0
  343. data/locale/el/katello.po.time_stamp +0 -0
  344. data/locale/en/LC_MESSAGES/katello.mo +0 -0
  345. data/locale/en/katello.po.time_stamp +0 -0
  346. data/locale/en_GB/LC_MESSAGES/katello.mo +0 -0
  347. data/locale/en_GB/katello.po.time_stamp +0 -0
  348. data/locale/en_US/LC_MESSAGES/katello.mo +0 -0
  349. data/locale/en_US/katello.po.time_stamp +0 -0
  350. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  351. data/locale/es/katello.po.time_stamp +0 -0
  352. data/locale/et_EE/LC_MESSAGES/katello.mo +0 -0
  353. data/locale/et_EE/katello.po.time_stamp +0 -0
  354. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  355. data/locale/fr/katello.po.time_stamp +0 -0
  356. data/locale/gl/LC_MESSAGES/katello.mo +0 -0
  357. data/locale/gl/katello.po.time_stamp +0 -0
  358. data/locale/gu/LC_MESSAGES/katello.mo +0 -0
  359. data/locale/gu/katello.po.time_stamp +0 -0
  360. data/locale/he_IL/LC_MESSAGES/katello.mo +0 -0
  361. data/locale/he_IL/katello.po.time_stamp +0 -0
  362. data/locale/hi/LC_MESSAGES/katello.mo +0 -0
  363. data/locale/hi/katello.po.time_stamp +0 -0
  364. data/locale/id/LC_MESSAGES/katello.mo +0 -0
  365. data/locale/id/katello.po.time_stamp +0 -0
  366. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  367. data/locale/it/katello.po.time_stamp +0 -0
  368. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  369. data/locale/ja/katello.po.time_stamp +0 -0
  370. data/locale/ka/LC_MESSAGES/katello.mo +0 -0
  371. data/locale/ka/katello.po.time_stamp +0 -0
  372. data/locale/kn/LC_MESSAGES/katello.mo +0 -0
  373. data/locale/kn/katello.po.time_stamp +0 -0
  374. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  375. data/locale/ko/katello.po.time_stamp +0 -0
  376. data/locale/ml_IN/LC_MESSAGES/katello.mo +0 -0
  377. data/locale/ml_IN/katello.po.time_stamp +0 -0
  378. data/locale/mr/LC_MESSAGES/katello.mo +0 -0
  379. data/locale/mr/katello.po.time_stamp +0 -0
  380. data/locale/nl_NL/LC_MESSAGES/katello.mo +0 -0
  381. data/locale/nl_NL/katello.po.time_stamp +0 -0
  382. data/locale/or/LC_MESSAGES/katello.mo +0 -0
  383. data/locale/or/katello.po.time_stamp +0 -0
  384. data/locale/pa/LC_MESSAGES/katello.mo +0 -0
  385. data/locale/pa/katello.po.time_stamp +0 -0
  386. data/locale/pl/LC_MESSAGES/katello.mo +0 -0
  387. data/locale/pl/katello.po.time_stamp +0 -0
  388. data/locale/pl_PL/LC_MESSAGES/katello.mo +0 -0
  389. data/locale/pl_PL/katello.po.time_stamp +0 -0
  390. data/locale/pt/LC_MESSAGES/katello.mo +0 -0
  391. data/locale/pt/katello.po.time_stamp +0 -0
  392. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  393. data/locale/pt_BR/katello.po.time_stamp +0 -0
  394. data/locale/ro/LC_MESSAGES/katello.mo +0 -0
  395. data/locale/ro/katello.po.time_stamp +0 -0
  396. data/locale/ro_RO/LC_MESSAGES/katello.mo +0 -0
  397. data/locale/ro_RO/katello.po.time_stamp +0 -0
  398. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  399. data/locale/ru/katello.po.time_stamp +0 -0
  400. data/locale/sl/LC_MESSAGES/katello.mo +0 -0
  401. data/locale/sl/katello.po.time_stamp +0 -0
  402. data/locale/sv_SE/LC_MESSAGES/katello.mo +0 -0
  403. data/locale/sv_SE/katello.po.time_stamp +0 -0
  404. data/locale/ta/LC_MESSAGES/katello.mo +0 -0
  405. data/locale/ta/katello.po.time_stamp +0 -0
  406. data/locale/ta_IN/LC_MESSAGES/katello.mo +0 -0
  407. data/locale/ta_IN/katello.po.time_stamp +0 -0
  408. data/locale/te/LC_MESSAGES/katello.mo +0 -0
  409. data/locale/te/katello.po.time_stamp +0 -0
  410. data/locale/tr/LC_MESSAGES/katello.mo +0 -0
  411. data/locale/tr/katello.po.time_stamp +0 -0
  412. data/locale/vi/LC_MESSAGES/katello.mo +0 -0
  413. data/locale/vi/katello.po.time_stamp +0 -0
  414. data/locale/vi_VN/LC_MESSAGES/katello.mo +0 -0
  415. data/locale/vi_VN/katello.po.time_stamp +0 -0
  416. data/locale/zh/LC_MESSAGES/katello.mo +0 -0
  417. data/locale/zh/katello.po.time_stamp +0 -0
  418. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  419. data/locale/zh_CN/katello.po.time_stamp +0 -0
  420. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  421. data/locale/zh_TW/katello.po.time_stamp +0 -0
  422. data/webpack/global_test_setup.js.bak +0 -59
  423. data/webpack/utils/useKatelloDocUrl.js +0 -18
@@ -7,9 +7,11 @@ import {
7
7
  PackageIcon,
8
8
  } from '@patternfly/react-icons';
9
9
  import { Link } from 'react-router-dom';
10
- import { Flex, FlexItem } from '@patternfly/react-core';
10
+ import { Flex, FlexItem, Popover, Badge } from '@patternfly/react-core';
11
11
  import { translate as __ } from 'foremanReact/common/I18n';
12
12
  import RelativeDateTime from 'foremanReact/components/common/dates/RelativeDateTime';
13
+ import { ContentViewEnvironmentDisplay } from '../components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard';
14
+ import { truncate } from '../utils/helpers';
13
15
 
14
16
  const hostsIndexColumnExtensions = [
15
17
  {
@@ -97,6 +99,47 @@ const hostsIndexColumnExtensions = [
97
99
  weight: 2400,
98
100
  isSorted: true,
99
101
  },
102
+ {
103
+ columnName: 'content_view_environments',
104
+ title: __('Content view environments'),
105
+ wrapper: (hostDetails) => {
106
+ const contentViewEnvironments =
107
+ hostDetails?.content_facet_attributes?.content_view_environments ?? [];
108
+ if (contentViewEnvironments.length === 0) return '—'; // don't show popover
109
+ return (
110
+ <Flex>
111
+ {contentViewEnvironments.length > 1 &&
112
+ <FlexItem>
113
+ <Badge isRead>{contentViewEnvironments.length}</Badge>
114
+ </FlexItem>
115
+ }
116
+ <Popover
117
+ id="content-view-environments-tooltip"
118
+ className="content-view-environments-tooltip"
119
+ maxWidth="34rem"
120
+ headerContent={hostDetails.display_name}
121
+ bodyContent={
122
+ <Flex direction={{ default: 'column' }}>
123
+ {contentViewEnvironments.map(env => (
124
+ <ContentViewEnvironmentDisplay
125
+ key={`${env.lifecycle_environment.name}-${env.content_view.name}`}
126
+ contentView={env.content_view}
127
+ lifecycleEnvironment={env.lifecycle_environment}
128
+ />
129
+ ))}
130
+ </Flex>
131
+ }
132
+ >
133
+ <FlexItem>
134
+ {truncate(contentViewEnvironments.map(cve => cve.candlepin_name).join(', '), 35)}
135
+ </FlexItem>
136
+ </Popover>
137
+ </Flex>
138
+ );
139
+ },
140
+ weight: 2290,
141
+ isSorted: false,
142
+ },
100
143
  {
101
144
  columnName: 'content_source',
102
145
  title: __('Content source'),
@@ -33,6 +33,8 @@ const TableWrapper = ({
33
33
  additionalListeners,
34
34
  activeFilters,
35
35
  displaySelectAllCheckbox,
36
+ hasInteracted,
37
+ setHasInteracted,
36
38
  selectAll,
37
39
  selectAllMode,
38
40
  selectNone,
@@ -307,6 +309,8 @@ TableWrapper.propTypes = {
307
309
  selectedDefaultCount: PropTypes.number,
308
310
  selectedResults: PropTypes.arrayOf(PropTypes.shape({})),
309
311
  clearSelectedResults: PropTypes.func,
312
+ hasInteracted: PropTypes.bool,
313
+ setHasInteracted: PropTypes.func,
310
314
  selectAll: PropTypes.func,
311
315
  selectAllMode: PropTypes.bool,
312
316
  selectNone: PropTypes.func,
@@ -337,6 +341,8 @@ TableWrapper.defaultProps = {
337
341
  alwaysShowActionButtons: true,
338
342
  alwaysShowToggleGroup: false,
339
343
  toggleGroup: null,
344
+ hasInteracted: false,
345
+ setHasInteracted: noop,
340
346
  displaySelectAllCheckbox: false,
341
347
  selectedCount: 0,
342
348
  selectedDefaultCount: 0,
@@ -5,6 +5,7 @@ import { Modal, Button, Alert, Checkbox, TextContent, Text, TextVariants } from
5
5
  import { translate as __ } from 'foremanReact/common/I18n';
6
6
  import { STATUS } from 'foremanReact/constants';
7
7
  import { useAPI } from 'foremanReact/common/hooks/API/APIHooks';
8
+ import { useUrlParams } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
8
9
  import { selectAPIStatus } from 'foremanReact/redux/API/APISelectors';
9
10
  import EnvironmentPaths from '../../../../../scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths';
10
11
  import { ENVIRONMENT_PATHS_KEY } from '../../../../../scenes/ContentViews/components/EnvironmentPaths/EnvironmentPathConstants';
@@ -32,7 +33,9 @@ const ChangeHostCVModal = ({
32
33
  hostId,
33
34
  contentSourceId,
34
35
  hostName,
36
+ multiEnv,
35
37
  }) => {
38
+ const { content_view_assignment: initialCVModalOpen } = useUrlParams();
36
39
  const [selectedEnvForHost, setSelectedEnvForHost]
37
40
  = useState([]);
38
41
 
@@ -62,6 +65,13 @@ const ChangeHostCVModal = ({
62
65
  closeModal();
63
66
  };
64
67
 
68
+ const handleCancel = () => {
69
+ handleModalClose();
70
+ if (initialCVModalOpen) {
71
+ window.history.back();
72
+ }
73
+ };
74
+
65
75
  const selectedEnv = selectedEnvForHost?.[0];
66
76
  const selectedEnvId = selectedEnv?.id;
67
77
 
@@ -132,8 +142,8 @@ const ChangeHostCVModal = ({
132
142
  >
133
143
  {__('Save')}
134
144
  </Button>,
135
- <Button key="cancel" ouiaId="change-host-cv-modal-cancel-button" variant="link" onClick={handleModalClose}>
136
- Cancel
145
+ <Button key="cancel" ouiaId="change-host-cv-modal-cancel-button" variant="link" onClick={handleCancel}>
146
+ {__('Cancel')}
137
147
  </Button>,
138
148
  ]);
139
149
  return (
@@ -174,13 +184,22 @@ const ChangeHostCVModal = ({
174
184
  <a href={`/change_host_content_source?host_id=${hostId}`}>{__('change the host\'s content source.')}</a>
175
185
  </Alert>
176
186
  }
187
+ {multiEnv &&
188
+ <Alert
189
+ variant="warning"
190
+ ouiaId="multi-env-alert"
191
+ isInline
192
+ title={__('This host is associated with multiple content view environments. If you assign a lifecycle environment and content view here, the host will be removed from the other environments.')}
193
+ style={{ marginBottom: '1rem' }}
194
+ />
195
+ }
177
196
  <EnvironmentPaths
178
197
  userCheckedItems={selectedEnvForHost}
179
198
  setUserCheckedItems={handleEnvSelect}
180
199
  publishing={false}
181
200
  multiSelect={false}
182
201
  hostId={hostId}
183
- headerText={__('Select environment')}
202
+ headerText={__('Select lifecycle environment')}
184
203
  isDisabled={hostUpdateStatus === STATUS.PENDING}
185
204
  />
186
205
  <ContentViewSelect
@@ -229,6 +248,7 @@ ChangeHostCVModal.propTypes = {
229
248
  hostId: PropTypes.number.isRequired,
230
249
  contentSourceId: PropTypes.number,
231
250
  hostName: PropTypes.string.isRequired,
251
+ multiEnv: PropTypes.bool,
232
252
  };
233
253
 
234
254
  ChangeHostCVModal.defaultProps = {
@@ -236,6 +256,7 @@ ChangeHostCVModal.defaultProps = {
236
256
  closeModal: () => {},
237
257
  hostEnvId: null,
238
258
  contentSourceId: null,
259
+ multiEnv: false,
239
260
  };
240
261
 
241
262
 
@@ -18,29 +18,91 @@ import { FormattedMessage } from 'react-intl';
18
18
  import { urlBuilder } from 'foremanReact/common/urlHelpers';
19
19
  import { translate as __ } from 'foremanReact/common/I18n';
20
20
  import { propsToCamelCase } from 'foremanReact/common/helpers';
21
+ import { useUrlParams } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
21
22
  import PropTypes from 'prop-types';
22
23
  import ContentViewIcon from '../../../../../scenes/ContentViews/components/ContentViewIcon';
23
24
  import { hasRequiredPermissions, hostIsRegistered } from '../../hostDetailsHelpers';
24
25
  import ChangeHostCVModal from './ChangeHostCVModal';
26
+ import { truncate } from '../../../../../utils/helpers';
25
27
 
26
28
  const requiredPermissions = [
27
29
  'view_lifecycle_environments', 'view_content_views',
28
30
  'promote_or_remove_content_views_to_environments',
29
31
  ];
30
32
 
31
- const HostContentViewDetails = ({
32
- contentView, lifecycleEnvironment, contentViewVersionId, contentViewDefault,
33
- contentViewVersion, contentViewVersionLatest, hostId, hostName, orgId, hostEnvId,
34
- hostPermissions, permissions, contentSourceId,
33
+ export const ContentViewEnvironmentDisplay = ({
34
+ contentView, lifecycleEnvironment,
35
35
  }) => {
36
- let versionLabel = `Version ${contentViewVersion}`;
36
+ const {
37
+ contentViewDefault,
38
+ contentViewVersionId,
39
+ contentViewVersion,
40
+ contentViewVersionLatest,
41
+ } = propsToCamelCase(contentView);
42
+ let versionLabel = 'Version {version}';
37
43
  if (contentViewVersionLatest) {
38
44
  versionLabel += ' (latest)';
39
45
  }
46
+ return (
47
+ <FlexItem>
48
+ <Flex direction={{ default: 'row', sm: 'row' }} flexWrap={{ default: 'wrap' }}>
49
+ <Tooltip
50
+ position="top"
51
+ enableFlip
52
+ entryDelay={400}
53
+ content={<FormattedMessage
54
+ id="cv-card-lce-tooltip"
55
+ defaultMessage={__('Lifecycle environment: {lce}')}
56
+ values={{
57
+ lce: lifecycleEnvironment.name,
58
+ }}
59
+ />}
60
+ >
61
+ <Label isTruncated color="purple" href={`/lifecycle_environments/${lifecycleEnvironment.id}`}>{lifecycleEnvironment.name}</Label>
62
+ </Tooltip>
63
+ <ContentViewIcon composite={contentView.composite} style={{ marginRight: '2px' }} position="left" />
64
+ {contentViewDefault ? <span>{contentView.name}</span> :
65
+ <a style={{ fontSize: '14px' }} href={`/content_views/${contentView.id}`}>
66
+ {truncate(contentView.name)}
67
+ </a>
68
+ }
69
+ {!contentViewDefault &&
70
+ <FlexItem>
71
+ <a style={{ fontSize: '14px' }} href={urlBuilder(`content_views/${contentView.id}/versions/${contentViewVersionId}`, '')}>
72
+ <FormattedMessage
73
+ id={`lce-${lifecycleEnvironment.name}-cv-version-${contentViewVersion}`}
74
+ defaultMessage={versionLabel}
75
+ values={{
76
+ version: contentViewVersion,
77
+ }}
78
+ />
79
+ </a>
80
+ </FlexItem>}
81
+ </Flex>
82
+ </FlexItem>
83
+ );
84
+ };
40
85
 
86
+ ContentViewEnvironmentDisplay.propTypes = {
87
+ contentView: PropTypes.shape({
88
+ name: PropTypes.string,
89
+ id: PropTypes.number,
90
+ composite: PropTypes.bool,
91
+ }).isRequired,
92
+ lifecycleEnvironment: PropTypes.shape({
93
+ name: PropTypes.string,
94
+ id: PropTypes.number,
95
+ }).isRequired,
96
+ };
97
+
98
+ const HostContentViewDetails = ({
99
+ contentViewEnvironments, hostId, hostName, orgId, hostEnvId,
100
+ hostPermissions, permissions, contentSourceId,
101
+ }) => {
41
102
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
42
103
  const toggleHamburger = () => setIsDropdownOpen(prev => !prev);
43
- const [isModalOpen, setIsModalOpen] = useState(false);
104
+ const { content_view_assignment: initialCVModalOpen } = useUrlParams();
105
+ const [isModalOpen, setIsModalOpen] = useState(!!initialCVModalOpen);
44
106
  const closeModal = () => setIsModalOpen(false);
45
107
  const openModal = () => {
46
108
  setIsDropdownOpen(false);
@@ -58,7 +120,7 @@ const HostContentViewDetails = ({
58
120
  component="button"
59
121
  onClick={openModal}
60
122
  >
61
- {__('Edit content view assignment')}
123
+ {__('Edit content view environments')}
62
124
  </DropdownItem>,
63
125
  ];
64
126
 
@@ -77,7 +139,15 @@ const HostContentViewDetails = ({
77
139
  justifyContent={{ default: 'justifyContentSpaceBetween' }}
78
140
  >
79
141
  <FlexItem>
80
- <CardTitle>{__('Content view details')}</CardTitle>
142
+ <CardTitle>
143
+ <FormattedMessage
144
+ id="cv-card-title"
145
+ defaultMessage="{count, plural, =0 {Content view environments} one {Content view environment} other {Content view environments}}"
146
+ values={{
147
+ count: contentViewEnvironments.length,
148
+ }}
149
+ />
150
+ </CardTitle>
81
151
  </FlexItem>
82
152
  </Flex>
83
153
  </FlexItem>
@@ -97,42 +167,14 @@ const HostContentViewDetails = ({
97
167
  </CardHeader>
98
168
  <CardBody>
99
169
  <Flex direction={{ default: 'column' }}>
100
- <Flex
101
- direction={{ default: 'row', sm: 'row' }}
102
- flexWrap={{ default: 'nowrap' }}
103
- alignItems={{ default: 'alignItemsCenter', sm: 'alignItemsCenter' }}
104
- >
105
- <ContentViewIcon composite={contentView.composite} style={{ marginRight: '2px' }} position="left" />
106
- <h3>{__('Content view')}</h3>
107
- </Flex>
108
- <Flex direction={{ default: 'row', sm: 'row' }} flexWrap={{ default: 'wrap' }}>
109
- <a style={{ fontSize: '14px' }} href={`/content_views/${contentView.id}`}>{contentView.name}</a>
110
- <Tooltip
111
- position="top"
112
- enableFlip
113
- entryDelay={400}
114
- content={<FormattedMessage
115
- id="cv-card-lce-tooltip"
116
- defaultMessage={__('Lifecycle environment: {lce}')}
117
- values={{
118
- lce: lifecycleEnvironment.name,
119
- }}
120
- />}
121
- >
122
- <Label isTruncated color="purple" href={`/lifecycle_environments/${lifecycleEnvironment.id}`}>{lifecycleEnvironment.name}</Label>
123
- </Tooltip>
124
- </Flex>
125
- </Flex>
126
- {!contentViewDefault &&
127
- <Flex direction={{ default: 'column' }}>
128
- <FlexItem>
129
- <h3>{__('Version in use')}</h3>
130
- <a style={{ fontSize: '14px' }} href={urlBuilder(`content_views/${contentView.id}/versions/${contentViewVersionId}`, '')}>
131
- {versionLabel}
132
- </a>
133
- </FlexItem>
170
+ {contentViewEnvironments.map(env => (
171
+ <ContentViewEnvironmentDisplay
172
+ key={`${env.lifecycle_environment.name}-${env.content_view.name}`}
173
+ contentView={env.content_view}
174
+ lifecycleEnvironment={env.lifecycle_environment}
175
+ />
176
+ ))}
134
177
  </Flex>
135
- }
136
178
  </CardBody>
137
179
  </Card>
138
180
  {hostId &&
@@ -144,6 +186,7 @@ const HostContentViewDetails = ({
144
186
  hostEnvId={hostEnvId}
145
187
  contentSourceId={contentSourceId}
146
188
  orgId={orgId}
189
+ multiEnv={contentViewEnvironments.length > 1}
147
190
  key={`cv-change-modal-${hostId}`}
148
191
  />
149
192
  }
@@ -151,6 +194,44 @@ const HostContentViewDetails = ({
151
194
  );
152
195
  };
153
196
 
197
+ HostContentViewDetails.propTypes = {
198
+ contentViewEnvironments: PropTypes.arrayOf(PropTypes.shape({
199
+ content_view: PropTypes.shape({
200
+ name: PropTypes.string,
201
+ id: PropTypes.number,
202
+ composite: PropTypes.bool,
203
+ }),
204
+ lifecycle_environment: PropTypes.shape({
205
+ name: PropTypes.string,
206
+ id: PropTypes.number,
207
+ }),
208
+ })),
209
+ hostId: PropTypes.number,
210
+ hostName: PropTypes.string,
211
+ orgId: PropTypes.number,
212
+ hostEnvId: PropTypes.number,
213
+ hostPermissions: PropTypes.shape({
214
+ edit_hosts: PropTypes.bool,
215
+ }),
216
+ permissions: PropTypes.shape({
217
+ view_content_views: PropTypes.bool,
218
+ view_lifecycle_environments: PropTypes.bool,
219
+ promote_or_remove_content_views_to_environments: PropTypes.bool,
220
+ }),
221
+ contentSourceId: PropTypes.number,
222
+ };
223
+
224
+ HostContentViewDetails.defaultProps = {
225
+ contentViewEnvironments: [],
226
+ hostId: null,
227
+ hostName: '',
228
+ orgId: null,
229
+ hostEnvId: null,
230
+ hostPermissions: {},
231
+ permissions: {},
232
+ contentSourceId: null,
233
+ };
234
+
154
235
  const ContentViewDetailsCard = ({ hostDetails }) => {
155
236
  if (hostIsRegistered({ hostDetails })
156
237
  && hostDetails.content_facet_attributes && hostDetails.organization_id) {
@@ -173,16 +254,6 @@ HostContentViewDetails.propTypes = {
173
254
  id: PropTypes.number,
174
255
  composite: PropTypes.bool,
175
256
  }).isRequired,
176
- contentViewDefault: PropTypes.bool,
177
- lifecycleEnvironment: PropTypes.shape({
178
- name: PropTypes.string,
179
- id: PropTypes.number,
180
- }).isRequired,
181
- contentViewVersionId: PropTypes.number.isRequired,
182
- contentViewVersion: PropTypes.string.isRequired,
183
- contentViewVersionLatest: PropTypes.bool.isRequired,
184
- id: PropTypes.number,
185
- name: PropTypes.string,
186
257
  hostId: PropTypes.number,
187
258
  hostName: PropTypes.string,
188
259
  contentSourceId: PropTypes.number,
@@ -199,14 +270,11 @@ HostContentViewDetails.propTypes = {
199
270
  };
200
271
 
201
272
  HostContentViewDetails.defaultProps = {
202
- id: null,
203
- name: '',
204
273
  hostEnvId: null,
205
274
  hostId: null,
206
275
  hostName: '',
207
276
  orgId: null,
208
277
  contentSourceId: null,
209
- contentViewDefault: false,
210
278
  hostPermissions: {},
211
279
  permissions: {},
212
280
  };
@@ -2,7 +2,7 @@ import { translate as __ } from 'foremanReact/common/I18n';
2
2
  import { API_OPERATIONS, put } from 'foremanReact/redux/API';
3
3
  import { errorToast } from '../../../../../scenes/Tasks/helpers';
4
4
  import { foremanApi } from '../../../../../services/api';
5
- import { runCommand } from '../../Tabs/RemoteExecutionActions';
5
+ import { uploadProfile } from '../../Tabs/RemoteExecutionActions';
6
6
  import HOST_CV_AND_ENV_KEY from './HostContentViewConstants';
7
7
 
8
8
  const updateHostContentViewAndEnvironment = (params, hostId, handleSuccess, handleError) => put({
@@ -17,9 +17,8 @@ const updateHostContentViewAndEnvironment = (params, hostId, handleSuccess, hand
17
17
  });
18
18
 
19
19
  export const runSubmanRepos =
20
- (hostname, handleSuccess) => runCommand({
20
+ (hostname, handleSuccess) => uploadProfile({
21
21
  hostname,
22
- command: 'subscription-manager repos',
23
22
  handleSuccess,
24
23
  });
25
24
 
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { render } from 'react-testing-lib-wrapper';
3
+ import * as hooks from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
3
4
  import ContentViewDetailsCard from '../ContentViewDetailsCard';
4
5
 
5
6
  const baseHostDetails = {
@@ -18,15 +19,36 @@ const baseHostDetails = {
18
19
  content_view_version_id: 1000,
19
20
  content_view_version: '1.0',
20
21
  content_view_version_latest: true,
22
+ content_view_environments: [
23
+ {
24
+ content_view: {
25
+ name: 'CV',
26
+ id: 100,
27
+ composite: false,
28
+ content_view_default: false,
29
+ content_view_version_id: 1000,
30
+ content_view_version: '1.0',
31
+ content_view_version_latest: true,
32
+ },
33
+ lifecycle_environment: {
34
+ name: 'ENV',
35
+ id: 300,
36
+ },
37
+ },
38
+ ],
21
39
  },
22
40
  subscription_facet_attributes: {
23
41
  uuid: '123',
24
42
  },
25
43
  };
26
44
 
45
+ beforeEach(() => {
46
+ jest.spyOn(hooks, 'useUrlParams').mockImplementation(() => ({}));
47
+ });
48
+
27
49
  test('shows content view details when host is registered', () => {
28
50
  const { getByText } = render(<ContentViewDetailsCard hostDetails={baseHostDetails} />);
29
- expect(getByText('Version 1.0 (latest)')).toBeInTheDocument();
51
+ expect(getByText('Version {version} (latest)')).toBeInTheDocument();
30
52
  });
31
53
 
32
54
 
@@ -36,7 +58,7 @@ test('does not show content view details when host is not registered', () => {
36
58
  subscription_facet_attributes: undefined,
37
59
  };
38
60
  const { queryByText } = render(<ContentViewDetailsCard hostDetails={hostDetails} />);
39
- expect(queryByText('Version 1.0')).toBeNull();
61
+ expect(queryByText('Version {version}')).toBeNull();
40
62
  });
41
63
 
42
64
 
@@ -45,12 +67,20 @@ test('shows when the CV in use is not the latest version', () => {
45
67
  ...baseHostDetails,
46
68
  content_facet_attributes: {
47
69
  ...baseHostDetails.content_facet_attributes,
48
- content_view_version_latest: false,
70
+ content_view_environments: [
71
+ {
72
+ content_view: {
73
+ ...baseHostDetails.content_facet_attributes.content_view_environments[0].content_view,
74
+ content_view_version_latest: false,
75
+ },
76
+ lifecycle_environment: baseHostDetails.content_facet_attributes.lifecycle_environment,
77
+ },
78
+ ],
49
79
  },
50
80
  };
51
81
  const { getByText, queryByText } = render(<ContentViewDetailsCard hostDetails={hostDetails} />);
52
- expect(getByText('Version 1.0')).toBeInTheDocument();
53
- expect(queryByText('Version 1.0 (latest)')).toBeNull();
82
+ expect(getByText('Version {version}')).toBeInTheDocument();
83
+ expect(queryByText('Version {version} (latest)')).toBeNull();
54
84
  });
55
85
 
56
86
  test('does not show version info when using Default Organization View', () => {
@@ -58,17 +88,21 @@ test('does not show version info when using Default Organization View', () => {
58
88
  ...baseHostDetails,
59
89
  content_facet_attributes: {
60
90
  ...baseHostDetails.content_facet_attributes,
61
- content_view:
91
+ content_view_environments: [
62
92
  {
63
- ...baseHostDetails.content_facet_attributes.content_view,
64
- content_view_default: true,
65
- name: 'Default Organization View',
93
+ content_view: {
94
+ ...baseHostDetails.content_facet_attributes.content_view_environments[0].content_view,
95
+ content_view_default: true,
96
+ name: 'Default Organization View',
97
+ },
98
+ lifecycle_environment: baseHostDetails.content_facet_attributes.lifecycle_environment,
66
99
  },
100
+ ],
67
101
  },
68
102
  };
69
103
 
70
104
  const { queryByText } = render(<ContentViewDetailsCard hostDetails={hostDetails} />);
71
105
  expect(queryByText('Default Organization View')).toBeInTheDocument();
72
- expect(queryByText('Version 1.0')).toBeNull();
106
+ expect(queryByText('Version {version}')).toBeNull();
73
107
  });
74
108