katello 4.13.0 → 4.14.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 (341) 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 -2
  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/repository_content_controller.rb +4 -3
  73. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +2 -4
  74. data/app/controllers/katello/remote_execution_controller.rb +53 -58
  75. data/app/helpers/katello/hosts_and_hostgroups_helper.rb +19 -2
  76. data/app/helpers/katello/katello_urls_helper.rb +1 -1
  77. data/app/lib/actions/katello/alternate_content_source/alternate_content_source_common.rb +1 -1
  78. data/app/lib/actions/katello/alternate_content_source/update.rb +2 -1
  79. data/app/lib/actions/katello/capsule_content/verify_checksum.rb +1 -2
  80. data/app/lib/actions/katello/content_view/publish.rb +1 -0
  81. data/app/lib/actions/katello/content_view_version/create_repos.rb +1 -0
  82. data/app/lib/actions/katello/content_view_version/incremental_update.rb +3 -2
  83. data/app/lib/actions/katello/environment/{publish_repositories.rb → publish_container_repositories.rb} +10 -8
  84. data/app/lib/actions/katello/foreman/content_update.rb +4 -6
  85. data/app/lib/actions/katello/host/hypervisors_update.rb +6 -4
  86. data/app/lib/actions/katello/repository/create.rb +4 -4
  87. data/app/lib/actions/katello/repository/discover.rb +11 -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/create_publication.rb +4 -0
  98. data/app/lib/actions/pulp3/repository/save_version.rb +3 -5
  99. data/app/lib/katello/concerns/base_template_scope_extensions.rb +5 -9
  100. data/app/lib/katello/errors.rb +1 -0
  101. data/app/lib/katello/http_resource.rb +1 -0
  102. data/app/lib/katello/lazy_accessor.rb +1 -1
  103. data/app/lib/katello/repo_discovery.rb +4 -190
  104. data/app/lib/katello/resources/candlepin/candlepin_ping.rb +0 -5
  105. data/app/lib/katello/resources/candlepin/owner.rb +1 -1
  106. data/app/lib/katello/resources/candlepin/pool.rb +1 -2
  107. data/app/lib/katello/resources/candlepin/upstream_job.rb +1 -1
  108. data/app/lib/katello/resources/cdn.rb +3 -2
  109. data/app/lib/katello/resources/discovery/container.rb +127 -0
  110. data/app/lib/katello/resources/discovery/yum.rb +95 -0
  111. data/app/lib/katello/util/cdn_var_substitutor.rb +5 -3
  112. data/app/lib/katello/util/data.rb +3 -2
  113. data/app/lib/katello/util/errata.rb +4 -3
  114. data/app/lib/katello/util/package.rb +3 -3
  115. data/app/lib/katello/util/path_with_substitutions.rb +1 -1
  116. data/app/lib/katello/util/report_table.rb +3 -2
  117. data/app/lib/katello/util/url_matcher.rb +1 -1
  118. data/app/lib/katello/validators/alternate_content_source_path_validator.rb +4 -3
  119. data/app/lib/katello/validators/alternate_content_source_products_validator.rb +5 -7
  120. data/app/lib/katello/validators/container_image_name_validator.rb +1 -1
  121. data/app/lib/katello/validators/katello_name_format_validator.rb +2 -2
  122. data/app/lib/katello/validators/no_trailing_space_validator.rb +2 -2
  123. data/app/lib/katello/validators/prior_validator.rb +2 -2
  124. data/app/lib/katello/validators/product_unique_attribute_validator.rb +2 -4
  125. data/app/models/katello/activation_key.rb +4 -6
  126. data/app/models/katello/alternate_content_source.rb +1 -1
  127. data/app/models/katello/authorization/host_tracer.rb +1 -2
  128. data/app/models/katello/candlepin/repository_mapper.rb +2 -2
  129. data/app/models/katello/concerns/host_managed_extensions.rb +41 -10
  130. data/app/models/katello/concerns/hostgroup_extensions.rb +2 -4
  131. data/app/models/katello/concerns/location_extensions.rb +2 -4
  132. data/app/models/katello/concerns/operatingsystem_extensions.rb +84 -16
  133. data/app/models/katello/concerns/smart_proxy_extensions.rb +4 -4
  134. data/app/models/katello/concerns/subscription_facet_host_extensions.rb +2 -0
  135. data/app/models/katello/content_view.rb +5 -1
  136. data/app/models/katello/content_view_environment.rb +19 -4
  137. data/app/models/katello/content_view_environment_content_facet.rb +11 -0
  138. data/app/models/katello/erratum.rb +1 -1
  139. data/app/models/katello/event.rb +1 -1
  140. data/app/models/katello/glue/provider.rb +1 -2
  141. data/app/models/katello/hash_util.rb +1 -1
  142. data/app/models/katello/host/content_facet.rb +16 -3
  143. data/app/models/katello/host/subscription_facet.rb +27 -4
  144. data/app/models/katello/host_collection.rb +12 -8
  145. data/app/models/katello/pool.rb +5 -1
  146. data/app/models/katello/product.rb +7 -4
  147. data/app/models/katello/provider.rb +1 -2
  148. data/app/models/katello/repository.rb +18 -4
  149. data/app/models/katello/root_repository.rb +29 -0
  150. data/app/models/katello/rpm.rb +2 -2
  151. data/app/models/katello/subscription_facet_pool.rb +1 -1
  152. data/app/models/katello/sync_plan.rb +5 -4
  153. data/app/models/katello/task_status.rb +18 -18
  154. data/app/presenters/katello/product_host_count_presenter.rb +10 -0
  155. data/app/services/katello/candlepin/consumer.rb +11 -11
  156. data/app/services/katello/candlepin/message_handler.rb +3 -2
  157. data/app/services/katello/content_unit_indexer.rb +6 -0
  158. data/app/services/katello/pulp3/alternate_content_source.rb +1 -3
  159. data/app/services/katello/pulp3/api/core.rb +1 -1
  160. data/app/services/katello/pulp3/api/docker.rb +10 -0
  161. data/app/services/katello/pulp3/content_view_version/export.rb +1 -0
  162. data/app/services/katello/pulp3/content_view_version/import.rb +6 -4
  163. data/app/services/katello/pulp3/content_view_version/importable_products.rb +1 -3
  164. data/app/services/katello/pulp3/repository/apt.rb +4 -16
  165. data/app/services/katello/pulp3/repository/yum.rb +9 -5
  166. data/app/services/katello/pulp3/repository.rb +2 -2
  167. data/app/services/katello/pulp3/repository_mirror.rb +2 -9
  168. data/app/services/katello/pulp3/task.rb +4 -2
  169. data/app/services/katello/registration_manager.rb +13 -3
  170. data/app/services/katello/repository_type.rb +1 -1
  171. data/app/services/katello/smart_proxy_helper.rb +1 -0
  172. data/app/views/dashboard/_host_collection_widget.html.erb +5 -4
  173. data/app/views/foreman/job_templates/install_errata.erb +2 -0
  174. data/app/views/foreman/job_templates/install_errata_-_katello_ansible_default.erb +2 -0
  175. data/app/views/foreman/job_templates/install_errata_by_search_query.erb +2 -0
  176. data/app/views/foreman/job_templates/install_errata_by_search_query_-_katello_ansible_default.erb +3 -1
  177. data/app/views/foreman/job_templates/install_packages_by_search_query_-_katello_ansible_default.erb +1 -1
  178. data/app/views/foreman/job_templates/remove_packages_by_search_query_-_katello_ansible_default.erb +2 -2
  179. data/app/views/foreman/job_templates/resolve_traces.erb +5 -1
  180. data/app/views/foreman/job_templates/update_packages_by_search_query_-_katello_ansible_default.erb +1 -1
  181. data/app/views/foreman/job_templates/upload_profile.erb +2 -0
  182. data/app/views/foreman/smart_proxies/_reclaim_space.html.erb +7 -5
  183. data/app/views/katello/api/v2/content_facet/base.json.rabl +18 -2
  184. data/app/views/katello/api/v2/packages/thindex.json.rabl +6 -0
  185. data/app/views/katello/api/v2/repositories/show.json.rabl +8 -8
  186. data/app/views/katello/api/v2/repository_sets/show.json.rabl +1 -1
  187. data/app/views/katello/api/v2/subscription_facet/base.json.rabl +1 -1
  188. data/app/views/katello/api/v2/subscriptions/index.json.rabl +1 -0
  189. data/app/views/katello/api/v2/subscriptions/show.json.rabl +1 -0
  190. data/app/views/overrides/activation_keys/_host_environment_select.html.erb +14 -11
  191. data/app/views/overrides/activation_keys/_host_synced_content_select.html.erb +4 -4
  192. data/config/initializers/monkeys.rb +0 -1
  193. data/config/routes/api/v2.rb +3 -1
  194. data/config/routes.rb +1 -3
  195. data/db/migrate/20160114200145_add_mirror_on_sync_to_repositories.rb +1 -0
  196. data/db/migrate/20160131182301_add_download_policy_to_katello_repositories.rb +1 -0
  197. data/db/migrate/20210119162528_delete_puppet_and_ostree_repos.rb +3 -0
  198. data/db/migrate/20240522165308_add_priority_to_content_view_environment_content_facet.rb +5 -0
  199. data/db/migrate/20240621121212_katello_repository_debs_id_bigint.rb +6 -0
  200. data/db/migrate/20240729192228_add_convert2rhel_to_host_facets.rb +9 -0
  201. data/db/seeds.d/102-organizations.rb +5 -7
  202. data/db/seeds.d/150-module_job_templates.rb +7 -9
  203. data/db/seeds.d/75-job_templates.rb +9 -16
  204. data/engines/bastion_katello/README.md +3 -0
  205. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-errata.controller.js +3 -3
  206. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/debs/details/views/deb-info.html +6 -6
  207. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/details/views/erratum-content-hosts.html +2 -2
  208. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +4 -4
  209. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/packages/details/views/package-info.html +6 -6
  210. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +31 -27
  211. data/engines/bastion_katello/lib/bastion_katello/engine.rb +2 -2
  212. data/lib/katello/engine.rb +1 -8
  213. data/lib/katello/permission_creator.rb +3 -2
  214. data/lib/katello/plugin.rb +31 -27
  215. data/lib/katello/repository_types/docker.rb +1 -0
  216. data/lib/katello/repository_types/yum.rb +1 -0
  217. data/lib/katello/tasks/clean_old_file_repos.rake +2 -4
  218. data/lib/katello/tasks/reset.rake +3 -4
  219. data/lib/katello/version.rb +1 -1
  220. data/lib/katello.rb +0 -4
  221. data/lib/monkeys/ar_postgres_evr_t.rb +2 -0
  222. data/locale/action_names.rb +1 -1
  223. data/locale/bn/LC_MESSAGES/katello.mo +0 -0
  224. data/locale/bn/katello.po +274 -22
  225. data/locale/bn_IN/katello.po +274 -22
  226. data/locale/ca/katello.po +274 -22
  227. data/locale/cs/katello.po +274 -22
  228. data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
  229. data/locale/cs_CZ/katello.po +275 -23
  230. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  231. data/locale/de/katello.po +280 -28
  232. data/locale/de_AT/katello.po +274 -22
  233. data/locale/de_DE/katello.po +274 -22
  234. data/locale/el/katello.po +274 -22
  235. data/locale/en/katello.po +274 -22
  236. data/locale/en_GB/katello.po +274 -22
  237. data/locale/en_US/katello.po +274 -22
  238. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  239. data/locale/es/katello.po +276 -24
  240. data/locale/et_EE/katello.po +274 -22
  241. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  242. data/locale/fr/katello.po +283 -31
  243. data/locale/gl/katello.po +274 -22
  244. data/locale/gu/katello.po +274 -22
  245. data/locale/he_IL/katello.po +274 -22
  246. data/locale/hi/katello.po +274 -22
  247. data/locale/id/katello.po +274 -22
  248. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  249. data/locale/it/katello.po +274 -22
  250. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  251. data/locale/ja/katello.po +283 -31
  252. data/locale/ka/LC_MESSAGES/katello.mo +0 -0
  253. data/locale/ka/katello.po +280 -28
  254. data/locale/katello.pot +1001 -527
  255. data/locale/kn/katello.po +274 -22
  256. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  257. data/locale/ko/katello.po +274 -22
  258. data/locale/ml_IN/katello.po +274 -22
  259. data/locale/mr/katello.po +274 -22
  260. data/locale/nl_NL/katello.po +274 -22
  261. data/locale/or/katello.po +274 -22
  262. data/locale/pa/katello.po +274 -22
  263. data/locale/pl/katello.po +274 -22
  264. data/locale/pl_PL/katello.po +274 -22
  265. data/locale/pt/katello.po +274 -22
  266. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  267. data/locale/pt_BR/katello.po +276 -24
  268. data/locale/ro/katello.po +274 -22
  269. data/locale/ro_RO/katello.po +274 -22
  270. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  271. data/locale/ru/katello.po +274 -22
  272. data/locale/sl/katello.po +274 -22
  273. data/locale/sv_SE/katello.po +274 -22
  274. data/locale/ta/LC_MESSAGES/katello.mo +0 -0
  275. data/locale/ta/katello.po +274 -22
  276. data/locale/ta_IN/katello.po +274 -22
  277. data/locale/te/katello.po +274 -22
  278. data/locale/tr/katello.po +274 -22
  279. data/locale/vi/katello.po +274 -22
  280. data/locale/vi_VN/katello.po +274 -22
  281. data/locale/zh/katello.po +274 -22
  282. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  283. data/locale/zh_CN/katello.po +283 -31
  284. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  285. data/locale/zh_TW/katello.po +274 -22
  286. data/webpack/ForemanColumnExtensions/index.js +44 -1
  287. data/webpack/components/Table/TableWrapper.js +6 -0
  288. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ChangeHostCVModal.js +24 -3
  289. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard.js +124 -56
  290. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/HostContentViewActions.js +2 -3
  291. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/__tests__/contentViewDetailsCard.test.js +44 -10
  292. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +75 -31
  293. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionConstants.js +1 -0
  294. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionHooks.js +1 -1
  295. data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +22 -7
  296. data/webpack/components/extensions/Hosts/ActionsBar/ActionsBar.scss +14 -0
  297. data/webpack/components/extensions/Hosts/ActionsBar/index.js +82 -23
  298. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCVModal/index.js +5 -2
  299. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/02_BulkErrataTable.js +171 -0
  300. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/04_Review.js +160 -0
  301. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/04_ReviewFooter.js +99 -0
  302. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/BulkErrataWizard.js +157 -0
  303. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/index.js +24 -0
  304. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/02_BulkPackagesTable.js +157 -0
  305. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/04_Review.js +168 -0
  306. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/04_ReviewFooter.js +141 -0
  307. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/BulkPackagesWizard.js +252 -0
  308. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/index.js +24 -0
  309. data/webpack/components/extensions/Hosts/BulkActions/HostReview.js +176 -0
  310. data/webpack/components/extensions/Hosts/TableRowActions/index.js +17 -0
  311. data/webpack/global_index.js +11 -3
  312. data/webpack/redux/actions/RedHatRepositories/repositorySetRepositories.js +5 -6
  313. data/webpack/redux/reducers/RedHatRepositories/__tests__/repositorySetRepositories.test.js +1 -1
  314. data/webpack/redux/reducers/RedHatRepositories/repositorySetRepositories.js +1 -1
  315. data/webpack/scenes/ContentViews/Copy/CopyContentViewModal.js +2 -1
  316. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +2 -1
  317. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +2 -1
  318. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +2 -1
  319. data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +2 -1
  320. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +2 -2
  321. data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +2 -1
  322. data/webpack/scenes/ContentViews/Publish/CVPublishReview.js +3 -2
  323. data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +2 -1
  324. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +2 -1
  325. data/webpack/scenes/ContentViews/components/CVBreadCrumb.js +2 -1
  326. data/webpack/scenes/ContentViews/components/ContentViewSelect/ContentViewSelectOption.js +2 -2
  327. data/webpack/scenes/Subscriptions/Details/SubscriptionAttributes.js +1 -0
  328. data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailInfo.test.js.snap +10 -0
  329. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +6 -0
  330. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +2 -0
  331. data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +14 -0
  332. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableHelpers.js +1 -0
  333. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableSchema.js +10 -0
  334. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.fixtures.js +1 -0
  335. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/__snapshots__/SubscriptionsToolbar.test.js.snap +10 -0
  336. data/webpack/scenes/Tasks/helpers.js +1 -1
  337. metadata +49 -29
  338. data/app/assets/javascripts/katello/containers/container.js +0 -304
  339. data/db/migrate/20240531193030_remove_sha1_repository_checksum_type.rb +0 -10
  340. data/lib/monkeys/anemone.rb +0 -33
  341. data/webpack/utils/useKatelloDocUrl.js +0 -18
@@ -0,0 +1,168 @@
1
+ import React, { useContext, useState } from 'react';
2
+ import { translate as __ } from 'foremanReact/common/I18n';
3
+ import { FormattedMessage } from 'react-intl';
4
+ import { TreeView, Button, Text, TextContent, TextVariants, Flex, FlexItem, Dropdown, DropdownItem, DropdownToggle } from '@patternfly/react-core';
5
+ import { useWizardContext } from '@patternfly/react-core/next';
6
+ import { CaretDownIcon } from '@patternfly/react-icons';
7
+ import { BulkPackagesWizardContext, UPGRADE_ALL, INSTALL, REMOVE, UPGRADE } from './BulkPackagesWizard';
8
+
9
+ export const dropdownOptions = [
10
+ __('via remote execution'),
11
+ __('via customized remote execution'),
12
+ ];
13
+
14
+ export const BulkPackagesReview = () => {
15
+ const { goToStepById } = useWizardContext();
16
+ const {
17
+ selectedAction,
18
+ finishButtonText,
19
+ selectedRexOption,
20
+ setSelectedRexOption,
21
+ finishButtonLoading,
22
+ packagesBulkSelect: {
23
+ selectedResults: selectedPackageResults,
24
+ selectedCount: currentSelectedPackagesCount,
25
+ },
26
+ hostsBulkSelect: {
27
+ selectedCount: currentSelectedHostsCount,
28
+ },
29
+ } = useContext(BulkPackagesWizardContext);
30
+
31
+ const [isDropdownOpen, setIsDropdownOpen] = useState(false);
32
+ const toggleDropdownOpen = () => setIsDropdownOpen(prev => !prev);
33
+ const handleSelect = () => {
34
+ setIsDropdownOpen(false);
35
+ };
36
+
37
+ const dropdownItems = dropdownOptions.map(text => (
38
+ <DropdownItem key={`option_${text}`} ouiaId={`option_${text}`} onClick={() => setSelectedRexOption(text)}>{text}</DropdownItem>
39
+ ));
40
+
41
+ const packageActionsDescriptions = {
42
+ [INSTALL]: __('Packages to install'),
43
+ [REMOVE]: __('Packages to be removed'),
44
+ [UPGRADE]: __('Packages to be updated'),
45
+ [UPGRADE_ALL]: __('Packages to be updated'),
46
+ };
47
+
48
+ const treeViewTitle = packageActionsDescriptions[selectedAction];
49
+ const treeViewData = [
50
+ {
51
+ name: treeViewTitle,
52
+ id: 'packages-treeview-title',
53
+ customBadgeContent: selectedAction === UPGRADE_ALL ? 'All' : currentSelectedPackagesCount,
54
+ children: selectedAction === UPGRADE_ALL ? undefined :
55
+ selectedPackageResults.map(({ id, name }) => ({
56
+ name,
57
+ id,
58
+ key: id,
59
+ })),
60
+ action: (
61
+ <Button
62
+ ouiaId="link-to-packages-wizard-step-2"
63
+ variant="link"
64
+ type="button"
65
+ aria-label="Edit packages list"
66
+ onClick={() => goToStepById(selectedAction === UPGRADE_ALL ? 'mpw-step-1' : 'mpw-step-2')}
67
+ >
68
+ {__('Edit')}
69
+ </Button>
70
+ ),
71
+ actionProps: {
72
+ 'aria-label': 'Edit packages list',
73
+ },
74
+ },
75
+ ];
76
+
77
+ const hostTreeViewData = [
78
+ {
79
+ name: __('Hosts'),
80
+ id: 'packages-host-treeview-title',
81
+ customBadgeContent: currentSelectedHostsCount,
82
+ expandedIcon: null,
83
+ action: (
84
+ <Button
85
+ ouiaId="link-to-packages-wizard-step-3"
86
+ variant="link"
87
+ type="button"
88
+ aria-label="Edit host selection"
89
+ onClick={() => goToStepById('mpw-step-3')}
90
+ >
91
+ {__('Edit')}
92
+ </Button>
93
+ ),
94
+ actionProps: {
95
+ 'aria-label': 'Edit host selection',
96
+ },
97
+ },
98
+ ];
99
+
100
+ return (
101
+ <>
102
+ <TextContent>
103
+ <Text ouiaId="mpw-step-3-header" component={TextVariants.h3}>
104
+ {__('Review')}
105
+ </Text>
106
+ <Text ouiaId="mpw-step-3-content" component={TextVariants.p}>
107
+ <FormattedMessage
108
+ id="bulkPackagesReviewContent"
109
+ defaultMessage={__('Review and then click {submitBtnText}.')}
110
+ values={{
111
+ submitBtnText: <strong>{finishButtonText}</strong>,
112
+ }}
113
+ />
114
+ </Text>
115
+ </TextContent>
116
+ <div style={{ width: '70%', maxHeight: '50%', marginBottom: '2rem' }}>
117
+ <TreeView
118
+ data={treeViewData}
119
+ aria-label={treeViewTitle}
120
+ hasBadges
121
+ />
122
+ <TreeView
123
+ data={hostTreeViewData}
124
+ aria-label={__('Hosts')}
125
+ hasBadges
126
+ />
127
+ </div>
128
+ <Flex direction={{ default: 'row' }}>
129
+ <FlexItem>
130
+ <TextContent>
131
+ <Text ouiaId="mpw-step-3-content" component={TextVariants.p}>
132
+ <FormattedMessage
133
+ id="bulkPackagesReviewContent"
134
+ defaultMessage={__('Selected packages will be {submitAction} on {hostCount} hosts')}
135
+ values={{
136
+ submitAction: selectedAction === 'install' ? __('installed') : __('updated'),
137
+ hostCount: currentSelectedHostsCount,
138
+ }}
139
+ />
140
+ </Text>
141
+ </TextContent>
142
+ </FlexItem>
143
+ <FlexItem>
144
+ <Dropdown
145
+ ouiaId="bulk-packages-wizard-dropdown"
146
+ toggle={
147
+ <DropdownToggle
148
+ id="toggle-bulk-packages-wizard-dropdown"
149
+ ouiaId="bulk-packages-wizard-dropdown-toggle"
150
+ onToggle={toggleDropdownOpen}
151
+ toggleIndicator={CaretDownIcon}
152
+ isDisabled={finishButtonLoading}
153
+ >
154
+ {selectedRexOption}
155
+ </DropdownToggle>
156
+ }
157
+ onSelect={handleSelect}
158
+ isOpen={isDropdownOpen}
159
+ dropdownItems={dropdownItems}
160
+ menuAppendTo="parent"
161
+ />
162
+ </FlexItem>
163
+ </Flex>
164
+ </>
165
+ );
166
+ };
167
+
168
+ export default BulkPackagesReview;
@@ -0,0 +1,141 @@
1
+ import React, { useContext } from 'react';
2
+ import { translate as __ } from 'foremanReact/common/I18n';
3
+ import { Button } from '@patternfly/react-core';
4
+ import { WizardFooterWrapper, useWizardContext } from '@patternfly/react-core/next';
5
+ import { BulkPackagesWizardContext, INSTALL, UPGRADE, UPGRADE_ALL, REMOVE } from './BulkPackagesWizard';
6
+ import { dropdownOptions } from './04_Review';
7
+ import { katelloPackageInstallBySearchUrl, packagesUpdateUrl, katelloPackageRemoveBySearchUrl } from '../../../HostDetails/Tabs/customizedRexUrlHelpers';
8
+ import { installPackageBySearch, updatePackages, removePackagesBySearch } from '../../../HostDetails/Tabs/RemoteExecutionActions';
9
+ import { useRexJobPolling } from '../../../HostDetails/Tabs/RemoteExecutionHooks';
10
+
11
+ export const BulkPackagesReviewFooter = () => {
12
+ const {
13
+ finishButtonText,
14
+ finishButtonLoading,
15
+ setFinishButtonLoading,
16
+ selectedRexOption,
17
+ closeModal,
18
+ packagesBulkSelect: {
19
+ fetchBulkParams: getPackagesBulkParams,
20
+ selectedCount: packagesSelectedCount,
21
+ },
22
+ hostsBulkSelect: {
23
+ fetchBulkParams: getHostsBulkParams,
24
+ selectedCount: hostsSelectedCount,
25
+ },
26
+ selectedAction,
27
+ } = useContext(BulkPackagesWizardContext);
28
+
29
+ const { goToStepById } = useWizardContext();
30
+
31
+ let packagesBulkParams = '';
32
+ let hostsBulkParams = '';
33
+ if (packagesSelectedCount) packagesBulkParams = getPackagesBulkParams();
34
+ if (hostsSelectedCount) hostsBulkParams = getHostsBulkParams();
35
+
36
+ // Customized REX
37
+ const [viaRex] = dropdownOptions;
38
+ const packageRexUrls = {
39
+ [INSTALL]: katelloPackageInstallBySearchUrl,
40
+ [REMOVE]: katelloPackageRemoveBySearchUrl,
41
+ [UPGRADE]: packagesUpdateUrl,
42
+ [UPGRADE_ALL]: packagesUpdateUrl,
43
+ };
44
+ const getCustomizedRexUrl = packageRexUrls[selectedAction];
45
+ const customizedRexUrl = getCustomizedRexUrl({
46
+ hostSearch: hostsBulkParams,
47
+ search: selectedAction === UPGRADE_ALL ? '' : packagesBulkParams,
48
+ });
49
+
50
+ // REX
51
+ const packageBulkUpgradeAction = () => updatePackages({
52
+ hostSearch: hostsBulkParams,
53
+ search: selectedAction === UPGRADE_ALL ? '' : packagesBulkParams,
54
+ descriptionFormat: selectedAction === UPGRADE_ALL ? __('Upgrade all packages') : undefined,
55
+ });
56
+
57
+ const {
58
+ triggerJobStart: triggerBulkPackageUpgrade,
59
+ isPolling: isBulkUpgradeInProgress,
60
+ } = useRexJobPolling(packageBulkUpgradeAction);
61
+
62
+ const packageBulkInstallAction = () => installPackageBySearch({
63
+ hostSearch: hostsBulkParams,
64
+ search: packagesBulkParams,
65
+ });
66
+
67
+ const packageBulkRemoveAction = () => removePackagesBySearch({
68
+ hostSearch: hostsBulkParams,
69
+ search: packagesBulkParams,
70
+ });
71
+
72
+ const {
73
+ triggerJobStart: triggerBulkPackageRemove,
74
+ isPolling: isBulkRemoveInProgress,
75
+ } = useRexJobPolling(packageBulkRemoveAction);
76
+
77
+ const {
78
+ triggerJobStart: triggerBulkPackageInstall,
79
+ isPolling: isBulkInstallInProgress,
80
+ } = useRexJobPolling(packageBulkInstallAction);
81
+
82
+ const handleFinishButtonClick = () => {
83
+ setFinishButtonLoading(true);
84
+ if ([UPGRADE_ALL, UPGRADE].includes(selectedAction)) {
85
+ triggerBulkPackageUpgrade();
86
+ }
87
+ if (selectedAction === INSTALL) {
88
+ triggerBulkPackageInstall();
89
+ }
90
+ if (selectedAction === REMOVE) {
91
+ triggerBulkPackageRemove();
92
+ }
93
+ closeModal();
94
+ };
95
+
96
+ const isBulkActionInProgress = isBulkUpgradeInProgress ||
97
+ isBulkInstallInProgress || isBulkRemoveInProgress;
98
+
99
+ const finishButton = (selectedRexOption === viaRex) ?
100
+ (
101
+ <Button
102
+ key="bulk-packages-wizard-finish-button"
103
+ ouiaId="bulk-packages-wizard-finish-button-via-rex"
104
+ type="submit"
105
+ variant="primary"
106
+ className="pf-m-progress"
107
+ isLoading={finishButtonLoading || isBulkActionInProgress}
108
+ isDisabled={finishButtonLoading || isBulkActionInProgress}
109
+ onClick={handleFinishButtonClick}
110
+ >
111
+ {finishButtonText}
112
+ </Button>
113
+ ) : (
114
+ <Button
115
+ key="bulk-packages-wizard-finish-button"
116
+ ouiaId="bulk-packages-wizard-finish-button-via-customized-rex"
117
+ component="a"
118
+ isLoading={finishButtonLoading}
119
+ isDisabled={finishButtonLoading}
120
+ onClick={() => setFinishButtonLoading(true)}
121
+ variant="primary"
122
+ href={customizedRexUrl}
123
+ >
124
+ {finishButtonText}
125
+ </Button>
126
+ );
127
+
128
+ return (
129
+ <WizardFooterWrapper>
130
+ {finishButton}
131
+ <Button variant="secondary" onClick={() => goToStepById('mpw-step-3')} isDisabled={finishButtonLoading} ouiaId="bulk-pkg-wiz-step4-back">
132
+ {__('Back')}
133
+ </Button>
134
+ <Button variant="link" onClick={closeModal} isDisabled={finishButtonLoading} ouiaId="bulk-pkg-wiz-step4-cancel">
135
+ {__('Cancel')}
136
+ </Button>
137
+ </WizardFooterWrapper>
138
+ );
139
+ };
140
+
141
+ export default BulkPackagesReviewFooter;
@@ -0,0 +1,252 @@
1
+ import React, { useState, createContext, useContext } from 'react';
2
+ import { Radio, Text, TextVariants, TextContent, Alert } from '@patternfly/react-core';
3
+ import { Wizard, WizardHeader, WizardStep } from '@patternfly/react-core/next';
4
+ import { translate as __ } from 'foremanReact/common/I18n';
5
+ import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
6
+ import { useBulkSelect } from 'foremanReact/components/PF4/TableIndexPage/Table/TableHooks';
7
+ import { ForemanActionsBarContext } from 'foremanReact/components/HostDetails/ActionsBar';
8
+ import { useTableIndexAPIResponse } from 'foremanReact/components/PF4/TableIndexPage/Table/TableIndexHooks';
9
+ import { STATUS } from 'foremanReact/constants';
10
+ import { HOSTS_API_PATH } from 'foremanReact/routes/Hosts/constants';
11
+ import HostReview from '../HostReview';
12
+ import { BulkPackagesReview, dropdownOptions } from './04_Review';
13
+ import { BulkPackagesUpgradeTable, BulkPackagesInstallTable, BulkPackagesRemoveTable } from './02_BulkPackagesTable';
14
+ import { BulkPackagesReviewFooter } from './04_ReviewFooter';
15
+ import katelloApi from '../../../../../services/api';
16
+
17
+ export const UPGRADE_ALL = 'upgradeAll';
18
+ export const UPGRADE = 'upgrade';
19
+ export const INSTALL = 'install';
20
+ export const REMOVE = 'remove';
21
+
22
+ export const BulkPackagesWizardContext = createContext({});
23
+
24
+ export const useHostsBulkSelect = ({ initialSelectedHosts, modalIsOpen }) => {
25
+ const defaultParams = { search: initialSelectedHosts };
26
+ const apiOptions = { key: 'HOST_REVIEW' };
27
+ const replacementResponse = !modalIsOpen ? { response: {} } : false;
28
+ const hostsResponse = useTableIndexAPIResponse({
29
+ replacementResponse, // don't fetch data if modal is closed
30
+ apiUrl: `${HOSTS_API_PATH}?per_page=7`,
31
+ apiOptions,
32
+ defaultParams,
33
+ });
34
+
35
+ const {
36
+ response: {
37
+ results: hostsResults,
38
+ ...hostsMetadata
39
+ },
40
+ } = hostsResponse;
41
+
42
+ const { total, page, subtotal } = hostsMetadata;
43
+
44
+ return {
45
+ hostsBulkSelect: useBulkSelect({
46
+ results: hostsResults,
47
+ metadata: { total, page, selectable: subtotal },
48
+ initialSearchQuery: initialSelectedHosts,
49
+ initialSelectAllMode: true,
50
+ }),
51
+ hostsResponse,
52
+ hostsMetadata,
53
+ };
54
+ };
55
+
56
+ export const getPackagesUrl = selectedAction =>
57
+ `${katelloApi.getApiUrl('/packages/thindex')}?per_page=7&include_permissions=true&packages_restrict_upgradable=${selectedAction === 'upgrade'}`;
58
+
59
+ const BulkPackagesWizard = () => {
60
+ const { modalOpen, setModalClosed: closeModal } = useForemanModal({ id: 'bulk-packages-wizard' });
61
+
62
+
63
+ const [selectedAction, setSelectedAction] = useState(UPGRADE_ALL);
64
+
65
+ const { selectedCount: initialSelectedHostCount, fetchBulkParams }
66
+ = useContext(ForemanActionsBarContext);
67
+
68
+ const [shouldValidateStep2, setShouldValidateStep2] = useState(false);
69
+ const [shouldValidateStep3, setShouldValidateStep3] = useState(false);
70
+ const [finishButtonLoading, setFinishButtonLoading] = useState(false);
71
+ const [selectedRexOption, setSelectedRexOption] = useState(dropdownOptions[0]);
72
+ const packageActionsNames = {
73
+ install: __('Install packages'), remove: __('Remove packages'), upgrade: __('Upgrade packages'), upgradeAll: __('Upgrade packages'),
74
+ };
75
+ const packageActions = () => {
76
+ switch (selectedAction) {
77
+ case INSTALL:
78
+ return (
79
+ <BulkPackagesInstallTable modalIsOpen={modalOpen} />
80
+ );
81
+ case REMOVE:
82
+ return (
83
+ <BulkPackagesRemoveTable modalIsOpen={modalOpen} />
84
+ );
85
+ default:
86
+ return (
87
+ <BulkPackagesUpgradeTable modalIsOpen={modalOpen} />
88
+ );
89
+ }
90
+ };
91
+
92
+ const finishButtonTextValues = {
93
+ install: __('Install'), remove: __('Remove'), upgrade: __('Upgrade'), upgradeAll: __('Upgrade'),
94
+ };
95
+ const finishButtonText = finishButtonTextValues[selectedAction];
96
+ const PACKAGES_URL = getPackagesUrl(selectedAction);
97
+ const apiOptions = { key: 'BULK_HOST_PACKAGES' };
98
+ const replacementResponse = !modalOpen ? { response: {} } : false;
99
+ const packagesResponse = useTableIndexAPIResponse({
100
+ replacementResponse, // don't fetch data if modal is closed
101
+ apiUrl: PACKAGES_URL,
102
+ apiOptions,
103
+ });
104
+
105
+ const {
106
+ response: {
107
+ results: packagesResults,
108
+ ...packagesMetadata
109
+ },
110
+ status: packagesStatus,
111
+ } = packagesResponse;
112
+
113
+ const { total, page, subtotal } = packagesMetadata;
114
+
115
+ const packagesBulkSelect = useBulkSelect({
116
+ results: packagesResults,
117
+ metadata: { total, page, selectable: subtotal },
118
+ idColumn: 'name',
119
+ });
120
+
121
+ const initialSelectedHosts = fetchBulkParams();
122
+
123
+ const hostsBulkSelect =
124
+ useHostsBulkSelect({ initialSelectedHosts, modalIsOpen: modalOpen });
125
+
126
+ // eslint-disable-next-line no-restricted-globals
127
+ const selectionIsValid = count => count > 0 || isNaN(count);
128
+ const packagesResultsPresent = packagesResults?.length > 0;
129
+ const packageSelectionIsValid =
130
+ selectionIsValid(packagesBulkSelect.selectedCount) || selectedAction === UPGRADE_ALL;
131
+ const hostSelectionIsValid = selectionIsValid(hostsBulkSelect.hostsBulkSelect.selectedCount);
132
+ let step2Valid = shouldValidateStep2 ? packageSelectionIsValid : true;
133
+ if (!packagesResultsPresent) step2Valid = false;
134
+ const step3Valid = shouldValidateStep3 ? hostSelectionIsValid : true;
135
+ const step4Valid = hostSelectionIsValid && packageSelectionIsValid;
136
+
137
+ const bulkPackagesWizardContextData = {
138
+ selectedAction,
139
+ finishButtonText,
140
+ initialSelectedHostCount,
141
+ setShouldValidateStep2,
142
+ finishButtonLoading,
143
+ setFinishButtonLoading,
144
+ selectedRexOption,
145
+ setSelectedRexOption,
146
+ closeModal,
147
+ packagesBulkSelect,
148
+ packagesResults,
149
+ packagesMetadata,
150
+ packagesResponse,
151
+ hostsBulkSelect: hostsBulkSelect.hostsBulkSelect,
152
+ };
153
+ return (
154
+ <BulkPackagesWizardContext.Provider value={bulkPackagesWizardContextData}>
155
+ <Wizard
156
+ header={<WizardHeader title={__('Manage packages')} onClose={closeModal} />}
157
+ >
158
+ <WizardStep
159
+ name={__('Select action')}
160
+ id="mpw-step-1"
161
+ footer={{ onClose: closeModal }}
162
+ >
163
+ <TextContent>
164
+ <Text ouiaId="mpw-step-1-header" component={TextVariants.h2}>
165
+ {__('Select action')}
166
+ </Text>
167
+ <Text ouiaId="mpw-step-1-content" component={TextVariants.p}>
168
+ {__('To manage packages, select an action.')}
169
+ </Text>
170
+ </TextContent>
171
+ {packagesStatus === STATUS.RESOLVED && !packagesResultsPresent && (
172
+ <Alert
173
+ ouiaId="no-packages-found-alert"
174
+ variant="info"
175
+ isInline
176
+ title={__('No upgradable packages found.')}
177
+ style={{ marginBottom: '1rem' }}
178
+ />
179
+ )}
180
+ <div style={{ marginBottom: '1rem' }} />
181
+ <div style={{ marginLeft: '1rem' }}>
182
+ <Radio
183
+ isChecked={selectedAction === UPGRADE_ALL}
184
+ name="packageActionRadioGroup"
185
+ onChange={() => setSelectedAction(UPGRADE_ALL)}
186
+ label={__('Upgrade all packages')}
187
+ id="r1-upgrade-all-packages"
188
+ ouiaId="r1-upgrade-all-packages"
189
+ />
190
+ <Radio
191
+ isChecked={selectedAction === UPGRADE}
192
+ name="packageActionRadioGroup"
193
+ onChange={() => setSelectedAction(UPGRADE)}
194
+ label={__('Upgrade packages')}
195
+ id="r2-upgrade-packages"
196
+ ouiaId="r2-upgrade-packages"
197
+ />
198
+ <Radio
199
+ isChecked={selectedAction === INSTALL}
200
+ name="packageActionRadioGroup"
201
+ onChange={() => setSelectedAction(INSTALL)}
202
+ label={__('Install packages')}
203
+ id="r3-install-packages"
204
+ ouiaId="r3-install-packages"
205
+ />
206
+ <Radio
207
+ isChecked={selectedAction === REMOVE}
208
+ name="packageActionRadioGroup"
209
+ onChange={() => setSelectedAction(REMOVE)}
210
+ label={__('Remove packages')}
211
+ id="r4-remove-packages"
212
+ ouiaId="r4-remove-packages"
213
+ />
214
+ </div>
215
+ </WizardStep>
216
+ <WizardStep
217
+ name={packageActionsNames[selectedAction]}
218
+ id="mpw-step-2"
219
+ isHidden={selectedAction === UPGRADE_ALL}
220
+ footer={{ isNextDisabled: !step2Valid, onClose: closeModal }}
221
+ status={step2Valid ? 'default' : 'error'}
222
+ >
223
+ {packageActions()}
224
+ </WizardStep>
225
+ <WizardStep
226
+ name={__('Review hosts')}
227
+ id="mpw-step-3"
228
+ status={step3Valid ? 'default' : 'error'}
229
+ footer={{ isNextDisabled: !step4Valid || !packagesResultsPresent, onClose: closeModal }}
230
+ >
231
+ <HostReview
232
+ key={modalOpen}
233
+ selectedAction={selectedAction}
234
+ hostsBulkSelect={hostsBulkSelect}
235
+ initialSelectedHosts={initialSelectedHosts}
236
+ setShouldValidateStep={setShouldValidateStep3}
237
+ />
238
+ </WizardStep>
239
+ <WizardStep
240
+ name={__('Review')}
241
+ id="mpw-review-step"
242
+ footer={<BulkPackagesReviewFooter />}
243
+ isDisabled={!step4Valid || !packagesResultsPresent}
244
+ >
245
+ <BulkPackagesReview />
246
+ </WizardStep>
247
+ </Wizard>
248
+ </BulkPackagesWizardContext.Provider>
249
+ );
250
+ };
251
+
252
+ export default BulkPackagesWizard;
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { Modal, ModalVariant } from '@patternfly/react-core';
3
+ import { useForemanModal } from 'foremanReact/components/ForemanModal/ForemanModalHooks';
4
+ import BulkPackagesWizard from './BulkPackagesWizard';
5
+
6
+ const BulkPackagesWizardModal = () => {
7
+ const { modalOpen: isOpen } = useForemanModal({ id: 'bulk-packages-wizard' });
8
+
9
+ return (
10
+ <Modal
11
+ width="60%"
12
+ ouiaId="bulk-packages-wizard-modal"
13
+ isOpen={isOpen}
14
+ showClose={false}
15
+ aria-label="Wizard modal"
16
+ hasNoBodyWrapper
17
+ variant={ModalVariant.medium}
18
+ >
19
+ <BulkPackagesWizard />
20
+ </Modal>
21
+ );
22
+ };
23
+
24
+ export default BulkPackagesWizardModal;