katello 4.3.0.rc1 → 4.3.0.rc4

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 (299) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/api_controller.rb +4 -0
  3. data/app/controllers/katello/api/v2/capsule_content_controller.rb +11 -3
  4. data/app/controllers/katello/api/v2/content_uploads_controller.rb +1 -1
  5. data/app/controllers/katello/api/v2/generic_content_units_controller.rb +10 -4
  6. data/app/controllers/katello/api/v2/host_errata_controller.rb +5 -0
  7. data/app/controllers/katello/api/v2/host_packages_controller.rb +2 -0
  8. data/app/controllers/katello/api/v2/host_tracer_controller.rb +4 -0
  9. data/app/controllers/katello/api/v2/repositories_bulk_actions_controller.rb +8 -0
  10. data/app/controllers/katello/api/v2/repositories_controller.rb +35 -3
  11. data/app/controllers/katello/api/v2/repository_sets_controller.rb +2 -2
  12. data/app/controllers/katello/api/v2/root_controller.rb +10 -19
  13. data/app/controllers/katello/concerns/api/v2/bulk_extensions.rb +3 -13
  14. data/app/controllers/katello/concerns/api/v2/registration_controller_extensions.rb +1 -9
  15. data/app/controllers/katello/remote_execution_controller.rb +1 -1
  16. data/app/lib/actions/katello/capsule_content/refresh_repos.rb +1 -1
  17. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +7 -5
  18. data/app/lib/actions/katello/repository/destroy.rb +3 -3
  19. data/app/lib/actions/katello/repository/import_upload.rb +12 -2
  20. data/app/lib/actions/pulp/repository/sync.rb +0 -2
  21. data/app/lib/actions/pulp3/abstract_async_task.rb +16 -4
  22. data/app/lib/actions/pulp3/capsule_content/generate_metadata.rb +5 -4
  23. data/app/lib/actions/pulp3/capsule_content/reclaim_space.rb +25 -0
  24. data/app/lib/actions/pulp3/orchestration/repository/import_repository_upload.rb +36 -0
  25. data/app/lib/actions/pulp3/orchestration/repository/import_upload.rb +1 -1
  26. data/app/lib/actions/pulp3/repository/commit_upload.rb +3 -1
  27. data/app/lib/actions/pulp3/repository/import_upload.rb +4 -2
  28. data/app/lib/actions/pulp3/repository/reclaim_space.rb +25 -0
  29. data/app/lib/actions/pulp3/repository/save_artifact.rb +12 -8
  30. data/app/lib/katello/resources/cdn.rb +10 -1
  31. data/app/lib/katello/resources/registry.rb +1 -1
  32. data/app/models/katello/concerns/host_managed_extensions.rb +7 -4
  33. data/app/models/katello/concerns/smart_proxy_extensions.rb +21 -9
  34. data/app/models/katello/content_view_version.rb +1 -6
  35. data/app/models/katello/glue/pulp/repo.rb +1 -2
  36. data/app/models/katello/host_tracer.rb +2 -0
  37. data/app/models/katello/pulp3/repository_reference.rb +7 -0
  38. data/app/models/katello/repository.rb +2 -30
  39. data/app/models/katello/root_repository.rb +3 -44
  40. data/app/models/setting/content.rb +2 -8
  41. data/app/presenters/katello/host_package_presenter.rb +21 -0
  42. data/app/services/katello/bulk_items_helper.rb +35 -0
  43. data/app/services/katello/pulp3/api/core.rb +16 -2
  44. data/app/services/katello/pulp3/content.rb +4 -2
  45. data/app/services/katello/pulp3/pulp_content_unit.rb +9 -3
  46. data/app/services/katello/pulp3/repository.rb +9 -4
  47. data/app/services/katello/pulp3/repository_mirror.rb +1 -1
  48. data/app/services/katello/repository_type.rb +2 -1
  49. data/app/services/katello/smart_proxy_helper.rb +10 -1
  50. data/app/views/foreman/job_templates/change_content_source.erb +42 -0
  51. data/app/views/foreman/job_templates/install_errata.erb +8 -6
  52. data/app/views/foreman/job_templates/resolve_traces.erb +4 -5
  53. data/app/views/foreman/job_templates/resolve_traces_-_katello_ansible_default.erb +3 -5
  54. data/app/views/foreman/smart_proxies/_content_sync.html.erb +17 -4
  55. data/app/views/foreman/smart_proxies/_reclaim_space.html.erb +12 -0
  56. data/app/views/foreman/smart_proxies/show.html.erb +4 -2
  57. data/app/views/katello/api/v2/capsule_content/sync_status.json.rabl +6 -0
  58. data/app/views/katello/api/v2/{organizations/cdn_configuration.rabl → cdn_configurations/show.json.rabl} +4 -0
  59. data/app/views/katello/api/v2/content_facet/show.json.rabl +8 -0
  60. data/app/views/katello/api/v2/content_view_filters/show.json.rabl +0 -1
  61. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -1
  62. data/app/views/katello/api/v2/host_packages/base.json.rabl +2 -0
  63. data/app/views/katello/api/v2/organizations/show.json.rabl +1 -1
  64. data/app/views/katello/api/v2/repositories/show.json.rabl +0 -3
  65. data/config/routes/api/v2.rb +5 -10
  66. data/db/migrate/20210331180353_katello_pool_organization_id_not_nullable.rb +2 -0
  67. data/db/migrate/20211115215210_drop_ostree_branches.rb +13 -0
  68. data/db/migrate/20211129200124_remove_dependency_solving_algorithm_setting.rb +5 -0
  69. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/bastion-katello-bootstrap.js +1 -2
  70. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/bastion_katello.js +3 -3
  71. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.controller.js +21 -1
  72. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.factory.js +2 -1
  73. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/sync-state.service.js +2 -0
  74. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/content-views.routes.js +0 -10
  75. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-versions.html +0 -3
  76. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/content-view-version-content.controller.js +0 -10
  77. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/content-view-versions.module.js +0 -1
  78. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version.html +0 -7
  79. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/content.service.js +0 -5
  80. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/environments.module.js +0 -1
  81. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/environments.routes.js +0 -11
  82. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/organizations/fenced-pages.service.js +1 -2
  83. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/product-repositories.controller.js +14 -2
  84. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.controller.js +2 -4
  85. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.filter.js +0 -10
  86. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-reclaim-space-modal.controller.js +36 -0
  87. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +16 -2
  88. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details-reclaim-space-modal.html +18 -0
  89. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +13 -0
  90. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +1 -1
  91. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +3 -6
  92. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +4 -1
  93. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/os-versions.service.js +1 -0
  94. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/product-repositories-reclaim-space-modal.controller.js +35 -0
  95. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repositories.routes.js +0 -9
  96. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository.factory.js +3 -1
  97. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/views/product-repositories-reclaim-space-modal.html +18 -0
  98. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/views/product-repositories.html +7 -8
  99. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/pulp-primary/pulp-primary.controller.js +35 -0
  100. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/pulp-primary/pulp-primary.factory.js +18 -0
  101. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/pulp-primary/pulp-primary.module.js +14 -0
  102. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/pulp-primary/pulp-primary.routes.js +16 -0
  103. data/engines/bastion_katello/lib/bastion_katello/engine.rb +0 -1
  104. data/lib/katello/permission_creator.rb +3 -4
  105. data/lib/katello/plugin.rb +4 -10
  106. data/lib/katello/repository_types/ostree.rb +3 -1
  107. data/lib/katello/tasks/reset.rake +2 -2
  108. data/lib/katello/tasks/upgrades/4.3/fix_url_auth.rake +25 -0
  109. data/lib/katello/version.rb +1 -1
  110. data/package.json +1 -0
  111. data/webpack/components/AddedStatusLabel.js +2 -1
  112. data/webpack/components/EditableTextInput/EditableTextInput.js +76 -17
  113. data/webpack/components/EditableTextInput/__tests__/editableTextInput.test.js +82 -0
  114. data/webpack/components/EditableTextInput/editableTextInput.scss +4 -0
  115. data/webpack/components/Packages/index.js +63 -0
  116. data/webpack/components/RoutedTabs/index.js +3 -1
  117. data/webpack/components/Search/Search.js +7 -1
  118. data/webpack/components/SelectAllCheckbox/index.js +2 -2
  119. data/webpack/components/Table/EmptyStateMessage.js +4 -2
  120. data/webpack/components/Table/MainTable.scss +7 -1
  121. data/webpack/components/Table/TableHooks.js +10 -19
  122. data/webpack/components/Table/TableWrapper.js +3 -3
  123. data/webpack/components/WithOrganization/__snapshots__/withOrganization.test.js.snap +3 -3
  124. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard.js +24 -30
  125. data/webpack/components/extensions/HostDetails/HostDetailsConstants.js +1 -0
  126. data/webpack/components/extensions/HostDetails/HostDetailsSelectors.js +16 -0
  127. data/webpack/components/extensions/HostDetails/HostErrata/HostErrataConstants.js +2 -0
  128. data/webpack/components/extensions/HostDetails/HostPackages/HostPackagesActions.js +11 -0
  129. data/webpack/components/extensions/HostDetails/HostPackages/HostPackagesConstants.js +2 -0
  130. data/webpack/components/extensions/HostDetails/HostPackages/HostPackagesSelectors.js +16 -0
  131. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/SecondaryTabsRoutes.js +4 -0
  132. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/constants.js +1 -0
  133. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab.js +119 -25
  134. data/webpack/components/extensions/HostDetails/Tabs/HostTracesConstants.js +1 -0
  135. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab.js +127 -0
  136. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab.scss +11 -0
  137. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +30 -4
  138. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionConstants.js +1 -0
  139. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsActions.js +73 -0
  140. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsConstants.js +2 -0
  141. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsSelectors.js +16 -0
  142. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +347 -0
  143. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.scss +7 -0
  144. data/webpack/components/extensions/HostDetails/Tabs/TracesTab.js +38 -31
  145. data/webpack/components/extensions/HostDetails/Tabs/__tests__/bookmarks.fixtures.json +12 -0
  146. data/webpack/components/extensions/HostDetails/Tabs/__tests__/contentOverrides.fixtures.json +227 -0
  147. data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +423 -2
  148. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packages.fixtures.json +28 -0
  149. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +91 -0
  150. data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySets.fixtures.json +120 -0
  151. data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySetsTab.test.js +307 -0
  152. data/webpack/components/extensions/HostDetails/Tabs/__tests__/resolveErrata.fixtures.json +35 -0
  153. data/webpack/components/extensions/HostDetails/Tabs/__tests__/tracesTab.test.js +55 -9
  154. data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +28 -14
  155. data/webpack/containers/Application/overrides.scss +31 -9
  156. data/webpack/global_index.js +11 -4
  157. data/webpack/redux/reducers/RedHatRepositories/enabled.fixtures.js +0 -2
  158. data/webpack/scenes/Content/ContentConfig.js +23 -7
  159. data/webpack/scenes/Content/Details/__tests__/contentDetail.test.js +2 -0
  160. data/webpack/scenes/ContentCredentials/ContentCredentialActions.js +18 -0
  161. data/webpack/scenes/ContentCredentials/ContentCredentialConstants.js +2 -0
  162. data/webpack/scenes/ContentCredentials/ContentCredentialSelectors.js +12 -0
  163. data/webpack/scenes/ContentCredentials/__tests__/contentCredentials.fixtures.js +73 -0
  164. data/webpack/scenes/ContentViews/Copy/CopyContentViewForm.js +8 -12
  165. data/webpack/scenes/ContentViews/Copy/CopyContentViewModal.js +1 -1
  166. data/webpack/scenes/ContentViews/Copy/__tests__/copyContentView.test.js +1 -1
  167. data/webpack/scenes/ContentViews/Create/ContentViewFormComponents.js +3 -3
  168. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +7 -2
  169. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.scss +7 -0
  170. data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +9 -9
  171. data/webpack/scenes/ContentViews/Delete/ContentViewDeleteWizard.js +6 -6
  172. data/webpack/scenes/ContentViews/Delete/Steps/CVDeleteEnvironmentsSelection.js +39 -37
  173. data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionFinish.js +10 -4
  174. data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionReview.js +35 -33
  175. data/webpack/scenes/ContentViews/Delete/__tests__/contentViewDelete.test.js +12 -7
  176. data/webpack/scenes/ContentViews/Delete/__tests__/cvVersionsData.fixtures.json +2 -6
  177. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentEnvironments.js +13 -14
  178. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +36 -31
  179. data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +8 -8
  180. data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +108 -41
  181. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +3 -2
  182. data/webpack/scenes/ContentViews/Details/Filters/Add/CVFilterAddModal.js +2 -2
  183. data/webpack/scenes/ContentViews/Details/Filters/Add/__tests__/cvFilterCreateResult.fixtures.json +1 -2
  184. data/webpack/scenes/ContentViews/Details/Filters/AffectedRepositories/AffectedRepositoryTable.js +1 -4
  185. data/webpack/scenes/ContentViews/Details/Filters/CVContainerImageFilterContent.js +6 -6
  186. data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +11 -5
  187. data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +6 -9
  188. data/webpack/scenes/ContentViews/Details/Filters/CVModuleStreamFilterContent.js +5 -8
  189. data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +40 -43
  190. data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +2 -2
  191. data/webpack/scenes/ContentViews/Details/Filters/ContentType.js +4 -4
  192. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilterDetailsHeader.js +6 -8
  193. data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilters.js +6 -1
  194. data/webpack/scenes/ContentViews/Details/Filters/Rules/ContainerTag/AddEditContainerTagRuleModal.js +1 -1
  195. data/webpack/scenes/ContentViews/Details/Filters/Rules/Package/AddEditPackageRuleModal.js +16 -22
  196. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVRpmFilterContent.test.js +8 -8
  197. data/webpack/scenes/ContentViews/Details/Filters/__tests__/ContentViewPackageGroupFilter.test.js +3 -5
  198. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewErrataByDateDetails.fixtures.json +1 -8
  199. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilterDetail.fixtures.json +1 -2
  200. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilterDetails.test.js +5 -9
  201. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvAllRepos.fixtures.json +0 -2
  202. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvErrataDateFilterContent.test.js +1 -9
  203. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvErrataIDFilter.test.js +2 -4
  204. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvErratumFilterDetails.fixtures.json +1 -2
  205. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvFilterDetailModuleAffectedRepos.fixtures.json +1 -8
  206. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvFilterDetailWithAffectedRepos.fixtures.json +1 -8
  207. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvModuleStreamFilter.test.js +2 -4
  208. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvModuleStreamFilterDetails.fixtures.json +1 -2
  209. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvPackageFilterDetail.fixtures.json +1 -3
  210. data/webpack/scenes/ContentViews/Details/Promote/ContentViewVersionPromote.js +61 -32
  211. data/webpack/scenes/ContentViews/Details/Repositories/ContentCounts.js +6 -1
  212. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +5 -8
  213. data/webpack/scenes/ContentViews/Details/Repositories/LastSync.js +55 -9
  214. data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewAddRemove.test.js +2 -0
  215. data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewDetailRepos.fixtures.json +0 -2
  216. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionContent.js +48 -29
  217. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionEnvironments.js +2 -2
  218. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionErrata.js +9 -7
  219. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionErrata.scss +5 -2
  220. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +38 -9
  221. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveCVVersionWizard.js +4 -1
  222. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVEnvironmentSelectionForm.js +59 -53
  223. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVVersionDeleteFinish.js +14 -3
  224. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVVersionRemoveReview.js +24 -17
  225. data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/cvVersionRemove.test.js +3 -3
  226. data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/versionsResponseData.fixtures.json +1 -4
  227. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetails.js +4 -2
  228. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsHeader.js +134 -32
  229. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionRepositoryCell.js +8 -3
  230. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionComponent.fixtures.json +1 -4
  231. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetails.fixtures.json +1 -2
  232. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetails.test.js +21 -1
  233. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetailsCounts.fixtures.json +1 -2
  234. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetailsEmpty.test.js +22 -1
  235. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionRepositories.fixtures.json +1 -18
  236. data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersions.fixtures.json +5 -5
  237. data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersions.test.js +2 -0
  238. data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersionsWithTask.fixtures.json +1 -3
  239. data/webpack/scenes/ContentViews/Details/contentViewInfo.scss +0 -4
  240. data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +66 -53
  241. data/webpack/scenes/ContentViews/Publish/CVPublishReview.js +40 -28
  242. data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +3 -3
  243. data/webpack/scenes/ContentViews/Publish/__tests__/publishContentView.test.js +14 -14
  244. data/webpack/scenes/ContentViews/Publish/cvPublishForm.scss +6 -0
  245. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +53 -12
  246. data/webpack/scenes/ContentViews/Table/tableDataGenerator.js +12 -6
  247. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +6 -6
  248. data/webpack/scenes/ContentViews/components/ContentViewIcon.js +12 -7
  249. data/webpack/scenes/ContentViews/components/ContentViewsCounter.js +2 -2
  250. data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.js +26 -27
  251. data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.scss +18 -6
  252. data/webpack/scenes/ContentViews/components/WizardHeader.js +44 -0
  253. data/webpack/scenes/ContentViews/components/contentViewIcon.scss +13 -2
  254. data/webpack/scenes/Organizations/OrganizationActions.js +22 -24
  255. data/webpack/scenes/Organizations/OrganizationConstants.js +1 -3
  256. data/webpack/scenes/Organizations/OrganizationReducer.js +0 -7
  257. data/webpack/scenes/Organizations/OrganizationSelectors.js +16 -0
  258. data/webpack/scenes/Organizations/__tests__/OrganizationActions.test.js +1 -21
  259. data/webpack/scenes/Organizations/__tests__/OrganizationReducer.test.js +0 -20
  260. data/webpack/scenes/Organizations/__tests__/organizations.fixtures.js +34 -23
  261. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationForm.js +185 -0
  262. data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationForm.scss +3 -0
  263. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +112 -146
  264. data/webpack/scenes/Subscriptions/Manifest/__tests__/CdnConfigurationForm.test.js +114 -0
  265. data/webpack/scenes/Subscriptions/Manifest/__tests__/ManageManifestModal.test.js +121 -31
  266. data/webpack/scenes/Subscriptions/Manifest/index.js +14 -3
  267. data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap +1 -0
  268. data/webpack/scenes/Tasks/TaskActions.js +4 -3
  269. data/webpack/scenes/Tasks/__tests__/__snapshots__/TaskActions.test.js.snap +1 -0
  270. data/webpack/utils/helpers.js +2 -2
  271. metadata +62 -43
  272. data/app/controllers/katello/api/v2/ostree_branches_controller.rb +0 -16
  273. data/app/lib/actions/pulp/repository/presenters/ostree_presenter.rb +0 -91
  274. data/app/models/katello/ostree_branch.rb +0 -12
  275. data/app/models/katello/repository_ostree_branch.rb +0 -7
  276. data/app/services/katello/pulp/ostree_branch.rb +0 -14
  277. data/app/services/katello/pulp/repository/ostree.rb +0 -48
  278. data/app/views/katello/api/v2/ostree_branches/compare.json.rabl +0 -10
  279. data/app/views/katello/api/v2/ostree_branches/index.json.rabl +0 -7
  280. data/app/views/katello/api/v2/ostree_branches/show.json.rabl +0 -5
  281. data/app/views/katello/api/v2/root/resource_list.json.rabl +0 -3
  282. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version-ostree-branches.html +0 -26
  283. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-ostree.html +0 -27
  284. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/details/ostree-branch-repositories.controller.js +0 -77
  285. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/details/ostree-branch.controller.js +0 -31
  286. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/details/views/ostree-branch-info.html +0 -15
  287. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/details/views/ostree-branch-repositories.html +0 -72
  288. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/details/views/ostree-branch.html +0 -30
  289. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/ostree-branch.factory.js +0 -27
  290. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/ostree-branches.controller.js +0 -67
  291. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/ostree-branches.module.js +0 -15
  292. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/ostree-branches.routes.js +0 -50
  293. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/views/ostree-branches.html +0 -40
  294. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-manage-ostree-branches.html +0 -40
  295. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/ostree-upstream-sync-policy.service.js +0 -26
  296. data/webpack/components/extensions/HostDetails/Tabs/SubscriptionTab.js +0 -12
  297. data/webpack/scenes/Content/Details/ContentCounts.js +0 -42
  298. data/webpack/scenes/Subscriptions/Manifest/__tests__/SimpleContentAccess.test.js +0 -108
  299. data/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap +0 -158
@@ -1,3 +1,3 @@
1
1
  module Katello
2
- VERSION = "4.3.0.rc1".freeze
2
+ VERSION = "4.3.0.rc4".freeze
3
3
  end
data/package.json CHANGED
@@ -28,6 +28,7 @@
28
28
  "@sheerun/mutationobserver-shim": "^0.3.3",
29
29
  "@testing-library/jest-dom": "^5.3.0",
30
30
  "@testing-library/react": "^10.0.2",
31
+ "@testing-library/user-event": "^13.5.0",
31
32
  "@theforeman/builder": ">= 6.0.0",
32
33
  "@theforeman/find-foreman": "^4.8.0",
33
34
  "axios-mock-adapter": "^1.10.0",
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
3
3
  import { Label } from '@patternfly/react-core';
4
4
  import { CheckCircleIcon } from '@patternfly/react-icons';
5
5
  import { translate as __ } from 'foremanReact/common/I18n';
6
+ import InactiveText from '../scenes/ContentViews/components/InactiveText';
6
7
 
7
8
  const AddedStatusLabel = ({ added }) => {
8
9
  if (added) {
@@ -12,7 +13,7 @@ const AddedStatusLabel = ({ added }) => {
12
13
  </Label>
13
14
  );
14
15
  }
15
- return __('Not added');
16
+ return <InactiveText text={__('Not added')} />;
16
17
  };
17
18
 
18
19
  AddedStatusLabel.propTypes = {
@@ -1,20 +1,33 @@
1
1
  import React, { useState, useEffect } from 'react';
2
- import { TextInput, TextArea, Text, TextVariants, Button, Split, SplitItem } from '@patternfly/react-core';
3
- import { TimesIcon, CheckIcon, PencilAltIcon } from '@patternfly/react-icons';
2
+ import {
3
+ TextInput, TextArea, Text, Button, Split,
4
+ SplitItem, Tooltip, TooltipPosition,
5
+ } from '@patternfly/react-core';
6
+ import {
7
+ EyeIcon,
8
+ EyeSlashIcon,
9
+ TimesIcon,
10
+ CheckIcon,
11
+ PencilAltIcon,
12
+ } from '@patternfly/react-icons';
4
13
  import { translate as __ } from 'foremanReact/common/I18n';
5
14
  import PropTypes from 'prop-types';
6
15
  import Loading from '../Loading';
7
16
  import './editableTextInput.scss';
8
17
 
18
+ const PASSWORD_MASK = '••••••••';
19
+
9
20
  const EditableTextInput = ({
10
- onEdit, value, textArea, attribute, placeholder,
21
+ onEdit, value, textArea, attribute, placeholder, isPassword, hasPassword,
11
22
  component, currentAttribute, setCurrentAttribute, disabled,
12
23
  }) => {
13
24
  // Tracks input box state
14
25
  const [inputValue, setInputValue] = useState(value);
15
26
  const [editing, setEditing] = useState(false);
16
27
  const [submitting, setSubmitting] = useState(false);
17
-
28
+ const [passwordPlaceholder, setPasswordPlaceholder] = useState(hasPassword
29
+ ? PASSWORD_MASK : null);
30
+ const [showPassword, setShowPassword] = useState(false);
18
31
 
19
32
  useEffect(() => {
20
33
  if (setCurrentAttribute && currentAttribute) {
@@ -27,6 +40,12 @@ const EditableTextInput = ({
27
40
  const onEditClick = () => {
28
41
  setEditing(true);
29
42
  if (setCurrentAttribute) setCurrentAttribute(attribute);
43
+
44
+ if (isPassword) {
45
+ if (passwordPlaceholder) {
46
+ setPasswordPlaceholder(null);
47
+ }
48
+ }
30
49
  };
31
50
 
32
51
  // Setting didCancel to prevent actions from happening after component has been unmounted
@@ -37,9 +56,16 @@ const EditableTextInput = ({
37
56
  const onSubmit = async () => {
38
57
  if (submitting) { // no dependency array because this check takes care of it
39
58
  await onEdit(inputValue, attribute);
59
+
40
60
  if (!didCancel) {
41
61
  setSubmitting(false);
42
62
  setEditing(false);
63
+
64
+ if (isPassword) {
65
+ if (inputValue?.length > 0) {
66
+ setPasswordPlaceholder(PASSWORD_MASK);
67
+ }
68
+ }
43
69
  }
44
70
  }
45
71
  };
@@ -64,10 +90,20 @@ const EditableTextInput = ({
64
90
  }, [editing]);
65
91
 
66
92
  const onClear = () => {
93
+ if (isPassword) {
94
+ if (hasPassword || inputValue?.length > 0) {
95
+ setPasswordPlaceholder(PASSWORD_MASK);
96
+ }
97
+ }
98
+
67
99
  setInputValue(value);
68
100
  setEditing(false);
69
101
  };
70
102
 
103
+ const toggleShowPassword = () => {
104
+ setShowPassword(prevShowPassword => !prevShowPassword);
105
+ };
106
+
71
107
  const inputProps = {
72
108
  component,
73
109
  value: inputValue || '',
@@ -81,7 +117,7 @@ const EditableTextInput = ({
81
117
  <SplitItem>
82
118
  {textArea ?
83
119
  (<TextArea {...inputProps} aria-label={`${attribute} text area`} />) :
84
- (<TextInput {...inputProps} type="text" aria-label={`${attribute} text input`} />)}
120
+ (<TextInput {...inputProps} type={(isPassword && !showPassword) ? 'password' : 'text'} aria-label={`${attribute} text input`} />)}
85
121
  </SplitItem>
86
122
  <SplitItem>
87
123
  <Button
@@ -97,29 +133,48 @@ const EditableTextInput = ({
97
133
  <TimesIcon />
98
134
  </Button>
99
135
  </SplitItem>
136
+ {isPassword ?
137
+ <SplitItem>
138
+ <Button aria-label={`show-password ${attribute}`} variant="plain" isDisabled={!inputValue?.length} onClick={toggleShowPassword}>
139
+ {showPassword ?
140
+ (<EyeSlashIcon />) :
141
+ (<EyeIcon />)}
142
+ </Button>
143
+ </SplitItem> :
144
+ null
145
+ }
100
146
  </Split>
101
147
  );
102
148
  }
103
149
  return (
104
150
  <Split>
105
151
  <SplitItem>
106
- <Text aria-label={`${attribute} text value`} component={component || TextVariants.p}>
107
- {value || (<i>{placeholder}</i>)}
108
- </Text>
109
- </SplitItem>
152
+ {inputValue ?
153
+ <Text aria-label={`${attribute} text value`} component={component}>
154
+ {editing ? inputValue : passwordPlaceholder || inputValue}
155
+ </Text> :
156
+ <Text className="textInput-placeholder" aria-label={`${attribute} text value`} component={component}>
157
+ {passwordPlaceholder || placeholder}
158
+ </Text>}
159
+ </SplitItem >
110
160
  {!disabled &&
111
161
  <SplitItem>
112
- <Button
113
- className="foreman-edit-icon"
114
- aria-label={`edit ${attribute}`}
115
- variant="plain"
116
- onClick={onEditClick}
162
+ <Tooltip
163
+ position={TooltipPosition.top}
164
+ content={__('Edit')}
117
165
  >
118
- <PencilAltIcon />
119
- </Button>
166
+ <Button
167
+ className="foreman-edit-icon"
168
+ aria-label={`edit ${attribute}`}
169
+ variant="plain"
170
+ onClick={onEditClick}
171
+ >
172
+ <PencilAltIcon />
173
+ </Button>
174
+ </Tooltip>
120
175
  </SplitItem>
121
176
  }
122
- </Split>
177
+ </Split >
123
178
  );
124
179
  };
125
180
 
@@ -133,6 +188,8 @@ EditableTextInput.propTypes = {
133
188
  currentAttribute: PropTypes.string,
134
189
  setCurrentAttribute: PropTypes.func,
135
190
  disabled: PropTypes.bool,
191
+ isPassword: PropTypes.bool,
192
+ hasPassword: PropTypes.bool,
136
193
  };
137
194
 
138
195
  EditableTextInput.defaultProps = {
@@ -143,6 +200,8 @@ EditableTextInput.defaultProps = {
143
200
  currentAttribute: undefined,
144
201
  setCurrentAttribute: undefined,
145
202
  disabled: false,
203
+ isPassword: false,
204
+ hasPassword: false,
146
205
  };
147
206
 
148
207
  export default EditableTextInput;
@@ -50,3 +50,85 @@ test('input is set back to original value after clearing', () => {
50
50
  // Original value is still showing even though it's been edited
51
51
  expect(getByLabelText(`${attribute} text value`)).toHaveTextContent(actualValue);
52
52
  });
53
+
54
+ test('shows a mask over the password when there is one', () => {
55
+ const { getByLabelText } = render(<EditableTextInput
56
+ attribute={attribute}
57
+ onEdit={jest.fn()}
58
+ isPassword
59
+ hasPassword
60
+ />);
61
+
62
+ expect(getByLabelText(`${attribute} text value`)).toHaveTextContent('••••••••');
63
+ });
64
+
65
+ test('shows a mask over the password after undoing changes', () => {
66
+ const { getByLabelText } = render(<EditableTextInput
67
+ attribute={attribute}
68
+ onEdit={jest.fn()}
69
+ isPassword
70
+ hasPassword
71
+ />);
72
+
73
+ getByLabelText(`edit ${attribute}`).click();
74
+ expect(getByLabelText(`${attribute} text input`)).toHaveTextContent('');
75
+
76
+ getByLabelText(`clear ${attribute}`).click();
77
+ expect(getByLabelText(`${attribute} text value`)).toHaveTextContent('••••••••');
78
+ });
79
+
80
+ test('shows a mask over the password after editing', async () => {
81
+ const newPassword = 'Pizza';
82
+ const { getByLabelText } = render(<EditableTextInput
83
+ attribute={attribute}
84
+ onEdit={jest.fn()}
85
+ isPassword
86
+ hasPassword
87
+ />);
88
+
89
+ getByLabelText(`edit ${attribute}`).click();
90
+ fireEvent.change(getByLabelText(`${attribute} text input`), { target: { value: newPassword } });
91
+ expect(getByLabelText(`${attribute} text input`)).toHaveValue(newPassword);
92
+ getByLabelText(`submit ${attribute}`).click();
93
+
94
+ await patientlyWaitFor(() => expect(getByLabelText(`${attribute} text value`)).toBeInTheDocument());
95
+ expect(getByLabelText(`${attribute} text value`)).toHaveTextContent('••••••••');
96
+ });
97
+
98
+ test('shows a placeholder after clearing the password', async () => {
99
+ const { getByLabelText } = render(<EditableTextInput
100
+ attribute={attribute}
101
+ onEdit={jest.fn()}
102
+ isPassword
103
+ hasPassword
104
+ />);
105
+
106
+ getByLabelText(`edit ${attribute}`).click();
107
+ getByLabelText(`submit ${attribute}`).click();
108
+
109
+ await patientlyWaitFor(() => expect(getByLabelText(`${attribute} text value`)).toBeInTheDocument());
110
+ expect(getByLabelText(`${attribute} text value`)).toHaveTextContent('None provided');
111
+ });
112
+
113
+ test('can toggle showing the current password', async () => {
114
+ const { getByLabelText } = render(<EditableTextInput
115
+ attribute={attribute}
116
+ onEdit={jest.fn()}
117
+ isPassword
118
+ hasPassword
119
+ />);
120
+
121
+ getByLabelText(`edit ${attribute}`).click();
122
+
123
+ expect(getByLabelText(`show-password ${attribute}`)).toHaveAttribute('disabled', '');
124
+
125
+ const newPassword = 'New Password';
126
+ fireEvent.change(getByLabelText(`${attribute} text input`), { target: { value: newPassword } });
127
+ expect(getByLabelText(`${attribute} text input`)).toHaveAttribute('type', 'password');
128
+
129
+ getByLabelText(`show-password ${attribute}`).click();
130
+ expect(getByLabelText(`${attribute} text input`)).toHaveAttribute('type', 'text');
131
+
132
+ getByLabelText(`show-password ${attribute}`).click();
133
+ expect(getByLabelText(`${attribute} text input`)).toHaveAttribute('type', 'password');
134
+ });
@@ -11,4 +11,8 @@
11
11
  // Edit icon isn't in line with text
12
12
  .foreman-edit-icon {
13
13
  padding-top: 2px;
14
+ }
15
+
16
+ .textInput-placeholder {
17
+ color: var(--pf-global--disabled-color--100);
14
18
  }
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import { TableText } from '@patternfly/react-table';
3
+ import { translate as __ } from 'foremanReact/common/I18n';
4
+ import {
5
+ CheckIcon,
6
+ LongArrowAltUpIcon,
7
+ MinusIcon,
8
+ } from '@patternfly/react-icons';
9
+ import PropTypes from 'prop-types';
10
+
11
+ export const PackagesStatus = ({ upgradable_version: upgradableVersion }) => {
12
+ let PackagesIcon;
13
+ let label;
14
+ let color;
15
+
16
+ if (upgradableVersion == null) {
17
+ color = 'green';
18
+ label = __('Up-to date');
19
+ PackagesIcon = CheckIcon;
20
+ } else {
21
+ color = 'blue';
22
+ label = __('Upgradable');
23
+ PackagesIcon = LongArrowAltUpIcon;
24
+ }
25
+ if (!PackagesIcon) return null;
26
+
27
+ return (
28
+ <TableText wrapModifier="nowrap">
29
+ {color && <PackagesIcon color={color} title={label} />} {label}
30
+ </TableText>
31
+ );
32
+ };
33
+
34
+ PackagesStatus.propTypes = {
35
+ upgradable_version: PropTypes.string,
36
+ };
37
+
38
+ PackagesStatus.defaultProps = {
39
+ upgradable_version: null,
40
+ };
41
+
42
+ export const PackagesLatestVersion = ({ name, upgradable_version: upgradableVersion }) => {
43
+ let label;
44
+ let color;
45
+
46
+ if (upgradableVersion == null) {
47
+ label = '';
48
+ color = 'green';
49
+ } else {
50
+ label = upgradableVersion.replace(`${name}-`, '');
51
+ }
52
+
53
+ return <TableText wrapModifier="nowrap">{color && <MinusIcon color={color} title={label} />} {label} </TableText>;
54
+ };
55
+
56
+ PackagesLatestVersion.propTypes = {
57
+ name: PropTypes.string.isRequired,
58
+ upgradable_version: PropTypes.string,
59
+ };
60
+
61
+ PackagesLatestVersion.defaultProps = {
62
+ upgradable_version: null,
63
+ };
@@ -14,6 +14,8 @@ const RoutedTabs = ({
14
14
 
15
15
  // The below transforms #/history/6 to history
16
16
  const currentTabFromUrl = head(last(hash.split('#/')).split('/'));
17
+ // Allows navigation back to mainTab
18
+ const onSubTab = currentTabFromUrl !== last(last(hash.split('#/')).split('/'));
17
19
 
18
20
  const onSelect = (e, key) => {
19
21
  e.preventDefault();
@@ -22,7 +24,7 @@ const RoutedTabs = ({
22
24
  // https://www.w3schools.com/jsref/event_button.asp
23
25
  const middleMouseButtonNotUsed = !(e.button === 1 || e.buttons === 4 || e.which === 2);
24
26
  const notCurrentTab = currentTabFromUrl !== key;
25
- if (middleMouseButtonNotUsed && notCurrentTab) {
27
+ if (middleMouseButtonNotUsed && (notCurrentTab || !!onSubTab)) {
26
28
  push(`#/${key}`);
27
29
  }
28
30
  };
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect } from 'react';
1
+ import React, { useState, useEffect, useRef } from 'react';
2
2
  import { useDispatch } from 'react-redux';
3
3
  import { ControlLabel } from 'react-bootstrap';
4
4
  import { loadSetting } from 'foremanReact/components/Settings/SettingsActions';
@@ -26,11 +26,14 @@ const Search = ({
26
26
  }) => {
27
27
  const [items, setItems] = useState([]);
28
28
  const dispatch = useDispatch();
29
+ const mountedRef = useRef(true);
29
30
 
30
31
  const onInputUpdate = async (searchTerm = '') => {
31
32
  const newItems = items.filter(({ text }) => stringIncludes(text, searchTerm));
32
33
 
33
34
  if (newItems.length !== items.length) {
35
+ // Checking whether the current component is mounted before state change events
36
+ if (!mountedRef.current) return;
34
37
  setItems(newItems);
35
38
  }
36
39
 
@@ -43,6 +46,8 @@ const Search = ({
43
46
  } else {
44
47
  data = await api.get(endpoint, undefined, params);
45
48
  }
49
+ // Checking whether the current component is mounted before state change events
50
+ if (!mountedRef.current) return;
46
51
  setItems(data?.data?.filter(({ error }) => !error).map(({ label }) => ({
47
52
  text: label.trim(),
48
53
  })));
@@ -56,6 +61,7 @@ const Search = ({
56
61
  useEffect(() => {
57
62
  dispatch(loadSetting(AUTOSEARCH_DELAY));
58
63
  dispatch(loadSetting(AUTOSEARCH_WHILE_TYPING));
64
+ return () => { mountedRef.current = false; };
59
65
  }, [dispatch]);
60
66
 
61
67
  const onNewSearch = (search) => {
@@ -71,13 +71,13 @@ const SelectAllCheckbox = ({
71
71
  <DropdownItem key="select-none" component="button" isDisabled={selectedCount === 0} onClick={handleSelectNone} >
72
72
  {`${__('Select none')} (0)`}
73
73
  </DropdownItem>,
74
- <DropdownItem key="select-page" component="button" isDisabled={areAllRowsOnPageSelected} onClick={handleSelectPage}>
74
+ <DropdownItem key="select-page" component="button" isDisabled={pageRowCount === 0 || areAllRowsOnPageSelected} onClick={handleSelectPage}>
75
75
  {`${__('Select page')} (${pageRowCount})`}
76
76
  </DropdownItem>,
77
77
  ];
78
78
  if (canSelectAll) {
79
79
  selectAllDropdownItems.push((
80
- <DropdownItem key="select-all" id="all" component="button" isDisabled={areAllRowsSelected} onClick={handleSelectAll}>
80
+ <DropdownItem key="select-all" id="all" component="button" isDisabled={totalCount === 0 || areAllRowsSelected} onClick={handleSelectAll}>
81
81
  {`${__('Select all')} (${totalCount})`}
82
82
  </DropdownItem>));
83
83
  }
@@ -1,10 +1,12 @@
1
1
  import React from 'react';
2
- import { EmptyState,
2
+ import {
3
+ EmptyState,
3
4
  EmptyStateBody,
4
5
  EmptyStateIcon,
5
6
  EmptyStateVariant,
6
7
  Bullseye,
7
- Title } from '@patternfly/react-core';
8
+ Title,
9
+ } from '@patternfly/react-core';
8
10
  import PropTypes from 'prop-types';
9
11
  import { translate as __ } from 'foremanReact/common/I18n';
10
12
  import { CubeIcon, ExclamationCircleIcon, SearchIcon } from '@patternfly/react-icons';
@@ -1,11 +1,17 @@
1
- .pf-c-dropdown.pf-m-align-right{
1
+ .pf-c-dropdown.pf-m-align-right {
2
2
  width: 100%;
3
3
  justify-content: flex-end;
4
4
  display: flex;
5
5
  }
6
+
6
7
  .pf-c-dropdown__menu {
7
8
  min-width: 0;
8
9
  }
10
+
9
11
  .pf-c-wizard__footer {
10
12
  z-index: 1;
13
+ }
14
+
15
+ .pf-c-table tbody tr td {
16
+ vertical-align: inherit;
11
17
  }
@@ -179,27 +179,18 @@ export const useBulkSelect = ({
179
179
  };
180
180
 
181
181
  const fetchBulkParams = () => {
182
- const selected = {
183
- included: {
184
- ids: [],
185
- search: null,
186
- },
187
- excluded: {
188
- ids: [],
189
- },
190
- all: false,
182
+ const searchQueryWithExclusionSet = () => {
183
+ const query = [searchQuery,
184
+ !isEmpty(exclusionSet) && `${idColumn} !^ (${[...exclusionSet].join(',')})`];
185
+ return query.filter(item => item).join(' and ');
191
186
  };
192
187
 
193
- if (selectAllMode) {
194
- selected.included.search = searchQuery;
195
- selected.excluded.ids = [...exclusionSet];
196
- selected.all = true;
197
- } else if (!isEmpty(inclusionSet)) {
198
- selected.included.ids = [...inclusionSet];
199
- } else {
200
- return {};
201
- }
202
- return selected;
188
+ const searchQueryWithInclusionSet = () => {
189
+ if (isEmpty(inclusionSet)) throw new Error('Cannot build a search query with no items selected');
190
+ return `${idColumn} ^ (${[...inclusionSet].join(',')})`;
191
+ };
192
+
193
+ return selectAllMode ? searchQueryWithExclusionSet() : searchQueryWithInclusionSet();
203
194
  };
204
195
 
205
196
  const prevSearchRef = usePrevious({ searchQuery });
@@ -49,6 +49,8 @@ const TableWrapper = ({
49
49
  const { pageRowCount } = getPageStats({ total, page, perPage });
50
50
  const unresolvedStatus = !!allTableProps?.status && allTableProps.status !== STATUS.RESOLVED;
51
51
  const unresolvedStatusOrNoRows = unresolvedStatus || pageRowCount === 0;
52
+ const resolvedStatusNoContent =
53
+ !searchQuery && allTableProps.status === STATUS.RESOLVED && pageRowCount === 0;
52
54
  const showPagination = !unresolvedStatusOrNoRows;
53
55
  const showActionButtons = actionButtons && !unresolvedStatus;
54
56
  const showToggleGroup = toggleGroup && !unresolvedStatus;
@@ -63,8 +65,6 @@ const TableWrapper = ({
63
65
  const hasChanged = (oldValue, newValue) => !isEqual(oldValue, newValue);
64
66
 
65
67
  const spawnFetch = useCallback((paginationData) => {
66
- // The search component will update the search query when a search is performed, listen for that
67
- // and perform the search so we can be sure the searchQuery is updated when search is performed.
68
68
  const fetchWithParams = (allParams = {}) => {
69
69
  const newRequest = {
70
70
  ...(paginationData ?? paginationParams()),
@@ -177,7 +177,7 @@ const TableWrapper = ({
177
177
  />
178
178
  </FlexItem>
179
179
  }
180
- {!disableSearch &&
180
+ {!disableSearch && !resolvedStatusNoContent &&
181
181
  <FlexItem>
182
182
  <Search
183
183
  isDisabled={unresolvedStatusOrNoRows && !searchQuery}
@@ -17,7 +17,6 @@ exports[`subscriptions page should render select org page 1`] = `
17
17
  default={[Function]}
18
18
  loadOrganization={[Function]}
19
19
  organization={Object {}}
20
- saveOrganization={[Function]}
21
20
  store={
22
21
  Object {
23
22
  "clearActions": [Function],
@@ -28,6 +27,7 @@ exports[`subscriptions page should render select org page 1`] = `
28
27
  "subscribe": [Function],
29
28
  }
30
29
  }
30
+ updateCdnConfiguration={[Function]}
31
31
  >
32
32
  <Header
33
33
  title="Select Organization"
@@ -73,7 +73,6 @@ exports[`subscriptions page should render the wrapped component 1`] = `
73
73
  default={[Function]}
74
74
  loadOrganization={[Function]}
75
75
  organization={Object {}}
76
- saveOrganization={[Function]}
77
76
  store={
78
77
  Object {
79
78
  "clearActions": [Function],
@@ -84,12 +83,12 @@ exports[`subscriptions page should render the wrapped component 1`] = `
84
83
  "subscribe": [Function],
85
84
  }
86
85
  }
86
+ updateCdnConfiguration={[Function]}
87
87
  >
88
88
  <WrappedComponent
89
89
  default={[Function]}
90
90
  loadOrganization={[Function]}
91
91
  organization={Object {}}
92
- saveOrganization={[Function]}
93
92
  store={
94
93
  Object {
95
94
  "clearActions": [Function],
@@ -100,6 +99,7 @@ exports[`subscriptions page should render the wrapped component 1`] = `
100
99
  "subscribe": [Function],
101
100
  }
102
101
  }
102
+ updateCdnConfiguration={[Function]}
103
103
  >
104
104
  <div>
105
105
  Wrapped!
@@ -1,9 +1,5 @@
1
1
  import React from 'react';
2
2
  import {
3
- DescriptionList,
4
- DescriptionListTerm,
5
- DescriptionListGroup,
6
- DescriptionListDescription,
7
3
  Card,
8
4
  CardHeader,
9
5
  CardTitle,
@@ -30,36 +26,34 @@ const HostContentViewDetails = ({
30
26
  }
31
27
 
32
28
  return (
33
- <GridItem rowSpan={2} md={6} lg={3}>
29
+ <GridItem rowSpan={2} md={6} lg={4}>
34
30
  <Card isHoverable>
35
31
  <CardHeader>
36
- <CardTitle>{__('Content View Details')}</CardTitle>
32
+ <CardTitle>{__('Content view details')}</CardTitle>
37
33
  </CardHeader>
38
34
  <CardBody>
39
- <DescriptionList isHorizontal isAutoColumnWidths>
40
- <DescriptionListGroup>
41
- <DescriptionListTerm>{__('Content View')}</DescriptionListTerm>
42
- <DescriptionListDescription>
43
- <Flex>
44
- <FlexItem spacer={{ default: 'spacerNone' }}><ContentViewIcon composite={contentView.composite} /></FlexItem>
45
- <FlexItem><a href={`/content_views/${contentView.id}`}>{`${contentView.name}`}</a> </FlexItem>
46
- <FlexItem><Label isTruncated color="purple" href={`/lifecycle_environments/${lifecycleEnvironment.id}`}>{`${lifecycleEnvironment.name}`}</Label></FlexItem>
47
- </Flex>
48
- </DescriptionListDescription>
49
- </DescriptionListGroup>
50
- <DescriptionListGroup>
51
- <DescriptionListTerm>{__('Version in use')}</DescriptionListTerm>
52
- <DescriptionListDescription>
53
- <Flex>
54
- <FlexItem>
55
- <a href={urlBuilder(`content_views/${contentView.id}/versions/${contentViewVersionId}`, '')}>
56
- {versionLabel}
57
- </a>
58
- </FlexItem>
59
- </Flex>
60
- </DescriptionListDescription>
61
- </DescriptionListGroup>
62
- </DescriptionList>
35
+ <Flex direction={{ default: 'column' }}>
36
+ <Flex
37
+ direction={{ default: 'row', sm: 'row' }}
38
+ flexWrap={{ default: 'nowrap' }}
39
+ alignItems={{ default: 'alignItemsCenter', sm: 'alignItemsCenter' }}
40
+ >
41
+ <ContentViewIcon composite={contentView.composite} style={{ marginRight: '2px' }} />
42
+ <h3>{__('Content view')}</h3>
43
+ </Flex>
44
+ <Flex direction={{ default: 'row', sm: 'row' }} flexWrap={{ default: 'wrap' }}>
45
+ <a style={{ fontSize: '14px' }} href={`/content_views/${contentView.id}`}>{`${contentView.name}`}</a>
46
+ <Label isTruncated color="purple" href={`/lifecycle_environments/${lifecycleEnvironment.id}`}>{`${lifecycleEnvironment.name}`}</Label>
47
+ </Flex>
48
+ </Flex>
49
+ <Flex direction={{ default: 'column' }}>
50
+ <FlexItem>
51
+ <h3>{__('Version in use')}</h3>
52
+ <a style={{ fontSize: '14px' }} href={urlBuilder(`content_views/${contentView.id}/versions/${contentViewVersionId}`, '')}>
53
+ {versionLabel}
54
+ </a>
55
+ </FlexItem>
56
+ </Flex>
63
57
  </CardBody>
64
58
  </Card>
65
59
  </GridItem>
@@ -0,0 +1 @@
1
+ export default 'HOST_DETAILS';