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
@@ -3,7 +3,7 @@ import { useSelector } from 'react-redux';
3
3
  import { STATUS } from 'foremanReact/constants';
4
4
  import PropTypes from 'prop-types';
5
5
  import { translate as __ } from 'foremanReact/common/I18n';
6
- import { Form, FormGroup, Checkbox } from '@patternfly/react-core';
6
+ import { FormGroup, Checkbox, TextContent } from '@patternfly/react-core';
7
7
  import { selectEnvironmentPaths, selectEnvironmentPathsStatus } from './EnvironmentPathSelectors';
8
8
  import EnvironmentLabels from '../EnvironmentLabels';
9
9
  import './EnvironmentPaths.scss';
@@ -36,41 +36,40 @@ const EnvironmentPaths = ({
36
36
  /* eslint-disable react/no-array-index-key */
37
37
  return (
38
38
  <>
39
- <b
40
- style={{ marginBottom: '1em' }}
41
- >{headerText}
42
- </b>
43
- <Form style={{ marginTop: '1em' }}>{results.map((path, count) => {
44
- const {
45
- environments,
46
- } = path || {};
47
- return (
48
- <React.Fragment key={count}>
49
- <FormGroup key={`fg-${count}`} isInline fieldId="environment-checkbox-group">
50
- {environments.map(env =>
39
+ <TextContent>{headerText}</TextContent>
40
+ <div>
41
+ {results.map((path, index) => {
42
+ const {
43
+ environments,
44
+ } = path || {};
45
+ return (
46
+ <div className="env-path" key={index}>
47
+ {index === 0 && <hr />}
48
+ <FormGroup key={`fg-${index}`} isInline fieldId="environment-checkbox-group">
49
+ {environments.map(env =>
51
50
  (<Checkbox
52
51
  isChecked={(publishing && env.library) ||
53
- envCheckedInList(env, userCheckedItems) ||
54
- envCheckedInList(env, promotedEnvironments)}
52
+ envCheckedInList(env, userCheckedItems) ||
53
+ envCheckedInList(env, promotedEnvironments)}
55
54
  isDisabled={(publishing && env.library)
56
- || envCheckedInList(env, promotedEnvironments)}
57
- style={{ marginRight: '3px', marginBottom: '1px' }}
58
- className="env-labels-with-pointer"
59
- key={`${env.id}${count}`}
60
- id={`${env.id}${count}`}
55
+ || envCheckedInList(env, promotedEnvironments)}
56
+ className="env-path__labels-with-pointer"
57
+ key={`${env.id}${index}`}
58
+ id={`${env.id}${index}`}
61
59
  label={<EnvironmentLabels environments={env} />}
62
60
  aria-label={env.label}
63
61
  onChange={checked => oncheckedChange(checked, env)}
64
62
  />))}
65
- </FormGroup>
66
- <hr key={`hr${count}`} style={{ margin: '0em' }} />
67
- </React.Fragment>
68
- );
69
- })}
70
- </Form>
63
+ </FormGroup>
64
+ <hr />
65
+ </div>
66
+ );
67
+ })
68
+ /* eslint-enable react/no-array-index-key */
69
+ }
70
+ </div>
71
71
  </>
72
72
  );
73
- /* eslint-enable react/no-array-index-key */
74
73
  };
75
74
 
76
75
  EnvironmentPaths.propTypes = {
@@ -1,8 +1,20 @@
1
- .env-labels-with-pointer {
2
- &:not(:last-child):after {
3
- content: '>';
4
- margin-top: 3px;
1
+ .env-path {
2
+ .pf-c-form__group {
3
+ margin: 20px 0;
4
+ }
5
+
6
+ .env-path__labels-with-pointer {
7
+ &:not(:last-child):after {
8
+ content: '>';
9
+ margin-top: 3px;
10
+ }
11
+
12
+ display: inline-flex;
13
+ margin: 3px 1px;
14
+ align-items: center;
15
+ }
16
+
17
+ hr {
18
+ margin: 0;
5
19
  }
6
- display: inline-flex;
7
- margin-top: 3px;
8
20
  }
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { Grid, TextContent, Text, TextVariants, Flex, FlexItem } from '@patternfly/react-core';
4
+
5
+ const WizardHeader = ({
6
+ title,
7
+ description,
8
+ }) => (
9
+ <Grid style={{ gridGap: '24px' }}>
10
+ {title &&
11
+ <TextContent>
12
+ <Text component={TextVariants.h2}>{title}</Text>
13
+ </TextContent>}
14
+ {description &&
15
+ <TextContent>
16
+ <Flex flex={{ default: 'inlineFlex' }}>
17
+ <FlexItem>
18
+ <TextContent>
19
+ {description}
20
+ </TextContent>
21
+ </FlexItem>
22
+ </Flex>
23
+ </TextContent>}
24
+ </Grid>
25
+ );
26
+
27
+ WizardHeader.propTypes = {
28
+ title: PropTypes.oneOfType([
29
+ PropTypes.node,
30
+ PropTypes.string,
31
+ ]),
32
+ description: PropTypes.oneOfType([
33
+ PropTypes.node,
34
+ PropTypes.string,
35
+ ]),
36
+ };
37
+
38
+ WizardHeader.defaultProps = {
39
+ title: undefined,
40
+ description: undefined,
41
+ };
42
+
43
+
44
+ export default WizardHeader;
@@ -1,9 +1,20 @@
1
1
  .svg-centered-container {
2
2
  display: flex;
3
3
  align-items: center;
4
+ align-content: center;
5
+
6
+ .composite-component-count {
7
+ min-width: 10px;
8
+ text-align: center;
9
+ }
4
10
  }
5
11
 
6
- .svg-icon-centered {
7
- margin: 0 5px;
12
+ .svg-icon-composite {
13
+ margin: 0 6px;
8
14
  display: block;
9
15
  }
16
+
17
+ .svg-icon-component {
18
+ margin: 0 9px;
19
+ display: block;
20
+ }
@@ -1,4 +1,6 @@
1
+ import { translate as __ } from 'foremanReact/common/I18n';
1
2
  import { propsToSnakeCase } from 'foremanReact/common/helpers';
3
+ import { API_OPERATIONS, put } from 'foremanReact/redux/API';
2
4
 
3
5
  import api, { orgId } from '../../services/api';
4
6
 
@@ -6,10 +8,9 @@ import {
6
8
  GET_ORGANIZATION_REQUEST,
7
9
  GET_ORGANIZATION_SUCCESS,
8
10
  GET_ORGANIZATION_FAILURE,
9
- SAVE_ORGANIZATION_REQUEST,
10
- SAVE_ORGANIZATION_SUCCESS,
11
- SAVE_ORGANIZATION_FAILURE,
11
+ UPDATE_CDN_CONFIGURATION_KEY,
12
12
  } from './OrganizationConstants';
13
+ import { getResponseErrorMsgs } from '../../utils/helpers';
13
14
 
14
15
  export const loadOrganization = (extendedParams = {}) => async (dispatch) => {
15
16
  dispatch({ type: GET_ORGANIZATION_REQUEST });
@@ -32,28 +33,25 @@ export const loadOrganization = (extendedParams = {}) => async (dispatch) => {
32
33
  }
33
34
  };
34
35
 
35
- export const saveOrganization = (extendedParams = {}) => async (dispatch) => {
36
- dispatch({ type: SAVE_ORGANIZATION_REQUEST });
36
+ const updateCdnConfigurationSuccessToast = () => __('CDN Configuration updated.');
37
+ const updateCdnConfigurationErrorToast = (error) => {
38
+ const messages = getResponseErrorMsgs(error.response);
39
+ return messages;
40
+ };
37
41
 
38
- const params = {
39
- ...{ id: orgId() },
40
- ...propsToSnakeCase(extendedParams),
41
- };
42
- try {
43
- const { data } = await api.put(`/organizations/${orgId()}`, params);
44
- const result = dispatch({
45
- type: SAVE_ORGANIZATION_SUCCESS,
46
- response: data,
47
- });
48
- // TODO: Necessary because of https://projects.theforeman.org/issues/26420
49
- dispatch(loadOrganization());
50
- return result;
51
- } catch (error) {
52
- return dispatch({
53
- type: SAVE_ORGANIZATION_FAILURE,
54
- result: error,
55
- });
56
- }
42
+ export const updateCdnConfiguration = (params) => {
43
+ const nonNullParams = Object.keys(params)
44
+ .filter(key => params[key] !== null)
45
+ .reduce((a, k) => ({ ...a, [k]: params[k] }), {});
46
+
47
+ return put({
48
+ type: API_OPERATIONS.PUT,
49
+ key: UPDATE_CDN_CONFIGURATION_KEY,
50
+ url: api.getApiUrl(`/organizations/${orgId()}/cdn_configuration`),
51
+ params: nonNullParams,
52
+ errorToast: error => updateCdnConfigurationErrorToast(error),
53
+ successToast: response => updateCdnConfigurationSuccessToast(response),
54
+ });
57
55
  };
58
56
 
59
57
  export default loadOrganization;
@@ -2,6 +2,4 @@ export const GET_ORGANIZATION_REQUEST = 'GET_ORGANIZATION_REQUEST';
2
2
  export const GET_ORGANIZATION_SUCCESS = 'GET_ORGANIZATION_SUCCESS';
3
3
  export const GET_ORGANIZATION_FAILURE = 'GET_ORGANIZATION_FAILURE';
4
4
 
5
- export const SAVE_ORGANIZATION_REQUEST = 'SAVE_ORGANIZATION_REQUEST';
6
- export const SAVE_ORGANIZATION_SUCCESS = 'SAVE_ORGANIZATION_SUCCESS';
7
- export const SAVE_ORGANIZATION_FAILURE = 'SAVE_ORGANIZATION_FAILURE';
5
+ export const UPDATE_CDN_CONFIGURATION_KEY = 'UPDATE_CDN_CONFIGURATION';
@@ -4,9 +4,6 @@ import {
4
4
  GET_ORGANIZATION_REQUEST,
5
5
  GET_ORGANIZATION_SUCCESS,
6
6
  GET_ORGANIZATION_FAILURE,
7
- SAVE_ORGANIZATION_REQUEST,
8
- SAVE_ORGANIZATION_SUCCESS,
9
- SAVE_ORGANIZATION_FAILURE,
10
7
  } from './OrganizationConstants';
11
8
 
12
9
  const initialState = Immutable({ loading: false });
@@ -14,16 +11,12 @@ const initialState = Immutable({ loading: false });
14
11
  export default (state = initialState, action) => {
15
12
  switch (action.type) {
16
13
  case GET_ORGANIZATION_REQUEST:
17
- case SAVE_ORGANIZATION_REQUEST:
18
14
  return state.set('loading', true);
19
15
 
20
16
  case GET_ORGANIZATION_SUCCESS:
21
- case SAVE_ORGANIZATION_SUCCESS: {
22
17
  return Immutable({ loading: false, ...action.response });
23
- }
24
18
 
25
19
  case GET_ORGANIZATION_FAILURE:
26
- case SAVE_ORGANIZATION_FAILURE:
27
20
  return Immutable({ error: action.error });
28
21
 
29
22
  default:
@@ -1,3 +1,13 @@
1
+ import {
2
+ selectAPIStatus,
3
+ } from 'foremanReact/redux/API/APISelectors';
4
+
5
+ import { STATUS } from 'foremanReact/constants';
6
+
7
+ import {
8
+ UPDATE_CDN_CONFIGURATION_KEY,
9
+ } from './OrganizationConstants';
10
+
1
11
  export const selectOrganizationState = state => state.katello.organization;
2
12
 
3
13
  export const selectManifestName = state =>
@@ -16,3 +26,9 @@ export const selectIsManifestImported = state =>
16
26
 
17
27
  export const selectSimpleContentAccessEnabled = state =>
18
28
  selectOrganizationState(state).simple_content_access;
29
+
30
+ export const selectCdnConfigurationUpdateStatus = state =>
31
+ selectAPIStatus(state, UPDATE_CDN_CONFIGURATION_KEY);
32
+
33
+ export const selectUpdatingCdnConfiguration = state =>
34
+ selectCdnConfigurationUpdateStatus(state) === STATUS.PENDING;
@@ -1,5 +1,3 @@
1
- import axios from 'axios';
2
- import MockAdapter from 'axios-mock-adapter';
3
1
  import thunk from 'redux-thunk';
4
2
  import Immutable from 'seamless-immutable';
5
3
  import configureMockStore from 'redux-mock-store';
@@ -8,11 +6,9 @@ import {
8
6
  requestSuccessResponse,
9
7
  getSuccessActions,
10
8
  getFailureActions,
11
- saveSuccessActions,
12
- saveFailureActions,
13
9
  } from './organizations.fixtures';
14
10
 
15
- import { loadOrganization, saveOrganization } from '../OrganizationActions';
11
+ import { loadOrganization } from '../OrganizationActions';
16
12
 
17
13
  const mockStore = configureMockStore([thunk]);
18
14
  const store = mockStore({ organization: Immutable({}) });
@@ -40,20 +36,4 @@ describe('organization actions', () => {
40
36
  await store.dispatch(loadOrganization());
41
37
  expect(store.getActions()).toEqual(getSuccessActions);
42
38
  });
43
-
44
- it('creates SAVE_ORGANIZATION_REQUEST and then fails with 422', async () => {
45
- const mock = new MockAdapter(axios);
46
- mock.onPut('/katello/api/v2/organizations/1').reply(422);
47
-
48
- await store.dispatch(saveOrganization());
49
- expect(store.getActions()).toEqual(saveFailureActions);
50
- });
51
-
52
- it('creates SAVE_ORGANIZATION_REQUEST and ends with success', async () => {
53
- const mock = new MockAdapter(axios);
54
- mock.onPut('/katello/api/v2/organizations/1').reply(200, requestSuccessResponse);
55
-
56
- await store.dispatch(saveOrganization());
57
- expect(store.getActions()).toEqual(saveSuccessActions);
58
- });
59
39
  });
@@ -33,24 +33,4 @@ describe('organizations reducer', () => {
33
33
  error: 'Unable to process request.',
34
34
  })).toEqual(errorState);
35
35
  });
36
-
37
- it('should keep loading state on SAVE_ORGANIZATION_REQUEST', () => {
38
- expect(reducer(initialState, {
39
- type: types.SAVE_ORGANIZATION_REQUEST,
40
- })).toEqual(loadingState);
41
- });
42
-
43
- it('should flatten organization response SAVE_ORGANIZATION_SUCCESS', () => {
44
- expect(reducer(initialState, {
45
- type: types.SAVE_ORGANIZATION_SUCCESS,
46
- response: requestSuccessResponse,
47
- })).toEqual(successState);
48
- });
49
-
50
- it('should have error on SAVE_ORGANIZATION_FAILURE', () => {
51
- expect(reducer(initialState, {
52
- type: types.SAVE_ORGANIZATION_FAILURE,
53
- error: 'Unable to process request.',
54
- })).toEqual(errorState);
55
- });
56
36
  });
@@ -8,6 +8,40 @@ export const loadingState = Immutable({
8
8
  loading: true,
9
9
  });
10
10
 
11
+ export const updateCdnConfigurationSuccessResponse = Immutable({
12
+ id: '6c536461-e7e3-421a-9d7a-780a39cd8fb4',
13
+ label: 'Actions::Katello::CdnConfiguration::Update',
14
+ pending: false,
15
+ action: 'Update CDN Configuration',
16
+ username: 'admin',
17
+ started_at: '2021-11-16 12:00:46 -0500',
18
+ ended_at: '2021-11-16 12:00:47 -0500',
19
+ state: 'stopped',
20
+ result: 'success',
21
+ progress: 1,
22
+ input: {
23
+ locale: 'en',
24
+ current_request_id: '7a0d7e03-ced1-4925-8790-79b73d25d29b',
25
+ current_timezone: 'America/New_York',
26
+ current_organization_id: 4,
27
+ current_location_id: 2,
28
+ current_user_id: 4,
29
+ },
30
+ output: {},
31
+ humanized: {
32
+ action: 'Update CDN Configuration',
33
+ input: [],
34
+ output: '',
35
+ errors: [],
36
+ },
37
+ cli_example: null,
38
+ start_at: '2021-11-16 12:00:46 -0500',
39
+ available_actions: {
40
+ cancellable: false,
41
+ resumable: false,
42
+ },
43
+ });
44
+
11
45
  export const requestSuccessResponse = Immutable({
12
46
  label: 'Default_Organization',
13
47
  owner_details: {
@@ -77,26 +111,3 @@ export const getFailureActions = [
77
111
  type: 'GET_ORGANIZATION_FAILURE',
78
112
  },
79
113
  ];
80
-
81
- export const saveSuccessActions = [
82
- {
83
- type: 'SAVE_ORGANIZATION_REQUEST',
84
- },
85
- {
86
- response: requestSuccessResponse,
87
- type: 'SAVE_ORGANIZATION_SUCCESS',
88
- },
89
- {
90
- type: 'GET_ORGANIZATION_REQUEST',
91
- },
92
- ];
93
-
94
- export const saveFailureActions = [
95
- {
96
- type: 'SAVE_ORGANIZATION_REQUEST',
97
- },
98
- {
99
- result: new Error('Request failed with status code 422'),
100
- type: 'SAVE_ORGANIZATION_FAILURE',
101
- },
102
- ];
@@ -0,0 +1,185 @@
1
+ import React, { useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { useDispatch, useSelector } from 'react-redux';
4
+
5
+ import {
6
+ ActionGroup,
7
+ Alert,
8
+ Button,
9
+ Form,
10
+ FormAlert,
11
+ FormGroup,
12
+ FormSelect,
13
+ FormSelectOption,
14
+ TextInput,
15
+ } from '@patternfly/react-core';
16
+
17
+ import { translate as __ } from 'foremanReact/common/I18n';
18
+
19
+ import EditableTextInput from '../../../components/EditableTextInput';
20
+
21
+ import {
22
+ selectUpdatingCdnConfiguration,
23
+ } from '../../Organizations/OrganizationSelectors';
24
+
25
+ import { updateCdnConfiguration } from '../../Organizations/OrganizationActions';
26
+ import './CdnConfigurationForm.scss';
27
+
28
+ const CdnConfigurationForm = (props) => {
29
+ const {
30
+ contentCredentials,
31
+ cdnConfiguration,
32
+ } = props;
33
+
34
+ const dispatch = useDispatch();
35
+
36
+ const [url, setUrl] = useState(cdnConfiguration.url);
37
+ const [username, setUsername] = useState(cdnConfiguration.username);
38
+ const [password, setPassword] = useState(null);
39
+ const [organizationLabel, setOrganizationLabel] =
40
+ useState(cdnConfiguration.upstream_organization_label);
41
+ const [sslCaCredentialId, setSslCaCredentialId] = useState(cdnConfiguration.ssl_ca_credential_id);
42
+ const updatingCdnConfiguration = useSelector(state => selectUpdatingCdnConfiguration(state));
43
+
44
+ const editPassword = (value) => {
45
+ if (value === null) {
46
+ setPassword('');
47
+ } else {
48
+ setPassword(value);
49
+ }
50
+ };
51
+
52
+ const hasPassword = (cdnConfiguration.password_exists && password === null)
53
+ || password?.length > 0;
54
+
55
+ const requiresValidation = username || password || organizationLabel || sslCaCredentialId;
56
+
57
+ const requiredFields = [username, organizationLabel, sslCaCredentialId];
58
+
59
+ if (!hasPassword) {
60
+ requiredFields.push(password);
61
+ }
62
+
63
+ const validated = requiresValidation ?
64
+ !requiredFields.some(field => !field) :
65
+ true;
66
+
67
+ const performUpdate = () => {
68
+ dispatch(updateCdnConfiguration({
69
+ url,
70
+ username,
71
+ password,
72
+ upstream_organization_label: organizationLabel,
73
+ ssl_ca_credential_id: sslCaCredentialId,
74
+ }));
75
+ };
76
+
77
+ return (
78
+ <div id="cdn-configuration">
79
+ <Form isHorizontal>
80
+ { !validated && (
81
+ <FormAlert>
82
+ <Alert
83
+ variant="danger"
84
+ title={__('Username, Password, Organization Label, and SSL CA Content Credential must be provided together.')}
85
+ aria-live="polite"
86
+ isInline
87
+ />
88
+ </FormAlert>
89
+ )}
90
+ <FormGroup
91
+ label={__('URL')}
92
+ isRequired
93
+ >
94
+ <TextInput
95
+ isRequired
96
+ aria-label="cdn-url"
97
+ type="text"
98
+ value={url || ''}
99
+ onChange={value => setUrl(value)}
100
+ />
101
+ </FormGroup>
102
+ <FormGroup
103
+ label={__('Username')}
104
+ isRequired={requiresValidation}
105
+ >
106
+ <TextInput
107
+ aria-label="cdn-username"
108
+ type="text"
109
+ value={username || ''}
110
+ onChange={value => setUsername(value)}
111
+ />
112
+ </FormGroup>
113
+ <FormGroup
114
+ label={__('Password')}
115
+ isRequired={requiresValidation}
116
+ >
117
+ <EditableTextInput
118
+ attribute="cdn-password"
119
+ value={password}
120
+ isPassword
121
+ hasPassword={hasPassword}
122
+ onEdit={editPassword}
123
+ />
124
+ </FormGroup>
125
+ <FormGroup
126
+ label={__('Organization Label')}
127
+ isRequired={requiresValidation}
128
+ >
129
+ <TextInput
130
+ aria-label="cdn-organization-label"
131
+ type="text"
132
+ value={organizationLabel || ''}
133
+ onChange={value => setOrganizationLabel(value)}
134
+ />
135
+ </FormGroup>
136
+ <FormGroup
137
+ label={__('SSL CA Content Credential')}
138
+ isRequired={requiresValidation}
139
+ >
140
+ <FormSelect
141
+ aria-label="cdn-ssl-ca-content-credential"
142
+ value={sslCaCredentialId || ''}
143
+ onChange={value => setSslCaCredentialId(value)}
144
+ >
145
+ <FormSelectOption label={__('Select one')} isDisabled isPlaceholder />
146
+ {contentCredentials.map(cred =>
147
+ <FormSelectOption data-testid="ssl-ca-content-credential-option" key={cred.id} value={cred.id} label={cred.name} />)}
148
+ </FormSelect>
149
+ </FormGroup>
150
+ <ActionGroup>
151
+ <Button
152
+ aria-label="update-cdn-configuration"
153
+ variant="secondary"
154
+ onClick={performUpdate}
155
+ isDisabled={updatingCdnConfiguration || !validated}
156
+ isLoading={updatingCdnConfiguration}
157
+ >
158
+ {__('Update')}
159
+ </Button>
160
+ </ActionGroup>
161
+ </Form>
162
+ </div>
163
+ );
164
+ };
165
+
166
+ CdnConfigurationForm.propTypes = {
167
+ contentCredentials: PropTypes.arrayOf(PropTypes.shape({
168
+ id: PropTypes.number,
169
+ name: PropTypes.string,
170
+ })),
171
+ cdnConfiguration: PropTypes.shape({
172
+ url: PropTypes.string,
173
+ username: PropTypes.string,
174
+ upstream_organization_label: PropTypes.string,
175
+ ssl_ca_credential_id: PropTypes.number,
176
+ password_exists: PropTypes.bool,
177
+ }),
178
+ };
179
+
180
+ CdnConfigurationForm.defaultProps = {
181
+ contentCredentials: [],
182
+ cdnConfiguration: {},
183
+ };
184
+
185
+ export default CdnConfigurationForm;
@@ -0,0 +1,3 @@
1
+ .pf-c-form__group.pf-m-action {
2
+ margin-top: 0px;
3
+ }