katello 4.4.1 → 4.5.0

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 (488) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/hosts/activation_key_edit.js +9 -2
  3. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +3 -0
  4. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +5 -1
  5. data/app/controllers/katello/api/v2/alternate_content_sources_bulk_actions_controller.rb +44 -0
  6. data/app/controllers/katello/api/v2/alternate_content_sources_controller.rb +121 -0
  7. data/app/controllers/katello/api/v2/content_export_incrementals_controller.rb +39 -3
  8. data/app/controllers/katello/api/v2/content_exports_controller.rb +19 -0
  9. data/app/controllers/katello/api/v2/content_imports_controller.rb +13 -16
  10. data/app/controllers/katello/api/v2/content_view_components_controller.rb +1 -1
  11. data/app/controllers/katello/api/v2/content_view_repositories_controller.rb +1 -1
  12. data/app/controllers/katello/api/v2/content_view_versions_controller.rb +0 -12
  13. data/app/controllers/katello/api/v2/content_views_controller.rb +13 -0
  14. data/app/controllers/katello/api/v2/environments_controller.rb +1 -1
  15. data/app/controllers/katello/api/v2/host_module_streams_controller.rb +8 -2
  16. data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +25 -3
  17. data/app/controllers/katello/api/v2/organizations_controller.rb +4 -2
  18. data/app/controllers/katello/api/v2/repositories_bulk_actions_controller.rb +1 -1
  19. data/app/controllers/katello/api/v2/repositories_controller.rb +1 -1
  20. data/app/controllers/katello/api/v2/repository_sets_controller.rb +40 -7
  21. data/app/controllers/katello/api/v2/subscriptions_controller.rb +2 -2
  22. data/app/controllers/katello/concerns/api/v2/hosts_controller_extensions.rb +1 -1
  23. data/app/helpers/katello/concerns/smart_proxy_helper_extensions.rb +4 -0
  24. data/app/helpers/katello/hosts_and_hostgroups_helper.rb +21 -3
  25. data/app/lib/actions/katello/alternate_content_source/create.rb +24 -0
  26. data/app/lib/actions/katello/alternate_content_source/destroy.rb +27 -0
  27. data/app/lib/actions/katello/alternate_content_source/refresh.rb +27 -0
  28. data/app/lib/actions/katello/alternate_content_source/update.rb +41 -0
  29. data/app/lib/actions/katello/cdn_configuration/update.rb +3 -3
  30. data/app/lib/actions/katello/content_view/destroy.rb +2 -1
  31. data/app/lib/actions/katello/content_view/incremental_updates.rb +7 -3
  32. data/app/lib/actions/katello/content_view/publish.rb +8 -10
  33. data/app/lib/actions/katello/content_view_version/auto_create_products.rb +4 -4
  34. data/app/lib/actions/katello/content_view_version/auto_create_redhat_repositories.rb +6 -4
  35. data/app/lib/actions/katello/content_view_version/auto_create_repositories.rb +6 -4
  36. data/app/lib/actions/katello/content_view_version/import.rb +25 -22
  37. data/app/lib/actions/katello/content_view_version/import_library.rb +0 -1
  38. data/app/lib/actions/katello/content_view_version/import_repository.rb +21 -0
  39. data/app/lib/actions/katello/content_view_version/incremental_update.rb +85 -93
  40. data/app/lib/actions/katello/content_view_version/reset_content_view_repositories_from_metadata.rb +2 -2
  41. data/app/lib/actions/katello/organization/manifest_refresh.rb +1 -1
  42. data/app/lib/actions/katello/product/content_create.rb +10 -8
  43. data/app/lib/actions/katello/repository/destroy.rb +36 -12
  44. data/app/lib/actions/katello/repository_set/disable_repository.rb +8 -3
  45. data/app/lib/actions/pulp3/alternate_content_source/create.rb +20 -0
  46. data/app/lib/actions/pulp3/alternate_content_source/create_remote.rb +20 -0
  47. data/app/lib/actions/pulp3/alternate_content_source/delete.rb +16 -0
  48. data/app/lib/actions/pulp3/alternate_content_source/delete_remote.rb +16 -0
  49. data/app/lib/actions/pulp3/alternate_content_source/refresh.rb +23 -0
  50. data/app/lib/actions/pulp3/alternate_content_source/update.rb +16 -0
  51. data/app/lib/actions/pulp3/alternate_content_source/update_remote.rb +17 -0
  52. data/app/lib/actions/pulp3/content_view_version/{import.rb → create_import.rb} +5 -5
  53. data/app/lib/actions/pulp3/content_view_version/create_importer.rb +4 -3
  54. data/app/lib/actions/pulp3/content_view_version/destroy_importer.rb +12 -1
  55. data/app/lib/actions/pulp3/orchestration/alternate_content_source/create.rb +16 -0
  56. data/app/lib/actions/pulp3/orchestration/alternate_content_source/delete.rb +23 -0
  57. data/app/lib/actions/pulp3/orchestration/alternate_content_source/refresh.rb +15 -0
  58. data/app/lib/actions/pulp3/orchestration/alternate_content_source/update.rb +16 -0
  59. data/app/lib/actions/pulp3/orchestration/content_view_version/copy_version_units_to_library.rb +1 -1
  60. data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +51 -0
  61. data/app/lib/actions/pulp3/orchestration/content_view_version/import.rb +5 -2
  62. data/app/lib/actions/pulp3/repository/save_artifact.rb +1 -1
  63. data/app/lib/katello/api/v2/error_handling.rb +1 -0
  64. data/app/lib/katello/concerns/base_template_scope_extensions.rb +24 -11
  65. data/app/lib/katello/resources/cdn/katello_cdn.rb +3 -1
  66. data/app/lib/katello/util/errata.rb +2 -3
  67. data/app/lib/katello/validators/alternate_content_source_path_validator.rb +29 -0
  68. data/app/lib/katello/validators/content_default_http_proxy_setting_validator.rb +12 -0
  69. data/app/lib/katello/validators/content_view_environment_validator.rb +10 -5
  70. data/app/models/katello/alternate_content_source.rb +71 -0
  71. data/app/models/katello/authorization/alternate_content_source.rb +33 -0
  72. data/app/models/katello/authorization/repository.rb +5 -3
  73. data/app/models/katello/candlepin/repository_mapper.rb +13 -6
  74. data/app/models/katello/cdn_configuration.rb +15 -15
  75. data/app/models/katello/concerns/content_facet_host_extensions.rb +25 -0
  76. data/app/models/katello/concerns/host_managed_extensions.rb +7 -6
  77. data/app/models/katello/concerns/http_proxy_extensions.rb +14 -0
  78. data/app/models/katello/concerns/organization_extensions.rb +4 -2
  79. data/app/models/katello/concerns/setting_extensions.rb +14 -0
  80. data/app/models/katello/concerns/smart_proxy_extensions.rb +2 -1
  81. data/app/models/katello/content.rb +1 -0
  82. data/app/models/katello/content_credential.rb +6 -0
  83. data/app/models/katello/content_override.rb +7 -3
  84. data/app/models/katello/content_view.rb +33 -2
  85. data/app/models/katello/content_view_erratum_filter.rb +26 -12
  86. data/app/models/katello/content_view_filter.rb +4 -0
  87. data/app/models/katello/content_view_version.rb +12 -0
  88. data/app/models/katello/content_view_version_export_history.rb +3 -1
  89. data/app/models/katello/erratum.rb +9 -5
  90. data/app/models/katello/events/delete_latest_content_view_version.rb +40 -0
  91. data/app/models/katello/host/content_facet.rb +14 -0
  92. data/app/models/katello/host_available_module_stream.rb +12 -0
  93. data/app/models/katello/product_content.rb +1 -0
  94. data/app/models/katello/purpose_sla_status.rb +1 -1
  95. data/app/models/katello/purpose_status.rb +2 -2
  96. data/app/models/katello/repository.rb +7 -4
  97. data/app/models/katello/root_repository.rb +1 -1
  98. data/app/models/katello/smart_proxy_alternate_content_source.rb +8 -0
  99. data/app/models/katello/sync_plan.rb +1 -1
  100. data/app/presenters/katello/product_content_presenter.rb +15 -0
  101. data/app/services/katello/applicable_host_queue.rb +1 -1
  102. data/app/services/katello/product_content_finder.rb +12 -2
  103. data/app/services/katello/pulp3/alternate_content_source.rb +123 -0
  104. data/app/services/katello/pulp3/api/file.rb +8 -0
  105. data/app/services/katello/pulp3/api/yum.rb +8 -0
  106. data/app/services/katello/pulp3/content_view_version/export.rb +27 -5
  107. data/app/services/katello/pulp3/content_view_version/import.rb +104 -71
  108. data/app/services/katello/pulp3/content_view_version/import_export_common.rb +4 -4
  109. data/app/services/katello/pulp3/content_view_version/import_gpg_keys.rb +13 -11
  110. data/app/services/katello/pulp3/content_view_version/import_validator.rb +67 -72
  111. data/app/services/katello/pulp3/content_view_version/importable_products.rb +40 -24
  112. data/app/services/katello/pulp3/content_view_version/importable_repositories.rb +102 -38
  113. data/app/services/katello/pulp3/content_view_version/metadata_generator.rb +2 -2
  114. data/app/services/katello/pulp3/content_view_version/metadata_map.rb +117 -0
  115. data/app/services/katello/pulp3/pulp_content_unit.rb +6 -1
  116. data/app/services/katello/pulp3/repository/yum.rb +70 -12
  117. data/app/services/katello/pulp3/repository.rb +6 -62
  118. data/app/services/katello/pulp3/service_common.rb +66 -0
  119. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +4 -1
  120. data/app/services/katello/ui_notifications/content_view/delete_latest_version_failure.rb +22 -0
  121. data/app/views/foreman/job_templates/change_content_source.erb +1 -1
  122. data/app/views/foreman/job_templates/install_errata.erb +5 -5
  123. data/app/views/foreman/job_templates/install_errata_by_search_query.erb +10 -8
  124. data/app/views/foreman/job_templates/install_group.erb +4 -4
  125. data/app/views/foreman/job_templates/install_package.erb +4 -4
  126. data/app/views/foreman/job_templates/install_packages_by_search_query.erb +3 -3
  127. data/app/views/foreman/job_templates/remove_group.erb +4 -4
  128. data/app/views/foreman/job_templates/remove_package.erb +4 -4
  129. data/app/views/foreman/job_templates/remove_packages_by_search_query.erb +3 -3
  130. data/app/views/foreman/job_templates/resolve_traces.erb +2 -2
  131. data/app/views/foreman/job_templates/restart_services.erb +3 -3
  132. data/app/views/foreman/job_templates/update_group.erb +4 -4
  133. data/app/views/foreman/job_templates/update_package.erb +4 -4
  134. data/app/views/foreman/job_templates/update_packages_by_search_query.erb +3 -3
  135. data/app/views/katello/api/v2/alternate_content_sources/base.json.rabl +24 -0
  136. data/app/views/katello/api/v2/alternate_content_sources/index.json.rabl +7 -0
  137. data/app/views/katello/api/v2/alternate_content_sources/show.json.rabl +3 -0
  138. data/app/views/katello/api/v2/capsule_content/sync_status.json.rabl +1 -1
  139. data/app/views/katello/api/v2/content_facet/show.json.rabl +12 -0
  140. data/app/views/katello/api/v2/content_view_version_export_histories/show.json.rabl +2 -3
  141. data/app/views/katello/api/v2/content_view_versions/base.json.rabl +1 -1
  142. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -0
  143. data/app/views/katello/api/v2/environments/show.json.rabl +2 -0
  144. data/app/views/katello/api/v2/errata/_counts.json.rabl +2 -2
  145. data/app/views/katello/api/v2/host_module_streams/base.json.rabl +2 -2
  146. data/app/views/katello/api/v2/hosts/host_collections.json.rabl +1 -1
  147. data/app/views/katello/api/v2/organizations/show.json.rabl +7 -1
  148. data/app/views/katello/api/v2/repositories/show.json.rabl +2 -1
  149. data/app/views/katello/api/v2/repository_sets/show.json.rabl +4 -0
  150. data/app/views/katello/sync_management/_repo.html.erb +8 -29
  151. data/config/routes/api/v2.rb +19 -0
  152. data/db/migrate/20150930183738_migrate_content_hosts.rb +0 -399
  153. data/db/migrate/20171025163149_remove_use_pulp_oauth_setting.rb +1 -1
  154. data/db/migrate/20171114150937_cleanup_installed_packages.rb +1 -1
  155. data/db/migrate/20180402160223_clean_up_force_post_sync_action_setting.rb +1 -1
  156. data/db/migrate/20211129200124_remove_dependency_solving_algorithm_setting.rb +1 -1
  157. data/db/migrate/20211220185935_clean_duplicate_content_units.rb +1 -1
  158. data/db/migrate/20220110223754_update_disconnected_settings.rb +5 -5
  159. data/db/migrate/20220117151612_add_alternate_content_sources.rb +48 -0
  160. data/db/migrate/20220124191056_add_type_to_cdn_configuration.rb +9 -4
  161. data/db/migrate/20220209203251_add_generated_for_to_content_views.rb +13 -0
  162. data/db/migrate/20220209205137_expand_sync_timeout_settings.rb +7 -7
  163. data/db/migrate/20220228173251_remove_drpm_from_ignorable_content.rb +12 -0
  164. data/db/migrate/20220303160220_remove_duplicate_errata.rb +1 -1
  165. data/db/migrate/20220404190836_delete_old_setting_data.rb +9 -0
  166. data/db/migrate/20220405220616_update_cdn_configuration_type.rb +11 -0
  167. data/db/migrate/20220419193414_content_settings_to_dsl_category.rb +5 -0
  168. data/db/migrate/20220428203334_add_last_refreshed_to_katello_alternate_content_sources.rb +5 -0
  169. data/db/seeds.d/110-content-view-autopublish.rb +13 -0
  170. data/db/seeds.d/150-module_job_templates.rb +1 -1
  171. data/engines/bastion/README.md +1 -0
  172. data/engines/bastion/app/assets/javascripts/bastion/components/bst-modal.directive.js +1 -0
  173. data/engines/bastion/app/views/bastion/layouts/assets.html.erb +1 -0
  174. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/activation-keys.routes.js +1 -1
  175. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-details.controller.js +4 -2
  176. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-details.html +1 -1
  177. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.controller.js +11 -6
  178. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-module-streams.controller.js +1 -0
  179. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages-installed.controller.js +1 -0
  180. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages.controller.js +11 -3
  181. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-traces.controller.js +1 -0
  182. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-actions.html +1 -1
  183. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/views/content-host-packages-applicable.html +1 -1
  184. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +8 -0
  185. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details.controller.js +4 -2
  186. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +2 -2
  187. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/content.service.js +10 -0
  188. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-deb-repositories.html +26 -0
  189. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-debs.html +27 -0
  190. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/environments.controller.js +1 -0
  191. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/environments.routes.js +22 -0
  192. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/views/environments.html +13 -7
  193. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +63 -17
  194. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.controller.js +7 -8
  195. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +10 -1
  196. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +21 -3
  197. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +8 -12
  198. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +7 -5
  199. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +2 -1
  200. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/discovery-create.controller.js +1 -1
  201. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/views/discovery-create.html +1 -1
  202. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.routes.js +1 -0
  203. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/views/content-access-mode-banner.html +6 -1
  204. data/lib/katello/engine.rb +1 -5
  205. data/lib/katello/permission_creator.rb +34 -4
  206. data/lib/katello/plugin.rb +377 -3
  207. data/lib/katello/tasks/refresh_alternate_content_sources.rake +15 -0
  208. data/lib/katello/tasks/reset.rake.bak +67 -0
  209. data/lib/katello/tasks/update_content_default_http_proxy.rake +2 -3
  210. data/lib/katello/version.rb +1 -1
  211. data/locale/action_names.rb +47 -41
  212. data/locale/bn/LC_MESSAGES/katello.mo +0 -0
  213. data/locale/bn/katello.po +820 -106
  214. data/locale/bn/katello.po.time_stamp +0 -0
  215. data/locale/cs/LC_MESSAGES/katello.mo +0 -0
  216. data/locale/cs/katello.po +818 -104
  217. data/locale/cs/katello.po.time_stamp +0 -0
  218. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  219. data/locale/de/katello.po +893 -179
  220. data/locale/de/katello.po.time_stamp +0 -0
  221. data/locale/en/LC_MESSAGES/katello.mo +0 -0
  222. data/locale/en/katello.po +817 -103
  223. data/locale/en/katello.po.time_stamp +0 -0
  224. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  225. data/locale/es/katello.po +882 -168
  226. data/locale/es/katello.po.time_stamp +0 -0
  227. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  228. data/locale/fr/katello.po +1219 -505
  229. data/locale/fr/katello.po.time_stamp +0 -0
  230. data/locale/gu/LC_MESSAGES/katello.mo +0 -0
  231. data/locale/gu/katello.po +826 -112
  232. data/locale/gu/katello.po.time_stamp +0 -0
  233. data/locale/hi/LC_MESSAGES/katello.mo +0 -0
  234. data/locale/hi/katello.po +826 -112
  235. data/locale/hi/katello.po.time_stamp +0 -0
  236. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  237. data/locale/it/katello.po +863 -148
  238. data/locale/it/katello.po.time_stamp +0 -0
  239. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  240. data/locale/ja/katello.po +1216 -499
  241. data/locale/ja/katello.po.time_stamp +0 -0
  242. data/locale/katello.pot +3847 -2507
  243. data/locale/kn/LC_MESSAGES/katello.mo +0 -0
  244. data/locale/kn/katello.po +826 -112
  245. data/locale/kn/katello.po.time_stamp +0 -0
  246. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  247. data/locale/ko/katello.po +912 -198
  248. data/locale/ko/katello.po.time_stamp +0 -0
  249. data/locale/mr/LC_MESSAGES/katello.mo +0 -0
  250. data/locale/mr/katello.po +826 -112
  251. data/locale/mr/katello.po.time_stamp +0 -0
  252. data/locale/or/LC_MESSAGES/katello.mo +0 -0
  253. data/locale/or/katello.po +826 -112
  254. data/locale/or/katello.po.time_stamp +0 -0
  255. data/locale/pa/LC_MESSAGES/katello.mo +0 -0
  256. data/locale/pa/katello.po +826 -112
  257. data/locale/pa/katello.po.time_stamp +0 -0
  258. data/locale/pt/LC_MESSAGES/katello.mo +0 -0
  259. data/locale/pt/katello.po +817 -103
  260. data/locale/pt/katello.po.time_stamp +0 -0
  261. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  262. data/locale/pt_BR/katello.po +879 -165
  263. data/locale/pt_BR/katello.po.time_stamp +0 -0
  264. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  265. data/locale/ru/katello.po +927 -213
  266. data/locale/ru/katello.po.time_stamp +0 -0
  267. data/locale/ta/LC_MESSAGES/katello.mo +0 -0
  268. data/locale/ta/katello.po +820 -106
  269. data/locale/ta/katello.po.time_stamp +0 -0
  270. data/locale/te/LC_MESSAGES/katello.mo +0 -0
  271. data/locale/te/katello.po +826 -112
  272. data/locale/te/katello.po.time_stamp +0 -0
  273. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  274. data/locale/zh_CN/katello.po +1202 -486
  275. data/locale/zh_CN/katello.po.time_stamp +0 -0
  276. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  277. data/locale/zh_TW/katello.po +856 -142
  278. data/locale/zh_TW/katello.po.time_stamp +0 -0
  279. data/webpack/components/Bookmark/index.js +22 -14
  280. data/webpack/components/EditableTextInput/EditableTextInput.js +20 -5
  281. data/webpack/components/Errata/index.js +38 -8
  282. data/webpack/components/Packages/index.js +1 -4
  283. data/webpack/components/Search/Search.js +22 -3
  284. data/webpack/components/SelectAllCheckbox/index.js +1 -0
  285. data/webpack/components/SelectableDropdown/SelectableDropdown.js +4 -2
  286. data/webpack/components/Table/EmptyStateMessage.js +21 -7
  287. data/webpack/components/Table/MainTable.js +29 -4
  288. data/webpack/components/Table/MainTable.scss +5 -1
  289. data/webpack/components/Table/TableHooks.js +65 -20
  290. data/webpack/components/Table/TableWrapper.js +9 -3
  291. data/webpack/components/Table/components/SortableColumnHeaders.js +19 -0
  292. data/webpack/components/Table/components/TranslatedPlural.js +57 -0
  293. data/webpack/components/TypeAhead/TypeAhead.js +12 -0
  294. data/webpack/components/TypeAhead/pf4Search/TypeAheadInput.js +13 -11
  295. data/webpack/components/TypeAhead/pf4Search/TypeAheadSearch.js +7 -2
  296. data/webpack/components/extensions/HostDetails/ActionsBar/index.js +27 -0
  297. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ChangeHostCVModal.js +250 -0
  298. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard.js +232 -0
  299. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/HostContentViewActions.js +19 -0
  300. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/HostContentViewConstants.js +2 -0
  301. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/__tests__/changeHostCVModal.test.js +131 -0
  302. data/webpack/components/extensions/HostDetails/Cards/{__tests__ → ContentViewDetailsCard/__tests__}/contentViewDetailsCard.test.js +22 -0
  303. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/__tests__/contentViews.fixtures.json +443 -0
  304. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/__tests__/envPaths.fixtures.json +320 -0
  305. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.js +57 -33
  306. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.scss +3 -0
  307. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsActions.js +30 -0
  308. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.js +206 -0
  309. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsConstants.js +7 -0
  310. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsModal.js +227 -0
  311. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsSelectors.js +18 -0
  312. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/__tests__/availableHostCollections.fixtures.json +106 -0
  313. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/__tests__/hostCollectionsCard.test.js +118 -0
  314. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/__tests__/hostCollectionsModal.test.js +235 -0
  315. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/__tests__/removableHostCollections.fixtures.json +45 -0
  316. data/webpack/components/extensions/HostDetails/Cards/__tests__/errataOverviewCard.test.js +33 -8
  317. data/webpack/components/extensions/HostDetails/DetailsTabCards/InstalledProductsCard.js +44 -0
  318. data/webpack/components/extensions/HostDetails/DetailsTabCards/RecentCommunicationCardExtensions.js +37 -0
  319. data/webpack/components/extensions/HostDetails/DetailsTabCards/RegistrationCard.js +107 -0
  320. data/webpack/components/extensions/HostDetails/DetailsTabCards/SystemPropertiesCardExtensions.js +38 -0
  321. data/webpack/components/extensions/HostDetails/HostDetailsActions.js +11 -0
  322. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/SecondaryTabsRoutes.js +4 -0
  323. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/constants.js +2 -0
  324. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/index.js +6 -1
  325. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +176 -72
  326. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/HostErrataActions.js +1 -7
  327. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsActions.js +1 -3
  328. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsConstants.js +28 -0
  329. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +522 -118
  330. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/HostPackagesActions.js +1 -7
  331. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js +6 -4
  332. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +164 -58
  333. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +59 -49
  334. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionConstants.js +1 -0
  335. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionHooks.js +85 -0
  336. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsActions.js +33 -54
  337. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsConstants.js +20 -0
  338. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +298 -107
  339. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerModal.js +14 -7
  340. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/HostTracesActions.js +2 -1
  341. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesEnabler.js +104 -0
  342. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesTab.js +134 -57
  343. data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +37 -32
  344. data/webpack/components/extensions/HostDetails/Tabs/{ModuleStreamsTab/__tests__/modules.fixtures.json → __tests__/moduleStreams.fixtures.json} +6 -3
  345. data/webpack/components/extensions/HostDetails/Tabs/__tests__/moduleStreamsTab.test.js +261 -0
  346. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packageInstallModal.test.js +21 -15
  347. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +44 -1
  348. data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySets.fixtures.json +4 -1
  349. data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySetsTab.test.js +105 -6
  350. data/webpack/components/extensions/HostDetails/Tabs/__tests__/tracesTab.test.js +25 -6
  351. data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +6 -0
  352. data/webpack/components/extensions/HostDetails/hostDetailsHelpers.js +18 -0
  353. data/webpack/containers/Application/config.js +5 -0
  354. data/webpack/global_index.js +32 -9
  355. data/webpack/global_test_setup.js +13 -0
  356. data/webpack/redux/actions/RedHatRepositories/enabled.js +2 -1
  357. data/webpack/redux/actions/RedHatRepositories/helpers.js +13 -8
  358. data/webpack/scenes/AlternateContentSources/ACSActions.js +65 -0
  359. data/webpack/scenes/AlternateContentSources/ACSConstants.js +18 -0
  360. data/webpack/scenes/AlternateContentSources/ACSIndexPage.js +23 -0
  361. data/webpack/scenes/AlternateContentSources/ACSSelectors.js +24 -0
  362. data/webpack/scenes/AlternateContentSources/Create/ACSCreateContext.js +4 -0
  363. data/webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js +160 -0
  364. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js +79 -0
  365. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSCredentials.js +199 -0
  366. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSReview.js +104 -0
  367. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSSmartProxies.js +41 -0
  368. data/webpack/scenes/AlternateContentSources/Create/Steps/AcsUrlPaths.js +71 -0
  369. data/webpack/scenes/AlternateContentSources/Create/Steps/NameACS.js +57 -0
  370. data/webpack/scenes/AlternateContentSources/Create/Steps/SelectSource.js +77 -0
  371. data/webpack/scenes/AlternateContentSources/Create/__tests__/acsCreate.test.js +149 -0
  372. data/webpack/scenes/AlternateContentSources/Create/__tests__/acsCreateData.fixtures.json +3 -0
  373. data/webpack/scenes/AlternateContentSources/Create/__tests__/contentCredentials.fixtures.json +69 -0
  374. data/webpack/scenes/AlternateContentSources/Create/__tests__/smartProxy.fixtures.json +65 -0
  375. data/webpack/scenes/AlternateContentSources/MainTable/ACSTable.js +162 -0
  376. data/webpack/scenes/AlternateContentSources/MainTable/__tests__/acsIndex.fixtures.json +91 -0
  377. data/webpack/scenes/AlternateContentSources/MainTable/__tests__/acsTable.test.js +67 -0
  378. data/webpack/scenes/AlternateContentSources/index.js +4 -0
  379. data/webpack/scenes/Content/Details/ContentRepositories.js +1 -0
  380. data/webpack/scenes/Content/Table/ContentTable.js +1 -0
  381. data/webpack/scenes/ContentCredentials/ContentCredentialSelectors.js +4 -1
  382. data/webpack/scenes/ContentViews/ContentViewsActions.js +6 -2
  383. data/webpack/scenes/ContentViews/ContentViewsConstants.js +11 -3
  384. data/webpack/scenes/ContentViews/Copy/CopyContentViewForm.js +2 -1
  385. data/webpack/scenes/ContentViews/Create/ContentViewFormComponents.js +10 -1
  386. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +2 -1
  387. data/webpack/scenes/ContentViews/Delete/ContentViewDeleteWizard.js +7 -5
  388. data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionFinish.js +29 -21
  389. data/webpack/scenes/ContentViews/Delete/__tests__/contentViewDelete.test.js +15 -8
  390. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +2 -2
  391. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +2 -2
  392. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +3 -1
  393. data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +34 -8
  394. data/webpack/scenes/ContentViews/Details/ContentViewDetailSelectors.js +33 -29
  395. data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +130 -79
  396. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +16 -2
  397. data/webpack/scenes/ContentViews/Details/Filters/Add/CVFilterAddModal.js +2 -1
  398. data/webpack/scenes/ContentViews/Details/Filters/AffectedRepositories/AffectedRepositoryTable.js +2 -1
  399. data/webpack/scenes/ContentViews/Details/Filters/CVContainerImageFilterContent.js +6 -1
  400. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +41 -21
  401. data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +38 -20
  402. data/webpack/scenes/ContentViews/Details/Filters/CVModuleStreamFilterContent.js +2 -0
  403. data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +8 -1
  404. data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +9 -1
  405. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilters.js +2 -1
  406. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/CVRpmMatchContentModal.js +1 -0
  407. data/webpack/scenes/ContentViews/Details/Filters/Rules/ContainerTag/AddEditContainerTagRuleModal.js +27 -12
  408. data/webpack/scenes/ContentViews/Details/Filters/Rules/Package/AddEditPackageRuleModal.js +39 -17
  409. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVContainerImageFilterContent.test.js +27 -10
  410. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVRpmFilterContent.test.js +46 -23
  411. data/webpack/scenes/ContentViews/Details/Histories/ContentViewHistories.js +3 -2
  412. data/webpack/scenes/ContentViews/Details/Promote/ContentViewVersionPromote.js +5 -2
  413. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +161 -108
  414. data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewAddRemove.test.js +7 -7
  415. data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewRepoAdd.fixture.json +1 -0
  416. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/ActionSummary.js +58 -0
  417. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/BulkDeleteContextWrapper.js +45 -0
  418. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/BulkDeleteHelpers.js +30 -0
  419. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/BulkDeleteModal.js +56 -0
  420. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/Steps/ConfirmBulkDelete.js +126 -0
  421. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/Steps/FinishBulkDelete.js +61 -0
  422. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/Steps/ReassignActivationKeys.js +196 -0
  423. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/Steps/ReassignHosts.js +220 -0
  424. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/Steps/ReviewEnvironments.js +104 -0
  425. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/BulkDeleteModal.test.js +122 -0
  426. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/BulkDeleteVersions.fixtures.json +600 -0
  427. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/contentView.fixtures.json +1504 -0
  428. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/contentViewVersion.fixtures.json +936 -0
  429. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/environmentPaths.fixtures.json +261 -0
  430. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/__tests__/hosts.fixtures.json +163 -0
  431. data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/bulkDeleteSteps.js +79 -0
  432. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +192 -167
  433. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveCVVersionWizard.js +2 -5
  434. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVVersionDeleteFinish.js +38 -53
  435. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVVersionRemoveReview.js +1 -1
  436. data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/cvVersionRemove.test.js +6 -12
  437. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js +1 -0
  438. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedHosts.js +1 -0
  439. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailConfig.js +1 -0
  440. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetails.js +8 -20
  441. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsHeader.js +23 -13
  442. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsTable.js +3 -0
  443. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetails.fixtures.json +4 -4
  444. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetails.test.js +0 -3
  445. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetailsEmpty.test.js +4 -4
  446. data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersions.test.js +12 -14
  447. data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetails.fixtures.json +1 -0
  448. data/webpack/scenes/ContentViews/Publish/CVPublishFinish.js +96 -117
  449. data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +13 -19
  450. data/webpack/scenes/ContentViews/Publish/__tests__/publishContentView.test.js +9 -20
  451. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +165 -148
  452. data/webpack/scenes/ContentViews/Table/tableDataGenerator.js +2 -0
  453. data/webpack/scenes/ContentViews/components/ContentViewIcon.js +14 -3
  454. data/webpack/scenes/ContentViews/components/EnvironmentLabels.js +4 -3
  455. data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.js +10 -6
  456. data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.scss +6 -1
  457. data/webpack/scenes/ContentViews/components/TaskPresenter/TaskPresenter.js +40 -35
  458. data/webpack/scenes/ContentViews/expansions/RelatedCompositeContentViewsModal.js +1 -1
  459. data/webpack/scenes/ContentViews/expansions/RelatedContentViewComponentsModal.js +2 -2
  460. data/webpack/scenes/ContentViews/helpers.js +3 -0
  461. data/webpack/scenes/Hosts/ChangeContentSource/helpers.js +5 -0
  462. data/webpack/scenes/RedHatRepositories/RedHatRepositoriesPage.js +3 -3
  463. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/EnabledRepository.js +2 -1
  464. data/webpack/scenes/RedHatRepositories/components/EnabledRepository/__tests__/EnabledRepository.test.js +2 -0
  465. data/webpack/scenes/RedHatRepositories/components/Search.js +4 -4
  466. data/webpack/scenes/SmartProxy/SmartProxyContentActions.js +9 -2
  467. data/webpack/scenes/SmartProxy/SmartProxyContentConstants.js +1 -1
  468. data/webpack/scenes/SmartProxy/SmartProxyContentSelectors.js +10 -1
  469. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnConfigurationConstants.js +3 -3
  470. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnTypeForm.js +2 -0
  471. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/{AirGappedTypeForm.js → ExportSyncForm.js} +7 -6
  472. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/{UpstreamServerTypeForm.js → NetworkSyncForm.js} +15 -7
  473. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/{AirGappedTypeForm.test.js → ExportSyncForm.test.js} +4 -4
  474. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/{UpstreamServerTypeForm.test.js → NetworkSyncForm.test.js} +8 -8
  475. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/index.js +11 -11
  476. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +1 -0
  477. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +8 -7
  478. data/webpack/scenes/Tasks/TaskActions.js +6 -0
  479. data/webpack/scenes/Tasks/TaskSelectors.js +11 -0
  480. data/webpack/scenes/Tasks/helpers.js +60 -5
  481. data/webpack/utils/helpers.js +2 -0
  482. metadata +183 -38
  483. data/app/models/setting/content.rb +0 -201
  484. data/db/seeds.d/107-enable_dynflow.rb +0 -8
  485. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard.js +0 -96
  486. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/__tests__/moduleStreamsTab.test.js +0 -108
  487. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerEmptyState.js +0 -42
  488. data/webpack/scenes/ContentViews/Details/DetailsContainer.js +0 -36
@@ -0,0 +1,104 @@
1
+ import React, { useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import {
4
+ EmptyState,
5
+ EmptyStateIcon,
6
+ EmptyStateBody,
7
+ Title,
8
+ EmptyStateVariant,
9
+ Button,
10
+ Flex,
11
+ FlexItem,
12
+ Spinner,
13
+ } from '@patternfly/react-core';
14
+ import { WrenchIcon } from '@patternfly/react-icons';
15
+ import { translate as __ } from 'foremanReact/common/I18n';
16
+ import { urlBuilder } from 'foremanReact/common/urlHelpers';
17
+ import EnableTracerModal from './EnableTracerModal';
18
+ import { useRexJobPolling } from '../RemoteExecutionHooks';
19
+ import { installTracerPackage } from './HostTracesActions';
20
+ import { getHostDetails } from '../../HostDetailsActions';
21
+
22
+ const EnableTracerButton = ({ setEnableTracerModalOpen, pollingStarted }) => (
23
+ <Button
24
+ onClick={() => setEnableTracerModalOpen(true)}
25
+ isDisabled={pollingStarted}
26
+ >
27
+ {__('Enable Traces')}
28
+ </Button>
29
+ );
30
+
31
+ const ViewTaskButton = ({ jobId }) => (
32
+ <Button
33
+ component="a"
34
+ href={urlBuilder('job_invocations', '', jobId)}
35
+ variant="secondary"
36
+ isDisabled={!jobId}
37
+ >
38
+ {__('View the job')}
39
+ </Button>
40
+ );
41
+
42
+ ViewTaskButton.propTypes = {
43
+ jobId: PropTypes.number,
44
+ };
45
+ ViewTaskButton.defaultProps = {
46
+ jobId: null,
47
+ };
48
+
49
+ EnableTracerButton.propTypes = {
50
+ setEnableTracerModalOpen: PropTypes.func.isRequired,
51
+ pollingStarted: PropTypes.bool.isRequired,
52
+ };
53
+
54
+ const TracesEnabler = ({ hostname }) => {
55
+ const title = __('Traces are not enabled');
56
+ const enablingTitle = __('Traces are being enabled');
57
+ const body = __('Traces help administrators identify applications that need to be restarted after a system is patched.');
58
+ const [enableTracerModalOpen, setEnableTracerModalOpen] = useState(false);
59
+ const initialAction = installTracerPackage({ hostname });
60
+ const successAction = getHostDetails({ hostname });
61
+ const {
62
+ pollingStarted,
63
+ rexJobId,
64
+ triggerJobStart,
65
+ } = useRexJobPolling(initialAction, successAction);
66
+
67
+ return (
68
+ <EmptyState variant={EmptyStateVariant.small}>
69
+ {pollingStarted ?
70
+ <Spinner /> :
71
+ <EmptyStateIcon icon={WrenchIcon} />
72
+ }
73
+ <Title headingLevel="h2" size="lg">
74
+ {pollingStarted ? enablingTitle : title}
75
+ </Title>
76
+ <EmptyStateBody>
77
+ <Flex direction={{ default: 'column' }}>
78
+ <FlexItem>{body}</FlexItem>
79
+ <FlexItem>
80
+ {pollingStarted ?
81
+ <ViewTaskButton jobId={rexJobId} /> :
82
+ <EnableTracerButton {...{
83
+ setEnableTracerModalOpen,
84
+ pollingStarted,
85
+ }}
86
+ />
87
+ }
88
+ </FlexItem>
89
+ </Flex>
90
+ </EmptyStateBody>
91
+ <EnableTracerModal
92
+ isOpen={enableTracerModalOpen}
93
+ setIsOpen={setEnableTracerModalOpen}
94
+ triggerJobStart={triggerJobStart}
95
+ />
96
+ </EmptyState>
97
+ );
98
+ };
99
+
100
+ TracesEnabler.propTypes = {
101
+ hostname: PropTypes.string.isRequired,
102
+ };
103
+
104
+ export default TracesEnabler;
@@ -1,45 +1,77 @@
1
1
  import React, { useState, useCallback } from 'react';
2
+ import { FormattedMessage } from 'react-intl';
2
3
  import {
3
- Skeleton, Button, Split, SplitItem, ActionList, ActionListItem, Dropdown,
4
- DropdownItem, KebabToggle,
4
+ Skeleton, Split, SplitItem, ActionList, ActionListItem, Dropdown,
5
+ DropdownItem, DropdownToggle, DropdownToggleAction,
5
6
  } from '@patternfly/react-core';
6
7
  import { translate as __ } from 'foremanReact/common/I18n';
7
8
  import { TableVariant, Thead, Tbody, Tr, Th, Td } from '@patternfly/react-table';
8
- import { useSelector, useDispatch } from 'react-redux';
9
+ import { useSelector } from 'react-redux';
9
10
  import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
10
- import EnableTracerEmptyState from './EnableTracerEmptyState';
11
+ import TracesEnabler from './TracesEnabler';
11
12
  import TableWrapper from '../../../../Table/TableWrapper';
12
- import { useBulkSelect, useUrlParams } from '../../../../Table/TableHooks';
13
+ import { useBulkSelect, useTableSort, useUrlParams } from '../../../../Table/TableHooks';
13
14
  import { getHostTraces } from './HostTracesActions';
14
15
  import { resolveTraces } from '../RemoteExecutionActions';
15
16
  import { selectHostTracesStatus } from './HostTracesSelectors';
16
17
  import { resolveTraceUrl } from '../customizedRexUrlHelpers';
17
18
  import './TracesTab.scss';
18
19
  import hostIdNotReady from '../../HostDetailsActions';
20
+ import SortableColumnHeaders from '../../../../Table/components/SortableColumnHeaders';
21
+ import { useRexJobPolling } from '../RemoteExecutionHooks';
22
+ import { hasRequiredPermissions as can,
23
+ missingRequiredPermissions as cannot,
24
+ userPermissionsFromHostDetails } from '../../hostDetailsHelpers';
25
+
26
+ const invokeRexJobs = ['create_job_invocations'];
27
+ const createBookmarks = ['create_bookmarks'];
19
28
 
20
29
  const TracesTab = () => {
21
30
  const hostDetails = useSelector(state => selectAPIResponse(state, 'HOST_DETAILS'));
22
- const dispatch = useDispatch();
23
31
  const {
24
32
  id: hostId,
25
33
  name: hostname,
26
34
  content_facet_attributes: contentFacetAttributes,
27
35
  } = hostDetails;
36
+ const showActions = can(invokeRexJobs, userPermissionsFromHostDetails({ hostDetails }));
28
37
  const showEnableTracer = (contentFacetAttributes?.katello_tracer_installed === false);
29
- const emptyContentTitle = __('This host currently does not have traces.');
30
- const emptyContentBody = __('Add traces by applying updates on this host.');
38
+ const emptyContentTitle = showActions ? __('No applications to restart') : __('Traces not available');
39
+ const tracesNotAvailBody = showEnableTracer ? __('Traces may be enabled by a user with the appropriate permissions.') :
40
+ __('Traces will be shown here to a user with the appropriate permissions.');
41
+ const emptyContentBody = showActions ? (<FormattedMessage
42
+ id="traces-happy-empty"
43
+ values={{
44
+ pkgLink: <a href="#/Content/packages?status=Upgradable">{__('installing or updating packages')}</a>,
45
+ }}
46
+ defaultMessage={__('Traces may be listed here after {pkgLink}.')}
47
+ />) : tracesNotAvailBody;
31
48
  const emptySearchTitle = __('No matching traces found');
32
49
  const emptySearchBody = __('Try changing your search settings.');
33
- const fetchItems = useCallback(
34
- params =>
35
- (hostId ? getHostTraces(hostId, params) : hostIdNotReady),
36
- [hostId],
37
- );
50
+ const errorSearchTitle = __('Problem searching traces');
51
+ const columnHeaders = [
52
+ __('Application'),
53
+ __('Type'),
54
+ __('Helper'),
55
+ ];
56
+ const COLUMNS_TO_SORT_PARAMS = {
57
+ [columnHeaders[0]]: 'application',
58
+ [columnHeaders[1]]: 'app_type',
59
+ [columnHeaders[2]]: 'helper',
60
+ };
61
+ const {
62
+ pfSortParams, apiSortParams,
63
+ activeSortColumn, activeSortDirection,
64
+ } = useTableSort({
65
+ allColumns: columnHeaders,
66
+ columnsToSortParams: COLUMNS_TO_SORT_PARAMS,
67
+ initialSortColumnName: 'Application',
68
+ });
38
69
  const { searchParam } = useUrlParams();
39
70
  const [isBulkActionOpen, setIsBulkActionOpen] = useState(false);
40
71
  const toggleBulkAction = () => setIsBulkActionOpen(prev => !prev);
41
72
  const response = useSelector(state => selectAPIResponse(state, 'HOST_TRACES'));
42
73
  const { results, ...meta } = response;
74
+ const { error: errorSearchBody } = meta;
43
75
  const tracesSearchQuery = id => `id = ${id}`;
44
76
  const {
45
77
  selectOne, isSelected, searchQuery, selectedCount, isSelectable,
@@ -51,25 +83,46 @@ const TracesTab = () => {
51
83
  initialSearchQuery: searchParam || '',
52
84
  });
53
85
 
86
+ const BulkRestartTracesAction = () => resolveTraces({
87
+ hostname, search: fetchBulkParams(),
88
+ });
89
+ const {
90
+ triggerJobStart: triggerBulkRestart, lastCompletedJob: lastCompletedBulkRestart,
91
+ isPolling: isBulkRestartInProgress,
92
+ } = useRexJobPolling(BulkRestartTracesAction);
93
+
94
+ const restartTraceAction = id => resolveTraces({
95
+ hostname,
96
+ search: tracesSearchQuery(id),
97
+ });
98
+
99
+ const {
100
+ triggerJobStart: triggerAppRestart, lastCompletedJob: lastCompletedAppRestart,
101
+ isPolling: isAppRestartInProgress,
102
+ } = useRexJobPolling(restartTraceAction);
103
+
104
+ const actionInProgress = (isBulkRestartInProgress || isAppRestartInProgress);
105
+
106
+ const fetchItems = useCallback(
107
+ params =>
108
+ (hostId ? getHostTraces(hostId, { ...apiSortParams, ...params }) : hostIdNotReady),
109
+ [hostId, apiSortParams],
110
+ );
54
111
 
55
112
  const onBulkRestartApp = () => {
56
- dispatch(resolveTraces({
57
- hostname, search: fetchBulkParams(),
58
- }));
113
+ triggerBulkRestart();
59
114
  selectNone();
60
- const params = { page: meta.page, per_page: meta.per_page, search: meta.search };
61
- dispatch(getHostTraces(hostId, params));
62
115
  };
63
116
 
64
- const onRestartApp = id => dispatch(resolveTraces({
65
- hostname,
66
- search: tracesSearchQuery(id),
67
- }));
117
+ const onRestartApp = id => triggerAppRestart(id);
68
118
 
69
119
  const bulkCustomizedRexUrl = () => resolveTraceUrl({
70
120
  hostname, search: (selectedCount > 0) ? fetchBulkParams() : '',
71
121
  });
72
122
 
123
+ const readOnlyBookmarks =
124
+ cannot(createBookmarks, userPermissionsFromHostDetails({ hostDetails }));
125
+
73
126
  const dropdownItems = [
74
127
  <DropdownItem isDisabled={selectedCount === 0} aria-label="bulk_rex" key="bulk_rex" component="button" onClick={onBulkRestartApp}>
75
128
  {__('Restart via remote execution')}
@@ -79,24 +132,28 @@ const TracesTab = () => {
79
132
  </DropdownItem>,
80
133
  ];
81
134
 
82
- const actionButtons = (
135
+ const actionButtons = showActions ? (
83
136
  <Split hasGutter>
84
137
  <SplitItem>
85
138
  <ActionList isIconList>
86
- <ActionListItem>
87
- <Button
88
- variant="secondary"
89
- isDisabled={selectedCount === 0}
90
- onClick={onBulkRestartApp}
91
- >
92
- {__('Restart app')}
93
- </Button>
94
- </ActionListItem>
95
139
  <ActionListItem>
96
140
  <Dropdown
97
- toggle={<KebabToggle aria-label="bulk_actions" onToggle={toggleBulkAction} />}
141
+ aria-label="bulk_actions_dropdown"
142
+ toggle={
143
+ <DropdownToggle
144
+ aria-label="bulk_actions"
145
+ splitButtonItems={[
146
+ <DropdownToggleAction key="action" onClick={onBulkRestartApp}>
147
+ {__('Restart app')}
148
+ </DropdownToggleAction>,
149
+ ]}
150
+ isDisabled={selectedCount === 0}
151
+ splitButtonVariant="action"
152
+ toggleVariant="primary"
153
+ onToggle={toggleBulkAction}
154
+ />
155
+ }
98
156
  isOpen={isBulkActionOpen}
99
- isPlain
100
157
  dropdownItems={dropdownItems}
101
158
  />
102
159
  </ActionListItem>
@@ -104,9 +161,9 @@ const TracesTab = () => {
104
161
  </SplitItem>
105
162
  </Split>
106
163
 
107
- );
164
+ ) : null;
108
165
  const status = useSelector(state => selectHostTracesStatus(state));
109
- if (showEnableTracer) return <EnableTracerEmptyState />;
166
+ if (showEnableTracer && showActions) return <TracesEnabler hostname={hostname} />;
110
167
 
111
168
  if (!hostId) return <Skeleton />;
112
169
 
@@ -120,6 +177,8 @@ const TracesTab = () => {
120
177
  emptyContentBody,
121
178
  emptySearchTitle,
122
179
  emptySearchBody,
180
+ errorSearchTitle,
181
+ errorSearchBody,
123
182
  status,
124
183
  searchQuery,
125
184
  updateSearchQuery,
@@ -129,20 +188,28 @@ const TracesTab = () => {
129
188
  actionButtons,
130
189
  }
131
190
  }
191
+ happyEmptyContent={showActions}
192
+ ouiaId="host-traces-table"
132
193
  metadata={meta}
194
+ bookmarkController="katello_host_tracers"
195
+ readOnlyBookmarks={readOnlyBookmarks}
133
196
  autocompleteEndpoint={`/hosts/${hostId}/traces/auto_complete_search`}
134
197
  foremanApiAutoComplete
135
198
  rowsCount={results?.length}
136
199
  variant={TableVariant.compact}
137
- displaySelectAllCheckbox
200
+ additionalListeners={[activeSortColumn, activeSortDirection,
201
+ lastCompletedAppRestart, lastCompletedBulkRestart]}
202
+ displaySelectAllCheckbox={showActions}
138
203
  {...selectAll}
139
204
  >
140
205
  <Thead>
141
206
  <Tr>
142
207
  <Th key="select_checkbox" />
143
- <Th>{__('Application')}</Th>
144
- <Th>{__('Type')}</Th>
145
- <Th>{__('Helper')}</Th>
208
+ <SortableColumnHeaders
209
+ columnHeaders={columnHeaders}
210
+ pfSortParams={pfSortParams}
211
+ columnsToSortParams={COLUMNS_TO_SORT_PARAMS}
212
+ />
146
213
  <Th key="action_menu" />
147
214
  </Tr>
148
215
  </Thead>
@@ -155,8 +222,11 @@ const TracesTab = () => {
155
222
  app_type: appType,
156
223
  } = result;
157
224
  const resolveDisabled = !isSelectable(id);
225
+ let disabledReason;
226
+ if (resolveDisabled) disabledReason = __('Traces that require logout cannot be restarted remotely');
227
+ if (actionInProgress) disabledReason = __('A remote execution job is in progress');
158
228
  let rowDropdownItems = [
159
- { title: 'Restart via remote execution', onClick: () => onRestartApp(id) },
229
+ { title: 'Restart via remote execution', onClick: () => onRestartApp(id), isDisabled: actionInProgress },
160
230
  {
161
231
  component: 'a', href: resolveTraceUrl({ hostname, search: tracesSearchQuery(id) }), title: 'Restart via customized remote execution',
162
232
  },
@@ -168,25 +238,32 @@ const TracesTab = () => {
168
238
  }
169
239
  return (
170
240
  <Tr key={id} >
171
- <Td select={{
172
- disable: resolveDisabled,
173
- props: {
174
- 'aria-label': `check-${application}`,
175
- },
176
- isSelected: isSelected(id),
177
- onSelect: (event, selected) => selectOne(selected, id),
178
- rowIndex,
179
- variant: 'checkbox',
180
- }}
181
- />
241
+ {showActions ? (
242
+ <Td
243
+ select={{
244
+ disable: actionInProgress || resolveDisabled,
245
+ props: {
246
+ 'aria-label': `check-${application}`,
247
+ },
248
+ isSelected: isSelected(id),
249
+ onSelect: (event, selected) => selectOne(selected, id),
250
+ rowIndex,
251
+ variant: 'checkbox',
252
+ }}
253
+ title={disabledReason}
254
+ />
255
+ ) : <Td>&nbsp;</Td>
256
+ }
182
257
  <Td>{application}</Td>
183
258
  <Td>{appType}</Td>
184
259
  <Td>{helper}</Td>
185
- <Td
186
- actions={{
187
- items: rowDropdownItems,
188
- }}
189
- />
260
+ {showActions && (
261
+ <Td
262
+ actions={{
263
+ items: rowDropdownItems,
264
+ }}
265
+ />
266
+ )}
190
267
  </Tr>
191
268
  );
192
269
  })
@@ -8,6 +8,15 @@ import { REX_FEATURES } from '../RemoteExecutionConstants';
8
8
  import { ErrataTab } from '../ErrataTab/ErrataTab.js';
9
9
  import mockErrataData from './errata.fixtures.json';
10
10
  import mockResolveErrataTask from './resolveErrata.fixtures.json';
11
+ import mockBookmarkData from './bookmarks.fixtures.json';
12
+
13
+ jest.mock('../../hostDetailsHelpers', () => ({
14
+ ...jest.requireActual('../../hostDetailsHelpers'),
15
+ userPermissionsFromHostDetails: () => ({
16
+ create_job_invocations: true,
17
+ edit_hosts: true,
18
+ }),
19
+ }));
11
20
 
12
21
  const contentFacetAttributes = {
13
22
  id: 11,
@@ -17,6 +26,8 @@ const contentFacetAttributes = {
17
26
  };
18
27
  const hostName = 'foo.example.com';
19
28
 
29
+ const errataBookmarks = foremanApi.getApiUrl('/bookmarks?search=controller%3Dkatello_errata');
30
+
20
31
  const renderOptions = (facetAttributes = contentFacetAttributes) => ({
21
32
  apiNamespace: HOST_ERRATA_KEY,
22
33
  initialState: {
@@ -65,13 +76,18 @@ const makeMockErrata = ({ pageSize = 20, total = 100, page = 1 }) => {
65
76
 
66
77
  const hostErrata = foremanApi.getApiUrl('/hosts/1/errata');
67
78
  const autocompleteUrl = '/hosts/1/errata/auto_complete_search';
68
- const defaultQueryWithoutSearch = {
79
+ const baseQuery = {
69
80
  include_applicable: false,
70
81
  per_page: 20,
71
82
  page: 1,
72
83
  };
73
- const defaultQuery = { ...defaultQueryWithoutSearch, search: '' };
74
- const page2Query = { ...defaultQueryWithoutSearch, page: 2 };
84
+ const baseQueryWithSort = {
85
+ ...baseQuery,
86
+ sort_by: 'errata_id',
87
+ sort_order: 'asc',
88
+ };
89
+ const defaultQuery = { ...baseQueryWithSort, search: '' };
90
+ const page2Query = { ...baseQueryWithSort, page: 2 };
75
91
  const jobInvocations = foremanApi.getApiUrl('/job_invocations');
76
92
  const applyByKatelloAgentUrl = foremanApi.getApiUrl('/hosts/1/errata/apply');
77
93
 
@@ -79,10 +95,12 @@ let firstErrata;
79
95
  let thirdErrata;
80
96
  let searchDelayScope;
81
97
  let autoSearchScope;
98
+ let bookmarkScope;
82
99
 
83
100
  beforeEach(() => {
84
101
  const { results } = mockErrataData;
85
102
  [firstErrata, , thirdErrata] = results;
103
+ bookmarkScope = nockInstance.get(errataBookmarks).reply(200, mockBookmarkData);
86
104
  searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
87
105
  autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
88
106
  });
@@ -90,6 +108,7 @@ beforeEach(() => {
90
108
  afterEach(() => {
91
109
  assertNockRequest(searchDelayScope);
92
110
  assertNockRequest(autoSearchScope);
111
+ assertNockRequest(bookmarkScope);
93
112
  });
94
113
 
95
114
  test('Can call API for errata and show on screen on page load', async (done) => {
@@ -129,7 +148,7 @@ test('Can handle no errata being present', async (done) => {
129
148
  const { queryByText } = renderWithRedux(<ErrataTab />, renderOptions());
130
149
 
131
150
  // Assert that there are not any errata showing on the screen.
132
- await patientlyWaitFor(() => expect(queryByText('This host does not have any installable errata.')).toBeInTheDocument());
151
+ await patientlyWaitFor(() => expect(queryByText('This host has errata that are applicable, but not installable.')).toBeInTheDocument());
133
152
  // Assert request was made and completed, see helper function
134
153
  assertNockRequest(autocompleteScope);
135
154
  assertNockRequest(scope, done); // Pass jest callback to confirm test is done
@@ -171,8 +190,8 @@ test('Can display expanded errata details', async (done) => {
171
190
  expect(queryByText(firstErrata.cves[0].cve_id)).not.toBeInTheDocument();
172
191
 
173
192
  firstExpansion.click();
174
- // the errata details should now be hidden
175
- expect(getByText(firstErrata.summary)).not.toBeVisible();
193
+ // the errata details should now be gone
194
+ expect(queryByText(firstErrata.summary)).not.toBeInTheDocument();
176
195
  // Assert request was made and completed, see helper function
177
196
  assertNockRequest(autocompleteScope);
178
197
  assertNockRequest(scope, done); // Pass jest callback to confirm test is done
@@ -393,7 +412,7 @@ test('Can de-select items in select all mode across pages', async (done) => {
393
412
 
394
413
  const scope2 = nockInstance
395
414
  .get(hostErrata)
396
- .query({ ...defaultQueryWithoutSearch, page: 1 })
415
+ .query({ ...baseQueryWithSort, page: 1 })
397
416
  .reply(200, makeMockErrata({ page: 2 }));
398
417
 
399
418
  const scope3 = nockInstance
@@ -716,6 +735,7 @@ test('Can filter by errata type', async (done) => {
716
735
 
717
736
  const {
718
737
  queryByText,
738
+ queryByLabelText,
719
739
  getByRole,
720
740
  getAllByText,
721
741
  getByText,
@@ -726,7 +746,8 @@ test('Can filter by errata type', async (done) => {
726
746
  // the Bugfix text in the table is just a text node, while the dropdown is a button
727
747
  expect(getByText('Bugfix', { ignore: ['button', 'title'] })).toBeInTheDocument();
728
748
  expect(getByText('Enhancement', { ignore: ['button', 'title'] })).toBeInTheDocument();
729
- const typeDropdown = queryByText('Type', { ignore: 'th' });
749
+ const typeContainer = queryByLabelText('select Type container', { ignore: 'th' });
750
+ const typeDropdown = within(typeContainer).queryByText('Type');
730
751
  expect(typeDropdown).toBeInTheDocument();
731
752
  fireEvent.click(typeDropdown);
732
753
  const security = getByRole('option', { name: 'select Security' });
@@ -759,6 +780,7 @@ test('Can filter by severity', async (done) => {
759
780
  const {
760
781
  queryByText,
761
782
  getByRole,
783
+ queryByLabelText,
762
784
  getAllByText,
763
785
  getByText,
764
786
  } = renderWithRedux(<ErrataTab />, renderOptions());
@@ -769,7 +791,8 @@ test('Can filter by severity', async (done) => {
769
791
  expect(getByText('Moderate', { ignore: ['button', 'title'] })).toBeInTheDocument();
770
792
  expect(getByText('Important', { ignore: ['.pf-c-select__toggle-text', 'title'] })).toBeInTheDocument();
771
793
  expect(getByText('Critical', { ignore: ['button', 'title'] })).toBeInTheDocument();
772
- const severityDropdown = queryByText('Severity', { ignore: 'th' });
794
+ const severityContainer = queryByLabelText('select Severity container', { ignore: 'th' });
795
+ const severityDropdown = within(severityContainer).queryByText('Severity');
773
796
  expect(severityDropdown).toBeInTheDocument();
774
797
  fireEvent.click(severityDropdown);
775
798
  const important = getByRole('option', { name: 'select Important' });
@@ -860,7 +883,7 @@ test('Can bulk apply via katello agent', async (done) => {
860
883
  getByLabelText('Select row 0').click();
861
884
  getByLabelText('Select row 1').click();
862
885
 
863
- const actionMenu = getByLabelText('bulk_actions');
886
+ const actionMenu = getByLabelText('expand_errata_toggle');
864
887
  actionMenu.click();
865
888
  const viaAction = queryByText('Apply via Katello agent');
866
889
  expect(viaAction).toBeInTheDocument();
@@ -908,7 +931,7 @@ test('Can select all, exclude and bulk apply via katello agent', async (done) =>
908
931
 
909
932
  getByLabelText('Select row 0').click(); // deselect
910
933
 
911
- const actionMenu = getByLabelText('bulk_actions');
934
+ const actionMenu = getByLabelText('expand_errata_toggle');
912
935
  actionMenu.click();
913
936
  const viaAction = queryByText('Apply via Katello agent');
914
937
  expect(viaAction).toBeInTheDocument();
@@ -934,11 +957,6 @@ test('Apply button chooses remote execution', async (done) => {
934
957
  .query(defaultQuery)
935
958
  .reply(200, mockErrata);
936
959
 
937
- const scope1 = nockInstance
938
- .get(hostErrata)
939
- .query(defaultQueryWithoutSearch)
940
- .reply(200, mockErrata);
941
-
942
960
  const resolveErrataScope = nockInstance
943
961
  .post(jobInvocations)
944
962
  .reply(201, mockResolveErrataTask);
@@ -959,7 +977,6 @@ test('Apply button chooses remote execution', async (done) => {
959
977
 
960
978
  assertNockRequest(autocompleteScope);
961
979
  assertNockRequest(resolveErrataScope);
962
- assertNockRequest(scope1);
963
980
  assertNockRequest(scope, done);
964
981
  });
965
982
 
@@ -972,11 +989,6 @@ test('Can bulk apply via remote execution', async (done) => {
972
989
  .query(defaultQuery)
973
990
  .reply(200, mockErrata);
974
991
 
975
- const scope1 = nockInstance
976
- .get(hostErrata)
977
- .query(defaultQueryWithoutSearch)
978
- .reply(200, mockErrata);
979
-
980
992
  // eslint-disable-next-line camelcase
981
993
  const jobInvocationBody = ({ job_invocation: { inputs, feature, search_query } }) =>
982
994
  inputs[ERRATA_SEARCH_QUERY] === `errata_id ^ (${results[0].errata_id},${results[1].errata_id})` &&
@@ -998,7 +1010,7 @@ test('Can bulk apply via remote execution', async (done) => {
998
1010
  getByLabelText('Select row 0').click();
999
1011
  getByLabelText('Select row 1').click();
1000
1012
 
1001
- const actionMenu = getByLabelText('bulk_actions');
1013
+ const actionMenu = getByLabelText('expand_errata_toggle');
1002
1014
  actionMenu.click();
1003
1015
  const viaRexAction = queryByText('Apply via remote execution');
1004
1016
  expect(viaRexAction).toBeInTheDocument();
@@ -1006,7 +1018,6 @@ test('Can bulk apply via remote execution', async (done) => {
1006
1018
 
1007
1019
  assertNockRequest(autocompleteScope);
1008
1020
  assertNockRequest(resolveErrataScope);
1009
- assertNockRequest(scope1);
1010
1021
  assertNockRequest(scope, done);
1011
1022
  });
1012
1023
 
@@ -1021,11 +1032,6 @@ test('Can select all, exclude and bulk apply via remote execution', async (done)
1021
1032
  .query(defaultQuery)
1022
1033
  .reply(200, mockErrata);
1023
1034
 
1024
- const scope1 = nockInstance
1025
- .get(hostErrata)
1026
- .query(defaultQueryWithoutSearch)
1027
- .reply(200, mockErrata);
1028
-
1029
1035
  const jobInvocationBody = ({ job_invocation: { inputs } }) =>
1030
1036
  inputs[ERRATA_SEARCH_QUERY] === `errata_id !^ (${results[0].errata_id})`;
1031
1037
 
@@ -1044,7 +1050,7 @@ test('Can select all, exclude and bulk apply via remote execution', async (done)
1044
1050
 
1045
1051
  getByLabelText('Select row 0').click(); // de select
1046
1052
 
1047
- const actionMenu = getByLabelText('bulk_actions');
1053
+ const actionMenu = getByLabelText('expand_errata_toggle');
1048
1054
  actionMenu.click();
1049
1055
  const viaRexAction = queryByText('Apply via remote execution');
1050
1056
  expect(viaRexAction).toBeInTheDocument();
@@ -1052,7 +1058,6 @@ test('Can select all, exclude and bulk apply via remote execution', async (done)
1052
1058
 
1053
1059
  assertNockRequest(autocompleteScope);
1054
1060
  assertNockRequest(resolveErrataScope);
1055
- assertNockRequest(scope1);
1056
1061
  assertNockRequest(scope, done);
1057
1062
  });
1058
1063
 
@@ -1076,7 +1081,7 @@ test('Can apply errata in bulk via customized remote execution', async (done) =>
1076
1081
  getByLabelText('Select row 1').click();
1077
1082
  const errata = `${results[0].errata_id},${results[1].errata_id}`;
1078
1083
  const feature = REX_FEATURES.KATELLO_HOST_ERRATA_INSTALL_BY_SEARCH;
1079
- const actionMenu = getByLabelText('bulk_actions');
1084
+ const actionMenu = getByLabelText('expand_errata_toggle');
1080
1085
  actionMenu.click();
1081
1086
  const viaRexAction = queryByText('Apply via customized remote execution');
1082
1087
  expect(viaRexAction).toBeInTheDocument();
@@ -12,7 +12,8 @@
12
12
  "upgradable":false,
13
13
  "name":"horse",
14
14
  "stream":"1.4",
15
- "module_spec":"horse:1.4"
15
+ "module_spec":"horse:1.4",
16
+ "id":"1"
16
17
  },
17
18
  {
18
19
  "status":"unknown",
@@ -20,7 +21,8 @@
20
21
  "upgradable":false,
21
22
  "name":"monkey",
22
23
  "stream":"1.8",
23
- "module_spec":"monkey:1.8"
24
+ "module_spec":"monkey:1.8",
25
+ "id":"1"
24
26
  },
25
27
  {
26
28
  "status":"enabled",
@@ -28,7 +30,8 @@
28
30
  "upgradable":false,
29
31
  "name":"walrus",
30
32
  "stream":"2.4",
31
- "module_spec":"walrus:2.4"
33
+ "module_spec":"walrus:2.4",
34
+ "id":"3"
32
35
  }
33
36
  ]
34
37
  }