katello 4.7.3 → 4.8.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 (333) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +6 -4
  3. data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +15 -12
  4. data/app/controllers/katello/api/v2/capsule_content_controller.rb +0 -4
  5. data/app/controllers/katello/api/v2/content_export_incrementals_controller.rb +22 -81
  6. data/app/controllers/katello/api/v2/content_exports_controller.rb +11 -80
  7. data/app/controllers/katello/api/v2/content_imports_controller.rb +1 -0
  8. data/app/controllers/katello/api/v2/exports_controller.rb +130 -0
  9. data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +7 -8
  10. data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +8 -4
  11. data/app/controllers/katello/api/v2/organizations_controller.rb +3 -0
  12. data/app/controllers/katello/api/v2/package_groups_controller.rb +0 -52
  13. data/app/controllers/katello/concerns/api/v2/bulk_hosts_extensions.rb +4 -6
  14. data/app/controllers/katello/concerns/api/v2/registration_controller_extensions.rb +1 -2
  15. data/app/controllers/katello/concerns/authorization/api/v2/content_views_controller.rb +4 -1
  16. data/app/controllers/katello/concerns/content_facet_hosts_controller_extensions.rb +24 -0
  17. data/app/controllers/katello/concerns/hosts_controller_extensions.rb +3 -3
  18. data/app/helpers/katello/hosts_and_hostgroups_helper.rb +55 -24
  19. data/app/helpers/katello/katello_urls_helper.rb +0 -15
  20. data/app/helpers/katello/sync_management_helper.rb +0 -4
  21. data/app/lib/actions/candlepin/owner/destroy_imports.rb +1 -1
  22. data/app/lib/actions/katello/capsule_content/sync.rb +0 -4
  23. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +1 -2
  24. data/app/lib/actions/katello/content_view/publish.rb +6 -2
  25. data/app/lib/actions/katello/content_view/remove.rb +8 -2
  26. data/app/lib/actions/katello/content_view_version/destroy.rb +1 -1
  27. data/app/lib/actions/katello/environment/destroy.rb +8 -2
  28. data/app/lib/actions/katello/host/reassign.rb +4 -2
  29. data/app/lib/actions/katello/orphan_cleanup/remove_orphans.rb +0 -1
  30. data/app/lib/actions/katello/product/destroy.rb +2 -1
  31. data/app/lib/actions/katello/repository/filtered_index_content.rb +2 -10
  32. data/app/lib/actions/katello/repository/import_upload.rb +0 -1
  33. data/app/lib/actions/katello/repository/sync.rb +0 -1
  34. data/app/lib/actions/katello/repository/update.rb +5 -3
  35. data/app/lib/actions/katello/repository/upload_files.rb +0 -1
  36. data/app/lib/actions/pulp3/abstract.rb +0 -6
  37. data/app/lib/actions/pulp3/content_view/delete_repository_references.rb +1 -2
  38. data/app/lib/actions/pulp3/content_view_version/create_syncable_export_history.rb +4 -0
  39. data/app/lib/actions/pulp3/orchestration/content_view_version/export.rb +1 -0
  40. data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +7 -2
  41. data/app/lib/actions/pulp3/orchestration/content_view_version/syncable_export.rb +7 -2
  42. data/app/lib/actions/pulp3/repository/refresh_distribution.rb +1 -2
  43. data/app/lib/actions/pulp3/repository/save_distribution_references.rb +2 -2
  44. data/app/lib/katello/concerns/renderer_extensions.rb +1 -1
  45. data/app/lib/katello/event_daemon/runner.rb +12 -9
  46. data/app/lib/katello/resources/candlepin/consumer.rb +6 -6
  47. data/app/lib/katello/resources/candlepin/owner.rb +1 -1
  48. data/app/lib/katello/resources/candlepin/upstream_consumer.rb +3 -4
  49. data/app/lib/katello/resources/candlepin.rb +4 -4
  50. data/app/lib/katello/util/errata.rb +12 -10
  51. data/app/lib/katello/util/search.rb +0 -1
  52. data/app/lib/katello/validators/content_view_environment_org_validator.rb +5 -2
  53. data/app/lib/katello/validators/content_view_environment_validator.rb +1 -2
  54. data/app/lib/katello/validators/generated_content_view_validator.rb +16 -0
  55. data/app/mailers/katello/errata_mailer.rb +4 -2
  56. data/app/models/katello/alternate_content_source.rb +5 -1
  57. data/app/models/katello/concerns/content_facet_host_extensions.rb +25 -14
  58. data/app/models/katello/concerns/host_managed_extensions.rb +17 -8
  59. data/app/models/katello/concerns/redhat_extensions.rb +16 -6
  60. data/app/models/katello/concerns/smart_proxy_extensions.rb +0 -12
  61. data/app/models/katello/concerns/subscription_facet_host_extensions.rb +1 -0
  62. data/app/models/katello/content_view.rb +22 -5
  63. data/app/models/katello/content_view_environment.rb +11 -2
  64. data/app/models/katello/content_view_environment_content_facet.rb +9 -0
  65. data/app/models/katello/content_view_version.rb +10 -5
  66. data/app/models/katello/erratum.rb +6 -1
  67. data/app/models/katello/glue/candlepin/pool.rb +6 -0
  68. data/app/models/katello/glue/candlepin/product.rb +7 -1
  69. data/app/models/katello/glue/candlepin/subscription.rb +5 -0
  70. data/app/models/katello/glue/provider.rb +26 -26
  71. data/app/models/katello/host/content_facet.rb +106 -18
  72. data/app/models/katello/host/info_provider.rb +25 -21
  73. data/app/models/katello/host/subscription_facet.rb +18 -14
  74. data/app/models/katello/kt_environment.rb +12 -7
  75. data/app/models/katello/package_group.rb +0 -12
  76. data/app/models/katello/pool.rb +4 -1
  77. data/app/models/katello/product.rb +11 -1
  78. data/app/models/katello/repository.rb +11 -11
  79. data/app/models/katello/root_repository.rb +5 -4
  80. data/app/models/katello/task_status.rb +0 -18
  81. data/app/services/katello/candlepin/consumer.rb +2 -2
  82. data/app/services/katello/host/package_profile_uploader.rb +1 -1
  83. data/app/services/katello/product_content_finder.rb +11 -8
  84. data/app/services/katello/pulp3/content_view_version/export.rb +8 -65
  85. data/app/services/katello/pulp3/content_view_version/export_validation_error.rb +7 -0
  86. data/app/services/katello/pulp3/content_view_version/export_validator.rb +105 -0
  87. data/app/services/katello/pulp3/content_view_version/importable_products.rb +1 -1
  88. data/app/services/katello/pulp3/content_view_version/syncable_format_export.rb +7 -1
  89. data/app/services/katello/pulp3/erratum.rb +1 -0
  90. data/app/services/katello/pulp3/module_stream.rb +26 -11
  91. data/app/services/katello/pulp3/repository/yum.rb +2 -1
  92. data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +2 -1
  93. data/app/services/katello/registration_manager.rb +46 -26
  94. data/app/services/katello/repository_type.rb +3 -9
  95. data/app/services/katello/simple_package.rb +22 -0
  96. data/app/views/foreman/smart_proxies/_content_sync.html.erb +1 -0
  97. data/app/views/foreman/smart_proxies/_reclaim_space.html.erb +1 -0
  98. data/app/views/katello/api/v2/content_facet/base.json.rabl +23 -2
  99. data/app/views/katello/api/v2/content_facet/show.json.rabl +11 -8
  100. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -1
  101. data/app/views/katello/api/v2/hosts/base.json.rabl +22 -2
  102. data/app/views/overrides/activation_keys/_host_environment_select.html.erb +2 -2
  103. data/config/initializers/monkeys.rb +0 -2
  104. data/config/routes/api/registry.rb +8 -7
  105. data/config/routes/api/v2.rb +0 -2
  106. data/config/routes.rb +3 -0
  107. data/db/migrate/20200429153103_installed_package_bad_nvrea.rb +1 -1
  108. data/db/migrate/20220228173251_remove_drpm_from_ignorable_content.rb +7 -3
  109. data/db/migrate/20220419193414_content_settings_to_dsl_category.rb +1 -1
  110. data/db/migrate/20220929204746_add_content_view_environment_content_facet.rb +52 -0
  111. data/db/migrate/20221123212341_remove_pulp_docker_registry_port_setting.rb +5 -0
  112. data/db/seeds.d/111-upgrade_tasks.rb +2 -1
  113. data/engines/bastion/app/assets/stylesheets/bastion/bastion.scss +4 -0
  114. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-details.controller.js +2 -4
  115. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-errata-modal.controller.js +0 -1
  116. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details.controller.js +2 -4
  117. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +2 -1
  118. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/apply-errata.controller.js +11 -3
  119. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/views/host-collection-hosts-list.html +1 -1
  120. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +8 -4
  121. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de.po +5485 -0
  122. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/es.po +5397 -0
  123. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/fr.po +5658 -0
  124. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ja.po +5284 -0
  125. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ka.po +5231 -0
  126. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ko.po +5275 -0
  127. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pt_BR.po +5389 -0
  128. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_CN.po +5212 -0
  129. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_TW.po +5145 -0
  130. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/translations.js +9 -0
  131. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/views/content-access-mode-banner.html +2 -2
  132. data/lib/katello/engine.rb +2 -1
  133. data/lib/katello/permission_creator.rb +2 -4
  134. data/lib/katello/permissions/registry_permissions.rb +5 -5
  135. data/lib/katello/plugin.rb +22 -14
  136. data/lib/katello/repository_types/README.md +136 -19
  137. data/lib/katello/repository_types/deb.rb +0 -1
  138. data/lib/katello/repository_types/docker.rb +0 -1
  139. data/lib/katello/repository_types/file.rb +0 -1
  140. data/lib/katello/repository_types/yum.rb +0 -4
  141. data/lib/katello/tasks/clean_candlepin_orphaned_products.rake +38 -0
  142. data/lib/katello/tasks/clean_orphaned_facets.rb +20 -0
  143. data/lib/katello/tasks/reimport.rake +1 -2
  144. data/lib/katello/tasks/repository.rake +1 -22
  145. data/lib/katello/tasks/reset.rake +1 -0
  146. data/lib/katello/tasks/upgrades/4.8/fix_incorrect_providers.rake +29 -0
  147. data/lib/katello/version.rb +1 -1
  148. data/lib/katello.rb +0 -5
  149. data/locale/bn/katello.po +69 -27
  150. data/locale/cs/katello.po +69 -27
  151. data/locale/de/katello.po +78 -36
  152. data/locale/en/katello.po +69 -27
  153. data/locale/es/katello.po +70 -28
  154. data/locale/fr/katello.po +73 -31
  155. data/locale/gu/katello.po +69 -27
  156. data/locale/hi/katello.po +69 -27
  157. data/locale/it/katello.po +69 -27
  158. data/locale/ja/katello.po +73 -31
  159. data/locale/ka/katello.po +73 -31
  160. data/locale/katello.pot +335 -262
  161. data/locale/kn/katello.po +69 -27
  162. data/locale/ko/katello.po +69 -27
  163. data/locale/mr/katello.po +69 -27
  164. data/locale/or/katello.po +69 -27
  165. data/locale/pa/katello.po +69 -27
  166. data/locale/pt/katello.po +69 -27
  167. data/locale/pt_BR/katello.po +70 -28
  168. data/locale/ru/katello.po +70 -28
  169. data/locale/ta/katello.po +69 -27
  170. data/locale/te/katello.po +69 -27
  171. data/locale/zh_CN/katello.po +73 -31
  172. data/locale/zh_TW/katello.po +70 -28
  173. data/webpack/components/Content/ContentPage.js +51 -35
  174. data/webpack/components/Content/__tests__/ContentPage.test.js +2 -4
  175. data/webpack/components/Content/__tests__/__snapshots__/ContentPage.test.js.snap +22 -3
  176. data/webpack/components/Table/EmptyStateMessage.js +14 -11
  177. data/webpack/components/Table/MainTable.js +36 -15
  178. data/webpack/components/Table/TableWrapper.js +25 -25
  179. data/webpack/components/Table/__test__/emptyStateMessage.test.js +51 -0
  180. data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.js +5 -4
  181. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsModal.js +1 -1
  182. data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/__tests__/hostCollectionsModal.test.js +1 -17
  183. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +18 -9
  184. data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +1 -2
  185. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js +1 -2
  186. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +1 -2
  187. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +47 -27
  188. data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesTab.js +1 -2
  189. data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +2 -21
  190. data/webpack/components/extensions/HostDetails/Tabs/__tests__/moduleStreamsTab.test.js +1 -28
  191. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packageInstallModal.test.js +1 -10
  192. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +1 -18
  193. data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySetsTab.test.js +1 -17
  194. data/webpack/components/extensions/HostDetails/Tabs/__tests__/tracesTab.test.js +1 -15
  195. data/webpack/global_test_setup.js +1 -1
  196. data/webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js +12 -10
  197. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSCredentials.js +6 -0
  198. data/webpack/scenes/AlternateContentSources/Create/Steps/ACSSmartProxies.js +1 -0
  199. data/webpack/scenes/AlternateContentSources/Create/Steps/AcsUrlPaths.js +3 -10
  200. data/webpack/scenes/AlternateContentSources/Create/Steps/NameACS.js +1 -0
  201. data/webpack/scenes/AlternateContentSources/Create/__tests__/acsCreate.test.js +3 -3
  202. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditDetails.js +1 -0
  203. data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditURLPaths.js +12 -4
  204. data/webpack/scenes/AlternateContentSources/MainTable/ACSTable.js +7 -4
  205. data/webpack/scenes/AlternateContentSources/MainTable/__tests__/acsTable.test.js +4 -8
  206. data/webpack/scenes/AlternateContentSources/helpers.js +1 -1
  207. data/webpack/scenes/Content/Details/ContentRepositories.js +5 -4
  208. data/webpack/scenes/Content/Details/__tests__/contentDetail.test.js +1 -12
  209. data/webpack/scenes/Content/Table/ContentTable.js +2 -1
  210. data/webpack/scenes/Content/__tests__/contentTable.test.js +1 -14
  211. data/webpack/scenes/ContentViews/Delete/__tests__/contentViewDelete.test.js +1 -25
  212. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +2 -1
  213. data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/contentViewComponents.test.js +44 -31
  214. data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +2 -0
  215. data/webpack/scenes/ContentViews/Details/Filters/AffectedRepositories/AffectedRepositoryTable.js +6 -1
  216. data/webpack/scenes/ContentViews/Details/Filters/CVContainerImageFilterContent.js +2 -1
  217. data/webpack/scenes/ContentViews/Details/Filters/CVDebFilterContent.js +2 -1
  218. data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +3 -1
  219. data/webpack/scenes/ContentViews/Details/Filters/CVModuleStreamFilterContent.js +3 -1
  220. data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +3 -1
  221. data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +2 -1
  222. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilterDetailsHeader.js +2 -0
  223. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilters.js +2 -1
  224. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/CVDebMatchContentModal.js +1 -1
  225. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/CVRpmMatchContentModal.js +1 -1
  226. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/__tests__/CVRpmMatchContentModal.test.js +35 -33
  227. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVContainerImageFilterContent.test.js +48 -45
  228. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVRpmFilterContent.test.js +58 -24
  229. data/webpack/scenes/ContentViews/Details/Filters/__tests__/ContentViewPackageGroupFilter.test.js +64 -0
  230. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilterDetails.test.js +36 -20
  231. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilters.test.js +40 -23
  232. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvErrataIDFilter.test.js +0 -13
  233. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvModuleStreamFilter.test.js +0 -13
  234. data/webpack/scenes/ContentViews/Details/Histories/ContentViewHistories.js +2 -1
  235. data/webpack/scenes/ContentViews/Details/Histories/__tests__/contentViewHistory.test.js +1 -10
  236. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +2 -1
  237. data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewAddRemove.test.js +1 -10
  238. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareConfig.js +21 -9
  239. data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareTable.js +4 -0
  240. data/webpack/scenes/ContentViews/Details/Versions/Compare/__tests__/CVVersionCompare.test.js +1 -32
  241. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +3 -1
  242. data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/cvVersionRemove.test.js +1 -15
  243. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js +1 -1
  244. data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedHosts.js +1 -2
  245. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailConfig.js +31 -9
  246. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsTable.js +4 -0
  247. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetails.test.js +30 -14
  248. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +1 -1
  249. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +55 -120
  250. data/webpack/scenes/ContentViews/components/WizardHeader.js +1 -1
  251. data/webpack/scenes/ContentViews/expansions/RelatedContentViewComponentsModal.js +1 -1
  252. data/webpack/scenes/ContentViews/expansions/__tests__/contentViewComponentsModal.test.js +8 -1
  253. data/webpack/scenes/ModuleStreams/ModuleStreamsPage.js +3 -9
  254. data/webpack/scenes/ModuleStreams/__tests__/__snapshots__/ModuleStreamPage.test.js.snap +7 -1
  255. data/webpack/scenes/RedHatRepositories/components/Search.js +22 -16
  256. data/webpack/scenes/RedHatRepositories/index.scss +20 -1
  257. data/webpack/scenes/SmartProxy/SmartProxyContentTable.js +12 -1
  258. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnTypeForm.js +1 -1
  259. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CustomCdnTypeForm.js +1 -1
  260. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +21 -19
  261. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +34 -1
  262. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.js +20 -7
  263. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.test.js +0 -1
  264. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/__snapshots__/SubscriptionsToolbar.test.js.snap +65 -15
  265. metadata +47 -113
  266. data/app/lib/actions/katello/pulp_selector.rb +0 -24
  267. data/app/lib/actions/katello/repository/correct_checksum.rb +0 -24
  268. data/app/lib/actions/katello/repository/destroy_package_group.rb +0 -26
  269. data/app/lib/actions/katello/repository/upload_package_group.rb +0 -24
  270. data/app/lib/actions/pulp/abstract.rb +0 -37
  271. data/app/lib/actions/pulp/abstract_async_task.rb +0 -154
  272. data/app/lib/actions/pulp/abstract_async_task_group.rb +0 -94
  273. data/app/lib/actions/pulp/consumer/sync_capsule.rb +0 -45
  274. data/app/lib/actions/pulp/consumer/unassociate_units.rb +0 -20
  275. data/app/lib/actions/pulp/expect_one_task.rb +0 -11
  276. data/app/lib/actions/pulp/orchestration/orphan_cleanup/remove_orphans.rb +0 -16
  277. data/app/lib/actions/pulp/orchestration/repository/copy_all_units.rb +0 -19
  278. data/app/lib/actions/pulp/orchestration/repository/delete.rb +0 -15
  279. data/app/lib/actions/pulp/orchestration/repository/refresh.rb +0 -14
  280. data/app/lib/actions/pulp/orchestration/repository/refresh_if_needed.rb +0 -13
  281. data/app/lib/actions/pulp/orchestration/repository/refresh_repos.rb +0 -19
  282. data/app/lib/actions/pulp/orchestration/repository/remove_units.rb +0 -14
  283. data/app/lib/actions/pulp/orchestration/repository/smart_proxy_sync.rb +0 -34
  284. data/app/lib/actions/pulp/orchestration/repository/sync.rb +0 -18
  285. data/app/lib/actions/pulp/orchestration/repository/upload_content.rb +0 -37
  286. data/app/lib/actions/pulp/orphan_cleanup/remove_orphans.rb +0 -15
  287. data/app/lib/actions/pulp/orphan_cleanup/remove_unneeded_repos.rb +0 -16
  288. data/app/lib/actions/pulp/repository/abstract_copy_content.rb +0 -45
  289. data/app/lib/actions/pulp/repository/abstract_remove_content.rb +0 -32
  290. data/app/lib/actions/pulp/repository/clear.rb +0 -18
  291. data/app/lib/actions/pulp/repository/copy_all_units.rb +0 -30
  292. data/app/lib/actions/pulp/repository/copy_units.rb +0 -25
  293. data/app/lib/actions/pulp/repository/create.rb +0 -28
  294. data/app/lib/actions/pulp/repository/create_in_plan.rb +0 -15
  295. data/app/lib/actions/pulp/repository/create_upload_request.rb +0 -20
  296. data/app/lib/actions/pulp/repository/delete_upload_request.rb +0 -19
  297. data/app/lib/actions/pulp/repository/destroy.rb +0 -28
  298. data/app/lib/actions/pulp/repository/distributor_publish.rb +0 -25
  299. data/app/lib/actions/pulp/repository/download.rb +0 -16
  300. data/app/lib/actions/pulp/repository/import_upload.rb +0 -19
  301. data/app/lib/actions/pulp/repository/presenters/abstract_sync_presenter.rb +0 -47
  302. data/app/lib/actions/pulp/repository/presenters/deb_presenter.rb +0 -95
  303. data/app/lib/actions/pulp/repository/presenters/docker_presenter.rb +0 -103
  304. data/app/lib/actions/pulp/repository/presenters/file_unit_presenter.rb +0 -42
  305. data/app/lib/actions/pulp/repository/presenters/yum_presenter.rb +0 -131
  306. data/app/lib/actions/pulp/repository/refresh.rb +0 -21
  307. data/app/lib/actions/pulp/repository/regenerate_applicability.rb +0 -21
  308. data/app/lib/actions/pulp/repository/remove_distribution.rb +0 -11
  309. data/app/lib/actions/pulp/repository/remove_units.rb +0 -44
  310. data/app/lib/actions/pulp/repository/sync.rb +0 -99
  311. data/app/lib/actions/pulp/repository/upload_file.rb +0 -28
  312. data/app/lib/actions/pulp/repository_group/create.rb +0 -31
  313. data/app/lib/actions/pulp/repository_group/delete.rb +0 -17
  314. data/app/lib/actions/pulp/repository_group/export.rb +0 -51
  315. data/app/lib/katello/util/package_clause_generator.rb +0 -77
  316. data/app/models/katello/glue/pulp/pulp_errors.rb +0 -9
  317. data/app/models/katello/glue/pulp/repo.rb +0 -353
  318. data/app/models/katello/pulp_sync_status.rb +0 -165
  319. data/app/models/katello/pulp_task_status.rb +0 -63
  320. data/app/services/katello/pulp/content.rb +0 -24
  321. data/app/services/katello/pulp/importer_comparison.rb +0 -28
  322. data/app/services/katello/pulp/repository/deb.rb +0 -61
  323. data/app/services/katello/pulp/repository/docker.rb +0 -82
  324. data/app/services/katello/pulp/repository/file.rb +0 -52
  325. data/app/services/katello/pulp/repository/yum.rb +0 -205
  326. data/app/services/katello/pulp/repository.rb +0 -327
  327. data/app/services/katello/pulp/server.rb +0 -35
  328. data/app/services/katello/pulp/simple_package.rb +0 -24
  329. data/app/services/katello/pulp/smart_proxy_repository.rb +0 -52
  330. data/lib/monkeys/fix_deb_optimized_sync.rb +0 -35
  331. data/lib/monkeys/fix_pulp_container_path.rb +0 -35
  332. data/locale/zanata.xml +0 -30
  333. data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/__tests__/CVRpmMatchContentSearch.fixtures.json +0 -33
@@ -1,16 +1,15 @@
1
1
  import React from 'react';
2
2
  import { shallow } from 'enzyme';
3
3
  import toJson from 'enzyme-to-json';
4
+ import SearchBar from 'foremanReact/components/SearchBar';
4
5
  import ContentPage from '../ContentPage';
5
6
  import ContentTable from '../ContentTable';
6
- import Search from '../../../components/Search/index';
7
7
 
8
8
  describe('Content page', () => {
9
9
  it('should render and contain appropriate components', async () => {
10
10
  const contentHeader = 'Content Header';
11
11
  const content = {};
12
12
  const onSearch = () => {};
13
- const getAutoCompleteParams = () => {};
14
13
  const updateSearchQuery = () => {};
15
14
  const searchQuery = '';
16
15
  const onPaginationChange = () => {};
@@ -21,7 +20,6 @@ describe('Content page', () => {
21
20
  content={content}
22
21
  tableSchema={TableSchema}
23
22
  onSearch={onSearch}
24
- getAutoCompleteParams={getAutoCompleteParams}
25
23
  updateSearchQuery={updateSearchQuery}
26
24
  initialInputValue={searchQuery}
27
25
  onPaginationChange={onPaginationChange}
@@ -29,6 +27,6 @@ describe('Content page', () => {
29
27
 
30
28
  expect(toJson(wrapper)).toMatchSnapshot();
31
29
  expect(wrapper.find(ContentTable)).toHaveLength(1);
32
- expect(wrapper.find(Search)).toHaveLength(1);
30
+ expect(wrapper.find(SearchBar)).toHaveLength(1);
33
31
  });
34
32
  });
@@ -40,11 +40,30 @@ exports[`Content page should render and contain appropriate components 1`] = `
40
40
  bsClass="form-group"
41
41
  className="toolbar-pf toolbar-pf-filter"
42
42
  >
43
- <Connect(Search)
44
- getAutoCompleteParams={[Function]}
43
+ <SearchBar
44
+ data={
45
+ Object {
46
+ "autocomplete": Object {
47
+ "apiParams": Object {},
48
+ "id": "searchBar-content-page-Content Header",
49
+ "searchQuery": "",
50
+ "url": "undefined/auto_complete_search",
51
+ "useKeyShortcuts": true,
52
+ },
53
+ "bookmarks": Object {
54
+ "canCreate": true,
55
+ "documentationUrl": "/links/manual/4.1.5Searching",
56
+ "id": "searchBar-content-page-Content Header",
57
+ "url": "/api/bookmarks",
58
+ },
59
+ "controller": undefined,
60
+ }
61
+ }
45
62
  initialInputValue=""
63
+ initialQuery=""
64
+ name={null}
46
65
  onSearch={[Function]}
47
- updateSearchQuery={[Function]}
66
+ onSearchChange={[Function]}
48
67
  />
49
68
  </FormGroup>
50
69
  </Form>
@@ -33,9 +33,9 @@ const EmptyStateMessage = ({
33
33
  let emptyStateTitle = title;
34
34
  let emptyStateBody = body;
35
35
  const {
36
- primaryActionTitle, showPrimaryAction, showSecondaryAction,
36
+ primaryActionTitle, showPrimaryAction, showSecondaryAction, showSecondaryActionButton,
37
37
  secondaryActionTitle, primaryActionLink, secondaryActionLink, searchIsActive, resetFilters,
38
- filtersAreActive, requestKey, primaryActionButton,
38
+ filtersAreActive, requestKey, primaryActionButton, secondaryActionTextOverride,
39
39
  } = extraTableProps;
40
40
  if (error) {
41
41
  if (error?.response?.data?.error) {
@@ -48,14 +48,16 @@ const EmptyStateMessage = ({
48
48
  emptyStateBody = error?.response?.data?.displayMessage || __('Something went wrong! Please check server logs!');
49
49
  }
50
50
  }
51
- const secondaryActionText = searchIsActive ? __('Clear search') : __('Clear filters');
51
+ const defaultSecondaryActionText = searchIsActive ? __('Clear search') : __('Clear filters');
52
+ const secondaryActionText = secondaryActionTextOverride || defaultSecondaryActionText;
52
53
  const dispatch = useDispatch();
53
54
  const clearSearch = useSelector(selectHostDetailsClearSearch);
55
+ const showSecondaryActionAnchor = showSecondaryAction && secondaryActionLink;
54
56
  const handleClick = () => {
55
57
  if (searchIsActive) {
56
58
  clearSearch();
57
59
  }
58
- if (filtersAreActive) {
60
+ if (filtersAreActive || showSecondaryActionButton) {
59
61
  resetFilters();
60
62
  }
61
63
  dispatch({
@@ -65,7 +67,7 @@ const EmptyStateMessage = ({
65
67
  };
66
68
 
67
69
  const actionButton = primaryActionButton ?? (
68
- <Button>
70
+ <Button ouiaId="empty-state-primary-action-button">
69
71
  <a href={primaryActionLink} style={{ color: 'white', textDecoration: 'none' }}>{primaryActionTitle}</a>
70
72
  </Button>
71
73
  );
@@ -87,17 +89,17 @@ const EmptyStateMessage = ({
87
89
  {emptyStateBody}
88
90
  </EmptyStateBody>
89
91
  {showPrimaryAction && actionButton}
90
- {showSecondaryAction &&
92
+ {showSecondaryActionAnchor &&
91
93
  <EmptyStateSecondaryActions>
92
- <Button variant="link">
94
+ <Button variant="link" ouiaId="empty-state-secondary-action-link">
93
95
  <a href={secondaryActionLink} style={{ textDecoration: 'none' }}>{secondaryActionTitle}</a>
94
96
  </Button>
95
97
  </EmptyStateSecondaryActions>
96
98
  }
97
99
 
98
- {(searchIsActive || !!filtersAreActive) &&
100
+ {(showSecondaryActionButton || searchIsActive || !!filtersAreActive) &&
99
101
  <EmptyStateSecondaryActions>
100
- <Button variant="link" onClick={handleClick}>
102
+ <Button variant="link" onClick={handleClick} ouiaId="empty-state-secondary-action-router-link">
101
103
  {secondaryActionText}
102
104
  </Button>
103
105
  </EmptyStateSecondaryActions>
@@ -143,9 +145,10 @@ EmptyStateMessage.propTypes = {
143
145
  ])),
144
146
  // eslint-disable-next-line react/require-default-props
145
147
  resetFilters: (props, propName) => {
146
- if (props.defaultFilters?.length || props.activeFilters?.length) {
148
+ if (props.showSecondaryActionButton || props.defaultFilters?.length
149
+ || props.activeFilters?.length) {
147
150
  if (typeof props[propName] !== 'function') {
148
- return new Error(`A ${propName} function is required when using activeFilters or defaultFilters`);
151
+ return new Error(`A ${propName} function is required when using activeFilters, defaultFilters, or showSecondaryActionButton`);
149
152
  }
150
153
  }
151
154
  return null;
@@ -16,11 +16,12 @@ import Loading from '../../components/Loading';
16
16
 
17
17
  const MainTable = ({
18
18
  status, cells, rows, error, emptyContentTitle, emptyContentBody,
19
- emptySearchTitle, emptySearchBody, errorSearchTitle, errorSearchBody,
20
- happyEmptyContent, searchIsActive, activeFilters, defaultFilters, actionButtons, rowsCount,
21
- children, showPrimaryAction, showSecondaryAction, primaryActionLink,
22
- secondaryActionLink, primaryActionTitle, secondaryActionTitle, resetFilters,
23
- updateSearchQuery, requestKey, primaryActionButton, ...extraTableProps
19
+ emptyContentOverride, emptySearchTitle, emptySearchBody, errorSearchTitle, errorSearchBody,
20
+ happyEmptyContent, searchIsActive, activeFilters, defaultFilters,
21
+ activeToggleState, unfilteredToggleState, actionButtons, rowsCount,
22
+ children, showPrimaryAction, showSecondaryAction, showSecondaryActionButton, primaryActionLink,
23
+ secondaryActionLink, primaryActionTitle, secondaryActionTitle, secondaryActionTextOverride,
24
+ resetFilters, updateSearchQuery, requestKey, primaryActionButton, ...extraTableProps
24
25
  }) => {
25
26
  const tableHasNoRows = () => {
26
27
  if (children) return rowsCount === 0;
@@ -29,15 +30,20 @@ const MainTable = ({
29
30
  const callToActionProps = {
30
31
  showPrimaryAction,
31
32
  showSecondaryAction,
33
+ showSecondaryActionButton,
32
34
  primaryActionLink,
33
35
  primaryActionTitle,
34
36
  secondaryActionLink,
35
37
  secondaryActionTitle,
36
38
  primaryActionButton,
39
+ secondaryActionTextOverride,
40
+ emptyContentOverride,
37
41
  };
38
42
  const filtersAreActive = activeFilters?.length &&
39
43
  !isEqual(new Set(activeFilters), new Set(defaultFilters));
40
- const isFiltering = searchIsActive || filtersAreActive;
44
+ const toggleIsActive = activeToggleState !== unfilteredToggleState;
45
+ const isSearchingOrFiltering = searchIsActive || filtersAreActive || toggleIsActive;
46
+
41
47
  if (status === STATUS.PENDING) return (<Loading />);
42
48
  const clearSearchProps = {
43
49
  resetFilters,
@@ -48,6 +54,10 @@ const MainTable = ({
48
54
  defaultFilters,
49
55
  activeFilters,
50
56
  };
57
+
58
+ const tableWouldBeEmpty = (status === STATUS.RESOLVED && tableHasNoRows());
59
+ const emptyContent = emptyContentOverride || (tableWouldBeEmpty && !isSearchingOrFiltering);
60
+ const emptySearch = (tableWouldBeEmpty && isSearchingOrFiltering);
51
61
  // Can we display the error message?
52
62
  if (status === STATUS.ERROR) return (<EmptyStateMessage error={error} />);
53
63
 
@@ -60,25 +70,26 @@ const MainTable = ({
60
70
  search
61
71
  />);
62
72
  }
63
- if (status === STATUS.RESOLVED && isFiltering && tableHasNoRows()) {
64
- return (<EmptyStateMessage
65
- title={emptySearchTitle}
66
- body={emptySearchBody}
67
- search
68
- {...clearSearchProps}
69
- />);
70
- }
71
- if (status === STATUS.RESOLVED && tableHasNoRows()) {
73
+ if (emptyContent) {
72
74
  return (
73
75
  <EmptyStateMessage
74
76
  title={emptyContentTitle}
75
77
  body={emptyContentBody}
76
78
  happy={happyEmptyContent}
77
79
  search={!happyEmptyContent}
80
+ {...clearSearchProps}
78
81
  {...callToActionProps}
79
82
  />
80
83
  );
81
84
  }
85
+ if (emptySearch) {
86
+ return (<EmptyStateMessage
87
+ title={emptySearchTitle}
88
+ body={emptySearchBody}
89
+ search
90
+ {...clearSearchProps}
91
+ />);
92
+ }
82
93
 
83
94
  const tableProps = { cells, rows, ...extraTableProps };
84
95
  if (children) {
@@ -129,6 +140,8 @@ MainTable.propTypes = {
129
140
  PropTypes.string,
130
141
  PropTypes.arrayOf(PropTypes.string),
131
142
  ])),
143
+ activeToggleState: PropTypes.string,
144
+ unfilteredToggleState: PropTypes.string,
132
145
  actionButtons: PropTypes.bool,
133
146
  rowsCount: PropTypes.number,
134
147
  children: PropTypes.oneOfType([
@@ -136,8 +149,11 @@ MainTable.propTypes = {
136
149
  PropTypes.node,
137
150
  ]),
138
151
  happyEmptyContent: PropTypes.bool,
152
+ emptyContentOverride: PropTypes.bool,
139
153
  showPrimaryAction: PropTypes.bool,
140
154
  showSecondaryAction: PropTypes.bool,
155
+ showSecondaryActionButton: PropTypes.bool,
156
+ secondaryActionTextOverride: PropTypes.string,
141
157
  primaryActionLink: PropTypes.string,
142
158
  secondaryActionLink: PropTypes.string,
143
159
  secondaryActionTitle: PropTypes.string,
@@ -153,6 +169,8 @@ MainTable.defaultProps = {
153
169
  searchIsActive: false,
154
170
  activeFilters: [],
155
171
  defaultFilters: [],
172
+ activeToggleState: '',
173
+ unfilteredToggleState: '',
156
174
  errorSearchTitle: __('Problem searching'),
157
175
  errorSearchBody: '',
158
176
  actionButtons: false,
@@ -161,8 +179,11 @@ MainTable.defaultProps = {
161
179
  rows: undefined,
162
180
  rowsCount: undefined,
163
181
  happyEmptyContent: false,
182
+ emptyContentOverride: false,
164
183
  showPrimaryAction: false,
165
184
  showSecondaryAction: false,
185
+ showSecondaryActionButton: false,
186
+ secondaryActionTextOverride: '',
166
187
  primaryActionLink: '',
167
188
  secondaryActionLink: '',
168
189
  primaryActionTitle: '',
@@ -2,8 +2,9 @@ import React, { useCallback, useRef } from 'react';
2
2
  import useDeepCompareEffect from 'use-deep-compare-effect';
3
3
  import PropTypes from 'prop-types';
4
4
  import { useDispatch } from 'react-redux';
5
- import { isEqual } from 'lodash';
6
- import { STATUS } from 'foremanReact/constants';
5
+ import { isEqual, isEmpty } from 'lodash';
6
+ import SearchBar from 'foremanReact/components/SearchBar';
7
+ import { STATUS, getControllerSearchProps } from 'foremanReact/constants';
7
8
  import { noop } from 'foremanReact/common/helpers';
8
9
  import { useForemanSettings } from 'foremanReact/Root/Context/ForemanContext';
9
10
  import { PaginationVariant, Flex, FlexItem } from '@patternfly/react-core';
@@ -11,7 +12,6 @@ import { translate as __ } from 'foremanReact/common/I18n';
11
12
  import PageControls from './PageControls';
12
13
  import MainTable from './MainTable';
13
14
  import { getPageStats } from './helpers';
14
- import Search from '../../components/Search';
15
15
  import SelectAllCheckbox from '../SelectAllCheckbox';
16
16
  import { orgId } from '../../services/api';
17
17
 
@@ -25,7 +25,7 @@ const TableWrapper = ({
25
25
  metadata,
26
26
  fetchItems,
27
27
  autocompleteEndpoint,
28
- foremanApiAutoComplete,
28
+ autocompleteQueryParams,
29
29
  searchQuery,
30
30
  updateSearchQuery,
31
31
  searchPlaceholderText,
@@ -43,6 +43,7 @@ const TableWrapper = ({
43
43
  clearSelectedResults,
44
44
  emptySearchBody,
45
45
  hideSearch,
46
+ alwaysHideToolbar,
46
47
  nodesBelowSearch,
47
48
  bookmarkController,
48
49
  readOnlyBookmarks,
@@ -60,8 +61,8 @@ const TableWrapper = ({
60
61
  const showPagination = !unresolvedStatusOrNoRows;
61
62
  const filtersAreActive = activeFilters?.length &&
62
63
  !isEqual(new Set(activeFilters), new Set(allTableProps.defaultFilters));
63
- const hideToolbar = !searchQuery && !filtersAreActive &&
64
- allTableProps.status === STATUS.RESOLVED && total === 0;
64
+ const hideToolbar = alwaysHideToolbar || (!searchQuery && !filtersAreActive &&
65
+ allTableProps.status === STATUS.RESOLVED && total === 0);
65
66
  const showActionButtons = actionButtons && (alwaysShowActionButtons || !hideToolbar);
66
67
  const showToggleGroup = toggleGroup && (alwaysShowToggleGroup || !hideToolbar);
67
68
  const paginationParams = useCallback(() =>
@@ -131,14 +132,6 @@ const TableWrapper = ({
131
132
  spawnFetch();
132
133
  }, [searchQuery, spawnFetch, additionalListeners]);
133
134
 
134
- const getAutoCompleteParams = search => ({
135
- endpoint: autocompleteEndpoint,
136
- params: {
137
- organization_id: orgId(),
138
- search,
139
- },
140
- });
141
-
142
135
  // If the new page wouldn't exist because of a perPage change,
143
136
  // we should set the current page to the last page.
144
137
  const validatePagination = (data) => {
@@ -164,6 +157,17 @@ const TableWrapper = ({
164
157
  spawnFetch(pagData);
165
158
  paginationChangePending.current = pagData;
166
159
  };
160
+
161
+ const extraSearchProps = (isEmpty(bookmarkController)) ?
162
+ { bookmarks: {} } :
163
+ { controller: bookmarkController };
164
+ const apiParams = { ...autocompleteQueryParams, organization_id: orgId() };
165
+ const searchDataProp = {
166
+ ...getControllerSearchProps(autocompleteEndpoint, `searchBar-${bookmarkController}`, !readOnlyBookmarks, apiParams),
167
+ ...extraSearchProps,
168
+ isDisabled: unresolvedStatusOrNoRows && !searchQuery,
169
+ };
170
+
167
171
  return (
168
172
  <>
169
173
  <Flex style={{ alignItems: 'center' }} className="margin-16-24">
@@ -186,16 +190,10 @@ const TableWrapper = ({
186
190
  }
187
191
  {!hideSearch && !hideToolbar &&
188
192
  <FlexItem>
189
- <Search
190
- isDisabled={unresolvedStatusOrNoRows && !searchQuery}
191
- patternfly4
192
- initialInputValue={searchQuery && searchQuery}
193
+ <SearchBar
194
+ data={searchDataProp}
195
+ initialQuery={searchQuery}
193
196
  onSearch={search => updateSearchQuery(search)}
194
- getAutoCompleteParams={getAutoCompleteParams}
195
- foremanApiAutoComplete={foremanApiAutoComplete}
196
- bookmarkController={bookmarkController}
197
- readOnlyBookmarks={readOnlyBookmarks}
198
- placeholder={searchPlaceholderText}
199
197
  />
200
198
  </FlexItem>
201
199
  }
@@ -272,7 +270,7 @@ TableWrapper.propTypes = {
272
270
  search: PropTypes.string,
273
271
  }),
274
272
  autocompleteEndpoint: PropTypes.string.isRequired,
275
- foremanApiAutoComplete: PropTypes.bool,
273
+ autocompleteQueryParams: PropTypes.shape({}),
276
274
  searchPlaceholderText: PropTypes.string,
277
275
  actionButtons: PropTypes.node,
278
276
  alwaysShowActionButtons: PropTypes.bool,
@@ -305,6 +303,7 @@ TableWrapper.propTypes = {
305
303
  areAllRowsSelected: PropTypes.func,
306
304
  emptySearchBody: PropTypes.string,
307
305
  hideSearch: PropTypes.bool,
306
+ alwaysHideToolbar: PropTypes.bool,
308
307
  nodesBelowSearch: PropTypes.node,
309
308
  bookmarkController: PropTypes.string,
310
309
  readOnlyBookmarks: PropTypes.bool,
@@ -317,7 +316,6 @@ TableWrapper.defaultProps = {
317
316
  additionalListeners: [],
318
317
  activeFilters: [],
319
318
  defaultFilters: [],
320
- foremanApiAutoComplete: false,
321
319
  searchPlaceholderText: undefined,
322
320
  actionButtons: null,
323
321
  alwaysShowActionButtons: true,
@@ -335,10 +333,12 @@ TableWrapper.defaultProps = {
335
333
  areAllRowsSelected: noop,
336
334
  emptySearchBody: __('Try changing your search settings.'),
337
335
  hideSearch: false,
336
+ alwaysHideToolbar: false,
338
337
  nodesBelowSearch: null,
339
338
  bookmarkController: undefined,
340
339
  readOnlyBookmarks: false,
341
340
  resetFilters: undefined,
341
+ autocompleteQueryParams: undefined,
342
342
  };
343
343
 
344
344
  export default TableWrapper;
@@ -0,0 +1,51 @@
1
+ import React from 'react';
2
+ import { renderWithRedux, patientlyWaitFor } from 'react-testing-lib-wrapper';
3
+ import EmptyStateMessage from '../EmptyStateMessage';
4
+
5
+ describe('EmptyStateMessage', () => {
6
+ test('Shows clear search link when there are no results', async (done) => {
7
+ const { getByText } = renderWithRedux(<EmptyStateMessage
8
+ title="empty content title"
9
+ body="empty content body"
10
+ search
11
+ searchIsActive
12
+ />);
13
+
14
+ // Verify that the clear search link is visible
15
+ await patientlyWaitFor(() => expect(getByText('Clear search')).toBeInTheDocument());
16
+
17
+ done();
18
+ });
19
+
20
+ test('Shows clear filters link when there are no results', async (done) => {
21
+ const { getByText } = renderWithRedux(<EmptyStateMessage
22
+ title="empty content title"
23
+ body="empty content body"
24
+ search
25
+ filtersAreActive
26
+ activeFilters={['foo']}
27
+ resetFilters={jest.fn()}
28
+ />);
29
+
30
+ // Verify that the clear filters link is visible
31
+ await patientlyWaitFor(() => expect(getByText('Clear filters')).toBeInTheDocument());
32
+
33
+ done();
34
+ });
35
+
36
+ test('Handles override of secondaryActionText', async (done) => {
37
+ const { getByText } = renderWithRedux(<EmptyStateMessage
38
+ title="empty content title"
39
+ body="empty content body"
40
+ resetFilters={jest.fn()}
41
+ showSecondaryActionButton
42
+ secondaryActionTextOverride="Custom text"
43
+ />);
44
+
45
+ // Verify that the custom text is visible
46
+ await patientlyWaitFor(() => expect(getByText('Custom text')).toBeInTheDocument());
47
+
48
+ done();
49
+ });
50
+ });
51
+
@@ -20,6 +20,7 @@ import { TranslatedAnchor } from '../../../Table/components/TranslatedPlural';
20
20
  import EmptyStateMessage from '../../../Table/EmptyStateMessage';
21
21
  import './ErrataOverviewCard.scss';
22
22
  import { errataStatusContemplation } from '../../../Errata/errataHelpers';
23
+ import { pluralize } from '../../../../utils/helpers';
23
24
 
24
25
  function HostInstallableErrata({
25
26
  id, errataCounts, errataStatus, errataCategory, errataStatusLabel,
@@ -31,11 +32,11 @@ function HostInstallableErrata({
31
32
  const errataEnhance = counts.enhancement;
32
33
  const { neededErrata, allUpToDate, otherErrataStatus } = errataStatusContemplation(errataStatus);
33
34
  const chartData = [{
34
- w: 'security advisories', x: 'security', y: errataSecurity, z: errataTotal,
35
+ w: __('security advisories'), singular: __('security advisory'), x: 'security', y: errataSecurity, z: errataTotal,
35
36
  }, {
36
- w: 'bug fixes', x: 'bugfix', y: errataBug, z: errataTotal,
37
+ w: __('bug fixes'), singular: __('bug fix'), x: 'bugfix', y: errataBug, z: errataTotal,
37
38
  }, {
38
- w: 'enhancements', x: 'enhancement', y: errataEnhance, z: errataTotal,
39
+ w: __('enhancements'), singular: __('enhancement'), x: 'enhancement', y: errataEnhance, z: errataTotal,
39
40
  }];
40
41
  return (
41
42
  <CardBody>
@@ -75,7 +76,7 @@ function HostInstallableErrata({
75
76
  ariaDesc="errataChart"
76
77
  data={chartData}
77
78
  constrainToVisibleArea
78
- labels={({ datum }) => `${datum.y} ${datum.w}`}
79
+ labels={({ datum }) => pluralize(datum.y, datum.singular, datum.w)}
79
80
  padding={{
80
81
  bottom: 20,
81
82
  left: 20,
@@ -169,7 +169,7 @@ export const HostCollectionsModal = ({
169
169
  additionalListeners={[hostId, modalType, existingHostCollectionIds.join(',')]}
170
170
  fetchItems={fetchItems}
171
171
  searchPlaceholderText={__('Search host collections')}
172
- autocompleteEndpoint="/host_collections/auto_complete_search"
172
+ autocompleteEndpoint="/katello/api/v2/host_collections"
173
173
  variant={TableVariant.compact}
174
174
  {...selectAll}
175
175
  displaySelectAllCheckbox={results?.length > 0}
@@ -3,7 +3,7 @@ import { renderWithRedux, patientlyWaitFor, fireEvent } from 'react-testing-lib-
3
3
  import mockAvailableHostCollections from './availableHostCollections.fixtures.json';
4
4
  import mockRemovableHostCollections from './removableHostCollections.fixtures.json';
5
5
  import { REMOVABLE_HOST_COLLECTIONS_KEY } from '../HostCollectionsConstants';
6
- import { assertNockRequest, mockAutocomplete, mockSetting, nockInstance } from '../../../../../../test-utils/nockWrapper';
6
+ import { assertNockRequest, mockAutocomplete, nockInstance } from '../../../../../../test-utils/nockWrapper';
7
7
  import katelloApi, { foremanApi } from '../../../../../../services/api';
8
8
  import { HostCollectionsAddModal, HostCollectionsRemoveModal } from '../HostCollectionsModal';
9
9
 
@@ -38,20 +38,11 @@ const defaultQueryWithAvailable = {
38
38
  };
39
39
 
40
40
  let firstHostCollection;
41
- let searchDelayScope;
42
- let autoSearchScope;
43
41
 
44
42
  describe('HostCollectionsAddModal', () => {
45
43
  beforeEach(() => {
46
44
  const { results } = mockAvailableHostCollections;
47
45
  [firstHostCollection] = results;
48
- searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 500);
49
- autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing', true);
50
- });
51
-
52
- afterEach(() => {
53
- assertNockRequest(searchDelayScope);
54
- assertNockRequest(autoSearchScope);
55
46
  });
56
47
 
57
48
  test('Calls API with available_for=host on page load', async (done) => {
@@ -153,13 +144,6 @@ describe('HostCollectionsRemoveModal', () => {
153
144
  beforeEach(() => {
154
145
  const { results } = mockAvailableHostCollections;
155
146
  [firstHostCollection] = results;
156
- searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 500);
157
- autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing', true);
158
- });
159
-
160
- afterEach(() => {
161
- assertNockRequest(searchDelayScope);
162
- assertNockRequest(autoSearchScope);
163
147
  });
164
148
 
165
149
  test('Calls API without available_for=host on page load', async (done) => {
@@ -99,7 +99,18 @@ export const ErrataTab = () => {
99
99
  const { allUpToDate, neededErrata } = errataStatusContemplation(errataStatus);
100
100
  const emptySearchTitle = __('No matching errata found');
101
101
  const emptySearchBody = __('Try changing your search settings.');
102
+ const resetFiltersOnly = () => {
103
+ setErrataTypeSelected(ERRATA_TYPE);
104
+ setErrataSeveritySelected(ERRATA_SEVERITY);
105
+ };
106
+
107
+ const resetFiltersAndToggle = () => {
108
+ resetFiltersOnly();
109
+ setToggleGroupState(APPLICABLE);
110
+ };
102
111
 
112
+ let resetFilters = resetFiltersOnly;
113
+ let secondaryActionTextOverride;
103
114
  let emptyContentTitle;
104
115
  let emptyContentBody;
105
116
  switch (friendlyErrataStatus(errataStatus)) {
@@ -108,8 +119,10 @@ export const ErrataTab = () => {
108
119
  emptyContentBody = __('No action is needed because there are no applicable errata for this host.');
109
120
  break;
110
121
  case 'Needed':
111
- emptyContentTitle = __('This host has errata that are applicable, but not installable.');
112
- emptyContentBody = __("You may want to check the host's content view and lifecycle environment.");
122
+ emptyContentTitle = __('No matching errata found');
123
+ emptyContentBody = __('This host has errata that are applicable, but not installable. Adjust your filters and try again.');
124
+ resetFilters = resetFiltersAndToggle;
125
+ secondaryActionTextOverride = __('View applicable errata');
113
126
  break;
114
127
  case 'Unknown':
115
128
  emptyContentTitle = __('Unknown errata status');
@@ -286,11 +299,6 @@ export const ErrataTab = () => {
286
299
  }
287
300
  };
288
301
 
289
- const resetFilters = () => {
290
- setErrataTypeSelected(ERRATA_TYPE);
291
- setErrataSeveritySelected(ERRATA_SEVERITY);
292
- };
293
-
294
302
  const readOnlyBookmarks =
295
303
  cannot(createBookmarks, userPermissionsFromHostDetails({ hostDetails }));
296
304
 
@@ -476,8 +484,10 @@ export const ErrataTab = () => {
476
484
  selectNone,
477
485
  toggleGroup,
478
486
  resetFilters,
487
+ secondaryActionTextOverride,
479
488
  }
480
489
  }
490
+ showSecondaryActionButton={neededErrata}
481
491
  happyEmptyContent={allUpToDate}
482
492
  ouiaId="host-errata-table"
483
493
  additionalListeners={[
@@ -487,8 +497,7 @@ export const ErrataTab = () => {
487
497
  fetchItems={fetchItems}
488
498
  bookmarkController="katello_errata"
489
499
  readOnlyBookmarks={readOnlyBookmarks}
490
- autocompleteEndpoint={`/hosts/${hostId}/errata/auto_complete_search`}
491
- foremanApiAutoComplete
500
+ autocompleteEndpoint={`/api/v2/hosts/${hostId}/errata`}
492
501
  rowsCount={results?.length}
493
502
  variant={TableVariant.compact}
494
503
  {...selectAll}
@@ -379,8 +379,7 @@ export const ModuleStreamsTab = () => {
379
379
  fetchItems={fetchItems}
380
380
  bookmarkController="katello_host_available_module_streams"
381
381
  readOnlyBookmarks={hideBookmarkActions}
382
- autocompleteEndpoint={`/hosts/${hostId}/module_streams/auto_complete_search`}
383
- foremanApiAutoComplete
382
+ autocompleteEndpoint={`/api/v2/hosts/${hostId}/module_streams`}
384
383
  rowsCount={results?.length}
385
384
  variant={TableVariant.compact}
386
385
  requestKey={MODULE_STREAMS_KEY}
@@ -219,8 +219,7 @@ const PackageInstallModal = ({
219
219
  additionalListeners={[hostId]}
220
220
  fetchItems={fetchItems}
221
221
  searchPlaceholderText={__('Search available packages')}
222
- autocompleteEndpoint={`/hosts/${hostId}/packages/auto_complete_search`}
223
- foremanApiAutoComplete
222
+ autocompleteEndpoint={`/api/v2/hosts/${hostId}/packages`}
224
223
  variant={TableVariant.compact}
225
224
  {...selectAll}
226
225
  displaySelectAllCheckbox
@@ -521,8 +521,7 @@ export const PackagesTab = () => {
521
521
  fetchItems={fetchItems}
522
522
  bookmarkController="katello_host_installed_packages"
523
523
  readOnlyBookmarks={readOnlyBookmarks}
524
- autocompleteEndpoint={`/hosts/${hostId}/packages/auto_complete_search`}
525
- foremanApiAutoComplete
524
+ autocompleteEndpoint={`/api/v2/hosts/${hostId}/packages`}
526
525
  rowsCount={results?.length}
527
526
  variant={TableVariant.compact}
528
527
  {...selectAll}