katello 4.6.2.1 → 4.7.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of katello might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/assets/javascripts/katello/common/vendor.js +0 -1
- data/app/controllers/katello/api/v2/activation_keys_controller.rb +1 -0
- data/app/controllers/katello/api/v2/alternate_content_sources_controller.rb +4 -4
- data/app/controllers/katello/api/v2/capsule_content_controller.rb +5 -0
- data/app/controllers/katello/api/v2/content_imports_controller.rb +1 -0
- data/app/controllers/katello/api/v2/content_view_components_controller.rb +1 -1
- data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +2 -1
- data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +1 -1
- data/app/controllers/katello/api/v2/organizations_controller.rb +1 -0
- data/app/controllers/katello/api/v2/repositories_controller.rb +78 -12
- data/app/controllers/katello/api/v2/upstream_subscriptions_controller.rb +1 -1
- data/app/controllers/katello/concerns/api/v2/registration_controller_extensions.rb +7 -1
- data/app/controllers/katello/concerns/api/v2/smart_proxies_controller_extensions.rb +1 -0
- data/app/controllers/katello/concerns/hosts_controller_extensions.rb +11 -9
- data/app/helpers/katello/content_source_helper.rb +9 -0
- data/app/helpers/katello/hosts_and_hostgroups_helper.rb +31 -0
- data/app/lib/actions/katello/activation_key/destroy.rb +1 -0
- data/app/lib/actions/katello/agent_action.rb +1 -0
- data/app/lib/actions/katello/alternate_content_source/create.rb +1 -1
- data/app/lib/actions/katello/alternate_content_source/update.rb +2 -2
- data/app/lib/actions/katello/capsule_content/sync.rb +10 -2
- data/app/lib/actions/katello/cdn_configuration/update.rb +1 -1
- data/app/lib/actions/katello/content_view/promote.rb +1 -0
- data/app/lib/actions/katello/content_view/publish.rb +5 -2
- data/app/lib/actions/katello/content_view_version/auto_create_redhat_repositories.rb +7 -3
- data/app/lib/actions/katello/content_view_version/auto_create_repositories.rb +4 -2
- data/app/lib/actions/katello/content_view_version/import.rb +22 -10
- data/app/lib/actions/katello/product/destroy.rb +1 -1
- data/app/lib/actions/katello/repository/destroy.rb +3 -3
- data/app/lib/actions/katello/repository/errata_mail.rb +9 -6
- data/app/lib/actions/katello/repository/refresh_repository.rb +1 -1
- data/app/lib/actions/katello/repository/sync.rb +13 -6
- data/app/lib/actions/katello/repository_set/enable_repository.rb +6 -2
- data/app/lib/actions/pulp3/alternate_content_source/refresh_remote.rb +16 -0
- data/app/lib/actions/pulp3/orchestration/alternate_content_source/refresh.rb +1 -0
- data/app/lib/actions/pulp3/orchestration/content_view_version/export_library.rb +1 -1
- data/app/lib/actions/pulp3/orchestration/content_view_version/export_repository.rb +10 -2
- data/app/lib/katello/concerns/renderer_extensions.rb +2 -1
- data/app/lib/katello/errors.rb +2 -2
- data/app/lib/katello/resources/candlepin.rb +7 -1
- data/app/lib/katello/resources/cdn/katello_cdn.rb +3 -13
- data/app/lib/katello/resources/cdn.rb +14 -9
- data/app/lib/katello/util/candlepin_repository_checker.rb +73 -0
- data/app/models/katello/activation_key.rb +12 -1
- data/app/models/katello/alternate_content_source.rb +15 -4
- data/app/models/katello/alternate_content_source_product.rb +1 -1
- data/app/models/katello/authorization/repository.rb +2 -2
- data/app/models/katello/cdn_configuration.rb +12 -3
- data/app/models/katello/concerns/host_managed_extensions.rb +15 -2
- data/app/models/katello/concerns/http_proxy_extensions.rb +5 -10
- data/app/models/katello/concerns/smart_proxy_extensions.rb +30 -15
- data/app/models/katello/content.rb +15 -0
- data/app/models/katello/content_credential.rb +8 -9
- data/app/models/katello/content_view.rb +7 -3
- data/app/models/katello/content_view_component.rb +4 -0
- data/app/models/katello/content_view_version.rb +1 -1
- data/app/models/katello/erratum.rb +6 -2
- data/app/models/katello/host/content_facet.rb +13 -3
- data/app/models/katello/repository.rb +15 -1
- data/app/models/katello/root_repository.rb +0 -2
- data/app/overrides/add_smart_proxy_form.rb +5 -0
- data/app/presenters/katello/content_view_version_compare_presenter.rb +5 -0
- data/app/presenters/katello/host_package_presenter.rb +4 -4
- data/app/services/katello/pulp3/alternate_content_source.rb +23 -15
- data/app/services/katello/pulp3/ansible_collection.rb +7 -10
- data/app/services/katello/pulp3/content_view_version/export.rb +19 -6
- data/app/services/katello/pulp3/content_view_version/import.rb +2 -0
- data/app/services/katello/pulp3/content_view_version/import_validator.rb +21 -5
- data/app/services/katello/pulp3/content_view_version/importable_products.rb +11 -1
- data/app/services/katello/pulp3/content_view_version/importable_repositories.rb +38 -9
- data/app/services/katello/pulp3/content_view_version/metadata_generator.rb +12 -5
- data/app/services/katello/pulp3/content_view_version/metadata_map.rb +13 -2
- data/app/services/katello/pulp3/content_view_version/syncable_format_export.rb +5 -1
- data/app/services/katello/pulp3/pulp_content_unit.rb +3 -0
- data/app/services/katello/pulp3/repository.rb +18 -6
- data/app/services/katello/pulp3/repository_mirror.rb +0 -1
- data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +2 -2
- data/app/services/katello/pulp3/task_group.rb +18 -1
- data/app/services/katello/repository_type.rb +5 -2
- data/app/services/katello/repository_type_manager.rb +4 -3
- data/app/views/dashboard/_content_views_widget.html.erb +1 -1
- data/app/views/foreman/job_templates/change_content_source.erb +6 -0
- data/app/views/foreman/job_templates/update_packages_by_search_query.erb +7 -1
- data/app/views/katello/api/v2/alternate_content_sources/base.json.rabl +4 -4
- data/app/views/katello/api/v2/alternate_content_sources/index.json.rabl +1 -0
- data/app/views/katello/api/v2/alternate_content_sources/permissions.rabl +11 -0
- data/app/views/katello/api/v2/content_credentials/show.json.rabl +12 -0
- data/app/views/katello/api/v2/content_views/permissions.rabl +1 -0
- data/app/views/katello/api/v2/host_packages/base.json.rabl +1 -1
- data/app/views/katello/api/v2/module_streams/show.json.rabl +7 -0
- data/app/views/katello/api/v2/repositories/compare.json.rabl +10 -0
- data/app/views/katello/api/v2/smart_proxies/pulp_info.json.rabl +1 -0
- data/app/views/katello/hosts/_errata_counts.html.erb +46 -0
- data/app/views/overrides/activation_keys/_host_synced_content_select.html.erb +1 -0
- data/app/views/overrides/smart_proxies/_acs_http_proxy.html.erb +6 -0
- data/config/initializers/monkeys.rb +1 -0
- data/config/routes/api/v2.rb +2 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20220730033504_update_custom_cdn.rb +13 -0
- data/db/migrate/20220920173656_add_http_proxy_to_smart_proxy.rb +7 -0
- data/db/migrate/20220920180858_remove_http_proxy_from_katello_alternate_content_sources.rb +6 -0
- data/engines/bastion/app/assets/javascripts/bastion/components/notification.service.js +1 -1
- data/engines/bastion/app/views/bastion/layouts/assets.html.erb +5 -5
- data/engines/bastion/vendor/assets/javascripts/bastion/angular/angular.js +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credential.factory.js +17 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/content-credentials.routes.js +10 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-acs.controller.js +36 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/content-credential-details.controller.js +7 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/views/content-credential-acs.html +38 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/details/views/content-credential-details.html +3 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-credentials/views/content-credentials.html +7 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content-hosts.controller.js +4 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-info.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +4 -3
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +14 -1392
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/katello-features.run.js +1 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +7 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +1 -1
- data/lib/katello/permission_creator.rb +1 -0
- data/lib/katello/plugin.rb +34 -11
- data/lib/katello/repository_types/deb.rb +1 -1
- data/lib/katello/repository_types/docker.rb +1 -1
- data/lib/katello/repository_types/python.rb +3 -3
- data/lib/katello/tasks/check_candlepin_content.rake +16 -0
- data/lib/katello/tasks/reset.rake +1 -1
- data/lib/katello/version.rb +1 -1
- data/lib/monkeys/try_pulp_container_path.rb +35 -0
- data/locale/action_names.rb +7 -7
- data/locale/bn/katello.po +395 -63
- data/locale/cs/katello.po +396 -64
- data/locale/de/katello.po +399 -67
- data/locale/en/katello.po +395 -63
- data/locale/es/katello.po +399 -67
- data/locale/fr/katello.po +400 -68
- data/locale/gu/katello.po +395 -63
- data/locale/hi/katello.po +395 -63
- data/locale/it/katello.po +396 -64
- data/locale/ja/katello.po +400 -68
- data/locale/katello.pot +1916 -1213
- data/locale/kn/katello.po +395 -63
- data/locale/ko/katello.po +396 -64
- data/locale/mr/katello.po +395 -63
- data/locale/or/katello.po +395 -63
- data/locale/pa/katello.po +395 -63
- data/locale/pt/katello.po +395 -63
- data/locale/pt_BR/katello.po +399 -67
- data/locale/ru/katello.po +396 -64
- data/locale/ta/katello.po +395 -63
- data/locale/te/katello.po +395 -63
- data/locale/zh_CN/katello.po +400 -68
- data/locale/zh_TW/katello.po +396 -64
- data/webpack/components/Bookmark/index.js +5 -1
- data/webpack/components/Content/Details/ContentDetails.js +1 -1
- data/webpack/components/Content/Details/__tests__/__snapshots__/ContentDetails.test.js.snap +6 -0
- data/webpack/components/EditableSwitch.js +1 -0
- data/webpack/components/EditableTextInput/EditableTextInput.js +3 -3
- data/webpack/components/Errata/errataHelpers.js +33 -0
- data/webpack/components/Errata/index.js +45 -12
- data/webpack/components/Loading.js +18 -8
- data/webpack/components/Packages/index.js +8 -24
- data/webpack/components/RoutedTabs/index.js +1 -0
- data/webpack/components/Search/Search.js +20 -2
- data/webpack/components/Search/__tests__/search.test.js +3 -3
- data/webpack/components/Table/EmptyStateMessage.js +1 -1
- data/webpack/components/Table/PageControls.js +1 -0
- data/webpack/components/Table/TableHooks.js +4 -0
- data/webpack/components/Table/TableWrapper.js +7 -7
- data/webpack/components/TypeAhead/pf4Search/TypeAheadInput.js +1 -0
- data/webpack/components/TypeAhead/pf4Search/TypeAheadItems.js +2 -0
- data/webpack/components/TypeAhead/pf4Search/TypeAheadSearch.js +1 -1
- data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ChangeHostCVModal.js +3 -1
- data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard.js +2 -1
- data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.js +124 -68
- data/webpack/components/extensions/HostDetails/Cards/ErrataOverviewCard.scss +5 -0
- data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.js +30 -4
- data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsCard.scss +23 -0
- data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/HostCollectionsModal.js +5 -4
- data/webpack/components/extensions/HostDetails/Cards/HostCollectionsCard/__tests__/hostCollectionsCard.test.js +25 -10
- data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeCard.js +3 -3
- data/webpack/components/extensions/HostDetails/Cards/SystemPurposeCard/SystemPurposeEditModal.js +6 -0
- data/webpack/components/extensions/HostDetails/Cards/__tests__/errataOverviewCard.test.js +145 -32
- data/webpack/components/extensions/HostDetails/DetailsTabCards/RegistrationCard.js +3 -1
- data/webpack/components/extensions/HostDetails/Tabs/ContentTab/constants.js +2 -1
- data/webpack/components/extensions/HostDetails/Tabs/ContentTab/index.js +1 -0
- data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +78 -26
- data/webpack/components/extensions/HostDetails/Tabs/ModuleStreamsTab/ModuleStreamsTab.js +23 -10
- data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/HostPackagesConstants.js +1 -0
- data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackageInstallModal.js +9 -4
- data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.js +141 -23
- data/webpack/components/extensions/HostDetails/Tabs/PackagesTab/PackagesTab.scss +6 -1
- data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +9 -8
- data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +24 -3
- data/webpack/components/extensions/HostDetails/Tabs/TracesTab/EnableTracerModal.js +7 -2
- data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesEnabler.js +2 -1
- data/webpack/components/extensions/HostDetails/Tabs/TracesTab/TracesTab.js +20 -4
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +56 -38
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/packages.fixtures.json +3 -3
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +5 -4
- data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +3 -3
- data/webpack/containers/Application/config.js +2 -2
- data/webpack/containers/Application/overrides.scss +12 -0
- data/webpack/global_test_setup.js +19 -1
- data/webpack/ouia_id_check.js +0 -2
- data/webpack/redux/actions/RedHatRepositories/helpers.js +4 -8
- data/webpack/scenes/AlternateContentSources/ACSActions.js +37 -6
- data/webpack/scenes/AlternateContentSources/ACSConstants.js +2 -0
- data/webpack/scenes/AlternateContentSources/ACSIndexPage.js +1 -1
- data/webpack/scenes/AlternateContentSources/ACSSelectors.js +6 -6
- data/webpack/scenes/AlternateContentSources/Acs.scss +3 -0
- data/webpack/scenes/AlternateContentSources/Create/ACSCreateWizard.js +24 -3
- data/webpack/scenes/AlternateContentSources/Create/Steps/ACSCreateFinish.js +10 -8
- data/webpack/scenes/AlternateContentSources/Create/Steps/ACSCredentials.js +25 -4
- data/webpack/scenes/AlternateContentSources/Create/Steps/ACSReview.js +22 -11
- data/webpack/scenes/AlternateContentSources/Create/Steps/ACSSmartProxies.js +27 -2
- data/webpack/scenes/AlternateContentSources/Create/Steps/AcsUrlPaths.js +49 -17
- data/webpack/scenes/AlternateContentSources/Create/Steps/SelectSource.js +76 -23
- data/webpack/scenes/AlternateContentSources/Create/__tests__/acsCreate.test.js +159 -11
- data/webpack/scenes/AlternateContentSources/Details/ACSExpandableDetails.js +83 -29
- data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditCredentials.js +9 -8
- data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditDetails.js +2 -2
- data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditProducts.js +2 -2
- data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditSmartProxies.js +39 -7
- data/webpack/scenes/AlternateContentSources/Details/EditModals/ACSEditURLPaths.js +27 -11
- data/webpack/scenes/AlternateContentSources/Details/__tests__/ACSEdits.test.js +58 -55
- data/webpack/scenes/AlternateContentSources/Details/__tests__/ACSExpandableDetails.test.js +35 -32
- data/webpack/scenes/AlternateContentSources/MainTable/ACSTable.js +323 -150
- data/webpack/scenes/AlternateContentSources/MainTable/__tests__/acsIndex.fixtures.json +5 -1
- data/webpack/scenes/AlternateContentSources/MainTable/__tests__/acsTable.test.js +10 -11
- data/webpack/scenes/AlternateContentSources/helpers.js +26 -0
- data/webpack/scenes/ContentViews/ContentViewsConstants.js +1 -0
- data/webpack/scenes/ContentViews/ContentViewsPage.js +1 -1
- data/webpack/scenes/ContentViews/Copy/CopyContentViewForm.js +1 -0
- data/webpack/scenes/ContentViews/Copy/CopyContentViewModal.js +1 -0
- data/webpack/scenes/ContentViews/Create/ContentViewFormComponents.js +10 -5
- data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +30 -7
- data/webpack/scenes/ContentViews/Create/CreateContentViewModal.js +1 -0
- data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +21 -6
- data/webpack/scenes/ContentViews/Delete/Steps/CVDeleteEnvironmentsSelection.js +3 -3
- data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionReassignActivationKeysForm.js +1 -0
- data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionReassignHostsForm.js +1 -0
- data/webpack/scenes/ContentViews/Delete/__tests__/CvData.fixtures.json +2 -0
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +3 -0
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +4 -1
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentVersion.js +1 -1
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +2 -1
- data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +14 -0
- data/webpack/scenes/ContentViews/Details/ContentViewDetailSelectors.js +11 -1
- data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +1 -1
- data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +2 -0
- data/webpack/scenes/ContentViews/Details/Filters/Add/CVFilterAddModal.js +5 -0
- data/webpack/scenes/ContentViews/Details/Filters/AffectedRepositories/AffectedRepositorySelection.js +1 -0
- data/webpack/scenes/ContentViews/Details/Filters/ArtifactsWithNoErrata.js +1 -0
- data/webpack/scenes/ContentViews/Details/Filters/CVContainerImageFilterContent.js +8 -2
- data/webpack/scenes/ContentViews/Details/Filters/CVDebFilterContent.js +5 -1
- data/webpack/scenes/ContentViews/Details/Filters/CVErrataDateFilterContent.js +22 -6
- data/webpack/scenes/ContentViews/Details/Filters/CVErrataIDFilterContent.js +19 -9
- data/webpack/scenes/ContentViews/Details/Filters/CVModuleStreamFilterContent.js +9 -2
- data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +9 -2
- data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +8 -2
- data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilterDetailsHeader.js +1 -1
- data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilters.js +2 -1
- data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/CVRpmMatchContentModal.js +3 -2
- data/webpack/scenes/ContentViews/Details/Filters/MatchContentModal/__tests__/CVRpmMatchContentModal.test.js +1 -1
- data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVContainerImageFilterContent.test.js +2 -2
- data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVRpmFilterContent.test.js +1 -1
- data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilterDetails.test.js +1 -1
- data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilters.test.js +1 -1
- data/webpack/scenes/ContentViews/Details/Histories/ContentViewHistories.js +2 -2
- data/webpack/scenes/ContentViews/Details/Promote/ContentViewVersionPromote.js +2 -0
- data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +2 -1
- data/webpack/scenes/ContentViews/Details/Versions/BulkDelete/Steps/ReviewEnvironments.js +3 -3
- data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompare.js +9 -1
- data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareConfig.js +83 -0
- data/webpack/scenes/ContentViews/Details/Versions/Compare/CVVersionCompareTable.js +32 -8
- data/webpack/scenes/ContentViews/Details/Versions/Compare/__tests__/CVVersionCompare.test.js +56 -3
- data/webpack/scenes/ContentViews/Details/Versions/Compare/__tests__/cvCompareRepositories.fixtures.json +175 -0
- data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +6 -2
- data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVEnvironmentSelectionForm.js +3 -3
- data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignActivationKeysForm.js +1 -0
- data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVReassignHostsForm.js +1 -0
- data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedActivationKeys.js +2 -2
- data/webpack/scenes/ContentViews/Details/Versions/Delete/affectedHosts.js +2 -2
- data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailConfig.js +2 -2
- data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetails.js +1 -0
- data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsHeader.js +4 -1
- data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailsTable.js +5 -4
- data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +5 -1
- data/webpack/scenes/ContentViews/Publish/CVPublishReview.js +3 -3
- data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +10 -5
- data/webpack/scenes/ContentViews/__tests__/basicContentViews.fixtures.js +2 -0
- data/webpack/scenes/ContentViews/__tests__/contentViewList.fixtures.json +1 -0
- data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +81 -19
- data/webpack/scenes/ContentViews/components/CVBreadCrumb.js +1 -1
- data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.js +1 -0
- data/webpack/scenes/ContentViews/components/InactiveText.js +9 -1
- data/webpack/scenes/ContentViews/expansions/RelatedCompositeContentViewsModal.js +4 -2
- data/webpack/scenes/ContentViews/expansions/RelatedContentViewComponentsModal.js +3 -2
- data/webpack/scenes/Hosts/ChangeContentSource/actions.js +18 -11
- data/webpack/scenes/Hosts/ChangeContentSource/components/ContentSourceForm.js +15 -8
- data/webpack/scenes/Hosts/ChangeContentSource/components/FormField.js +3 -4
- data/webpack/scenes/Hosts/ChangeContentSource/components/Hosts.js +55 -0
- data/webpack/scenes/Hosts/ChangeContentSource/components/HostsModal.js +59 -0
- data/webpack/scenes/Hosts/ChangeContentSource/constants.js +1 -0
- data/webpack/scenes/Hosts/ChangeContentSource/helpers.js +2 -5
- data/webpack/scenes/Hosts/ChangeContentSource/index.js +46 -41
- data/webpack/scenes/Hosts/ChangeContentSource/selectors.js +5 -5
- data/webpack/scenes/ModuleStreams/Details/ModuleDetailsSchema.js +10 -1
- data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetails.js +1 -1
- data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetails.test.js.snap +97 -2
- data/webpack/scenes/Organizations/OrganizationSelectors.js +1 -0
- data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnConfigurationConstants.js +2 -1
- data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CdnTypeForm.js +10 -25
- data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/CustomCdnTypeForm.js +154 -0
- data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/ExportSyncForm.js +4 -4
- data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/NetworkSyncForm.js +59 -44
- data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/CdnTypeForm.test.js +3 -28
- data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/CustomCdnTypeForm.test.js +97 -0
- data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/ExportSyncForm.test.js +1 -1
- data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/__tests__/NetworkSyncForm.test.js +4 -4
- data/webpack/scenes/Subscriptions/Manifest/CdnConfigurationTab/index.js +23 -10
- data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +1 -1
- data/webpack/scenes/Subscriptions/SubscriptionConstants.js +2 -1
- data/webpack/scenes/Subscriptions/SubscriptionsPage.js +5 -5
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +3 -3
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/__snapshots__/UpstreamSubscriptionsPage.test.js.snap +2 -2
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +3 -3
- data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.js +3 -3
- data/webpack/scenes/Tasks/helpers.js +14 -7
- metadata +54 -35
- data/app/lib/actions/pulp3/orchestration/alternate_content_source/refresh_remote.rb +0 -18
- data/db/migrate/20221206170122_update_ignore_srpm_to_false_for_mirror_complete.rb +0 -5
- data/vendor/assets/javascripts/katello/jquery.trunk8.js +0 -203
@@ -41,7 +41,11 @@ const ContentViewTable = () => {
|
|
41
41
|
const [actionableCvName, setActionableCvName] = useState('');
|
42
42
|
const dispatch = useDispatch();
|
43
43
|
const metadata = omit(response, ['results']);
|
44
|
-
const {
|
44
|
+
const {
|
45
|
+
can_create: canCreate = false,
|
46
|
+
can_view: canView = false,
|
47
|
+
results,
|
48
|
+
} = response;
|
45
49
|
const columnHeaders = [
|
46
50
|
__('Type'),
|
47
51
|
__('Name'),
|
@@ -152,6 +156,7 @@ const ContentViewTable = () => {
|
|
152
156
|
fetchItems,
|
153
157
|
showPrimaryAction,
|
154
158
|
}}
|
159
|
+
hideSearch={!canView}
|
155
160
|
ouiaId="content-views-table"
|
156
161
|
additionalListeners={[activeSortColumn, activeSortDirection]}
|
157
162
|
bookmarkController="katello_content_views"
|
@@ -168,7 +173,7 @@ const ContentViewTable = () => {
|
|
168
173
|
</Button >) : undefined}
|
169
174
|
actionButtons={
|
170
175
|
<>
|
171
|
-
{results?.length !== 0 &&
|
176
|
+
{results?.length !== 0 && canCreate &&
|
172
177
|
<Button ouiaId="create-content-view" onClick={openForm} variant="primary" aria-label="create_content_view">
|
173
178
|
{__('Create content view')}
|
174
179
|
</Button>
|
@@ -214,7 +219,7 @@ const ContentViewTable = () => {
|
|
214
219
|
}
|
215
220
|
>
|
216
221
|
<Thead>
|
217
|
-
<Tr>
|
222
|
+
<Tr ouiaId="cvTableHeaderRow">
|
218
223
|
<Th key="expand-carat" />
|
219
224
|
{columnHeaders.map(col => (
|
220
225
|
<Th
|
@@ -249,7 +254,7 @@ const ContentViewTable = () => {
|
|
249
254
|
const isExpanded = tableRowIsExpanded(cvId);
|
250
255
|
return (
|
251
256
|
<Tbody isExpanded={isExpanded} key={`${cvId}_${createdAt}`}>
|
252
|
-
<Tr key={cvId}>
|
257
|
+
<Tr key={cvId} ouiaId={`ContentViewTableRow-${cvId}`}>
|
253
258
|
<Td
|
254
259
|
expand={{
|
255
260
|
rowIndex,
|
@@ -279,7 +284,7 @@ const ContentViewTable = () => {
|
|
279
284
|
}}
|
280
285
|
/>
|
281
286
|
</Tr>
|
282
|
-
<Tr key="child_row" isExpanded={isExpanded}>
|
287
|
+
<Tr key="child_row" ouiaId={`ContentViewTableRowChild-${cvId}`} isExpanded={isExpanded}>
|
283
288
|
<Td colSpan={2}>
|
284
289
|
<ExpandableRowContent>
|
285
290
|
<DetailsExpansion
|
@@ -22,17 +22,6 @@ let scopeBookmark;
|
|
22
22
|
beforeEach(() => {
|
23
23
|
const { results } = cvIndexData;
|
24
24
|
[firstCV] = results;
|
25
|
-
scopeBookmark = nockInstance
|
26
|
-
.get('/api/v2/bookmarks')
|
27
|
-
.query(true)
|
28
|
-
.reply(200, {});
|
29
|
-
searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
|
30
|
-
autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
|
31
|
-
});
|
32
|
-
|
33
|
-
afterEach(() => {
|
34
|
-
assertNockRequest(searchDelayScope);
|
35
|
-
assertNockRequest(autoSearchScope);
|
36
25
|
});
|
37
26
|
|
38
27
|
test('Can call API for CVs and show on screen on page load', async (done) => {
|
@@ -41,6 +30,12 @@ test('Can call API for CVs and show on screen on page load', async (done) => {
|
|
41
30
|
.get(cvIndexPath)
|
42
31
|
.query(true)
|
43
32
|
.reply(200, cvIndexData);
|
33
|
+
searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
|
34
|
+
autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
|
35
|
+
scopeBookmark = nockInstance
|
36
|
+
.get('/api/v2/bookmarks')
|
37
|
+
.query(true)
|
38
|
+
.reply(200, {});
|
44
39
|
|
45
40
|
const { queryByText, queryAllByText } = renderWithRedux(<ContentViewsPage />, renderOptions);
|
46
41
|
|
@@ -56,6 +51,8 @@ test('Can call API for CVs and show on screen on page load', async (done) => {
|
|
56
51
|
|
57
52
|
assertNockRequest(scopeBookmark);
|
58
53
|
assertNockRequest(autocompleteScope);
|
54
|
+
assertNockRequest(searchDelayScope);
|
55
|
+
assertNockRequest(autoSearchScope);
|
59
56
|
assertNockRequest(scope, done);
|
60
57
|
});
|
61
58
|
|
@@ -65,6 +62,12 @@ test('Can show last task and link to it', async (done) => {
|
|
65
62
|
.get(cvIndexPath)
|
66
63
|
.query(true)
|
67
64
|
.reply(200, cvIndexData);
|
65
|
+
searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
|
66
|
+
autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
|
67
|
+
scopeBookmark = nockInstance
|
68
|
+
.get('/api/v2/bookmarks')
|
69
|
+
.query(true)
|
70
|
+
.reply(200, {});
|
68
71
|
|
69
72
|
const { getByText, queryByText } = renderWithRedux(<ContentViewsPage />, renderOptions);
|
70
73
|
|
@@ -81,6 +84,8 @@ test('Can show last task and link to it', async (done) => {
|
|
81
84
|
|
82
85
|
assertNockRequest(scopeBookmark);
|
83
86
|
assertNockRequest(autocompleteScope);
|
87
|
+
assertNockRequest(searchDelayScope);
|
88
|
+
assertNockRequest(autoSearchScope);
|
84
89
|
assertNockRequest(scope, done); // Pass jest callback to confirm test is done
|
85
90
|
});
|
86
91
|
|
@@ -90,6 +95,12 @@ test('Can show latest version and link to it', async (done) => {
|
|
90
95
|
.get(cvIndexPath)
|
91
96
|
.query(true)
|
92
97
|
.reply(200, cvIndexData);
|
98
|
+
searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
|
99
|
+
autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
|
100
|
+
scopeBookmark = nockInstance
|
101
|
+
.get('/api/v2/bookmarks')
|
102
|
+
.query(true)
|
103
|
+
.reply(200, {});
|
93
104
|
|
94
105
|
const {
|
95
106
|
getByText,
|
@@ -114,6 +125,8 @@ test('Can show latest version and link to it', async (done) => {
|
|
114
125
|
});
|
115
126
|
assertNockRequest(scopeBookmark);
|
116
127
|
assertNockRequest(autocompleteScope);
|
128
|
+
assertNockRequest(searchDelayScope);
|
129
|
+
assertNockRequest(autoSearchScope);
|
117
130
|
assertNockRequest(scope, done); // Pass jest callback to confirm test is done
|
118
131
|
});
|
119
132
|
|
@@ -123,6 +136,12 @@ test('Can expand cv and show activation keys and hosts', async (done) => {
|
|
123
136
|
.get(cvIndexPath)
|
124
137
|
.query(true)
|
125
138
|
.reply(200, cvIndexData);
|
139
|
+
searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
|
140
|
+
autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
|
141
|
+
scopeBookmark = nockInstance
|
142
|
+
.get('/api/v2/bookmarks')
|
143
|
+
.query(true)
|
144
|
+
.reply(200, {});
|
126
145
|
|
127
146
|
const {
|
128
147
|
queryByLabelText,
|
@@ -152,18 +171,21 @@ test('Can expand cv and show activation keys and hosts', async (done) => {
|
|
152
171
|
});
|
153
172
|
|
154
173
|
assertNockRequest(autocompleteScope);
|
174
|
+
assertNockRequest(searchDelayScope);
|
175
|
+
assertNockRequest(autoSearchScope);
|
176
|
+
assertNockRequest(scopeBookmark);
|
155
177
|
assertNockRequest(scope, done); // Pass jest callback to confirm test is done
|
156
178
|
});
|
157
179
|
|
158
180
|
test('Can handle no Content Views being present', async (done) => {
|
159
|
-
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
160
|
-
|
161
181
|
const noResults = {
|
162
182
|
total: 0,
|
163
183
|
subtotal: 0,
|
164
184
|
page: 1,
|
165
185
|
per_page: 20,
|
166
186
|
results: [],
|
187
|
+
can_view: true,
|
188
|
+
can_create: true,
|
167
189
|
};
|
168
190
|
const scope = nockInstance
|
169
191
|
.get(cvIndexPath)
|
@@ -173,12 +195,10 @@ test('Can handle no Content Views being present', async (done) => {
|
|
173
195
|
|
174
196
|
expect(queryByText(firstCV.name)).toBeNull();
|
175
197
|
await patientlyWaitFor(() => expect(queryByText(/don't have any Content views/i)).toBeInTheDocument());
|
176
|
-
assertNockRequest(autocompleteScope);
|
177
198
|
assertNockRequest(scope, done);
|
178
199
|
});
|
179
200
|
|
180
201
|
test('Can handle errored response', async (done) => {
|
181
|
-
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
182
202
|
const scope = nockInstance
|
183
203
|
.get(cvIndexPath)
|
184
204
|
.query(true)
|
@@ -188,7 +208,6 @@ test('Can handle errored response', async (done) => {
|
|
188
208
|
|
189
209
|
expect(queryByText(firstCV.name)).toBeNull();
|
190
210
|
await patientlyWaitFor(() => expect(queryByText(/Something went wrong! Please check server logs!/i)).toBeInTheDocument());
|
191
|
-
assertNockRequest(autocompleteScope);
|
192
211
|
assertNockRequest(scope, done);
|
193
212
|
});
|
194
213
|
|
@@ -201,11 +220,20 @@ test('Can handle unpublished Content Views', async (done) => {
|
|
201
220
|
.get(cvIndexPath)
|
202
221
|
.query(true)
|
203
222
|
.reply(200, unpublishedCVData);
|
223
|
+
searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
|
224
|
+
autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
|
225
|
+
scopeBookmark = nockInstance
|
226
|
+
.get('/api/v2/bookmarks')
|
227
|
+
.query(true)
|
228
|
+
.reply(200, {});
|
204
229
|
|
205
230
|
const { getAllByText } = renderWithRedux(<ContentViewsPage />, renderOptions);
|
206
231
|
|
207
232
|
await patientlyWaitFor(() => expect(getAllByText(/not yet published/i).length).toBeGreaterThan(0));
|
208
233
|
assertNockRequest(autocompleteScope);
|
234
|
+
assertNockRequest(searchDelayScope);
|
235
|
+
assertNockRequest(autoSearchScope);
|
236
|
+
assertNockRequest(scopeBookmark);
|
209
237
|
assertNockRequest(scope, done);
|
210
238
|
});
|
211
239
|
|
@@ -215,6 +243,12 @@ test('Can handle pagination', async (done) => {
|
|
215
243
|
const cvIndexFirstPage = { ...cvIndexLarge, ...{ results: results.slice(0, 20) } };
|
216
244
|
const cvIndexSecondPage = { ...cvIndexLarge, page: 2, results: results.slice(20, 40) };
|
217
245
|
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
246
|
+
searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
|
247
|
+
autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
|
248
|
+
scopeBookmark = nockInstance
|
249
|
+
.get('/api/v2/bookmarks')
|
250
|
+
.query(true)
|
251
|
+
.reply(200, {});
|
218
252
|
|
219
253
|
// Match first page API request
|
220
254
|
const firstPageScope = nockInstance
|
@@ -249,6 +283,9 @@ test('Can handle pagination', async (done) => {
|
|
249
283
|
expect(queryByText(results[41].name)).not.toBeInTheDocument();
|
250
284
|
});
|
251
285
|
assertNockRequest(autocompleteScope);
|
286
|
+
assertNockRequest(autoSearchScope);
|
287
|
+
assertNockRequest(searchDelayScope);
|
288
|
+
assertNockRequest(scopeBookmark);
|
252
289
|
assertNockRequest(firstPageScope);
|
253
290
|
assertNockRequest(secondPageScope, done); // Only pass jest callback to the last API request
|
254
291
|
});
|
@@ -264,6 +301,13 @@ test('Can search for specific Content View', async (done) => {
|
|
264
301
|
|
265
302
|
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
266
303
|
const withSearchScope = mockAutocomplete(nockInstance, autocompleteUrl, matchQuery);
|
304
|
+
searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
|
305
|
+
autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
|
306
|
+
scopeBookmark = nockInstance
|
307
|
+
.get('/api/v2/bookmarks')
|
308
|
+
.query(true)
|
309
|
+
.reply(200, {});
|
310
|
+
|
267
311
|
const initialScope = nockInstance
|
268
312
|
.get(cvIndexPath)
|
269
313
|
.query(true)
|
@@ -291,6 +335,9 @@ test('Can search for specific Content View', async (done) => {
|
|
291
335
|
});
|
292
336
|
|
293
337
|
assertNockRequest(autocompleteScope);
|
338
|
+
assertNockRequest(searchDelayScope);
|
339
|
+
assertNockRequest(autoSearchScope);
|
340
|
+
assertNockRequest(scopeBookmark);
|
294
341
|
assertNockRequest(initialScope);
|
295
342
|
assertNockRequest(withSearchScope);
|
296
343
|
assertNockRequest(searchResultScope, done);
|
@@ -301,10 +348,23 @@ test('No results message is shown for empty search', async (done) => {
|
|
301
348
|
const query = `name = \"${cvname}\"`;
|
302
349
|
const matchQuery = actualParams => actualParams?.search?.includes(cvname);
|
303
350
|
const emptyResults = {
|
304
|
-
total: 0,
|
351
|
+
total: 0,
|
352
|
+
subtotal: 0,
|
353
|
+
page: 1,
|
354
|
+
per_page: 20,
|
355
|
+
search: query,
|
356
|
+
results: [],
|
357
|
+
can_view: true,
|
358
|
+
can_create: true,
|
305
359
|
};
|
306
360
|
|
307
361
|
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
362
|
+
searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 0);
|
363
|
+
autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing');
|
364
|
+
scopeBookmark = nockInstance
|
365
|
+
.get('/api/v2/bookmarks')
|
366
|
+
.query(true)
|
367
|
+
.reply(200, {});
|
308
368
|
const withSearchScope = mockAutocomplete(nockInstance, autocompleteUrl, matchQuery);
|
309
369
|
const initialScope = nockInstance
|
310
370
|
.get(cvIndexPath)
|
@@ -324,20 +384,22 @@ test('No results message is shown for empty search', async (done) => {
|
|
324
384
|
await patientlyWaitFor(() => expect(getByText(/No matching content views found/i)).toBeInTheDocument());
|
325
385
|
|
326
386
|
assertNockRequest(autocompleteScope);
|
387
|
+
assertNockRequest(searchDelayScope);
|
388
|
+
assertNockRequest(autoSearchScope);
|
389
|
+
assertNockRequest(scopeBookmark);
|
327
390
|
assertNockRequest(initialScope);
|
328
391
|
assertNockRequest(withSearchScope);
|
329
392
|
assertNockRequest(searchResultScope, done);
|
330
393
|
});
|
331
394
|
|
332
395
|
test('Displays Create Content View and opens modal with Form', async () => {
|
333
|
-
mockAutocomplete(nockInstance, autocompleteUrl);
|
334
|
-
|
335
396
|
const noResults = {
|
336
397
|
total: 0,
|
337
398
|
subtotal: 0,
|
338
399
|
page: 1,
|
339
400
|
per_page: 20,
|
340
401
|
can_create: true,
|
402
|
+
can_view: true,
|
341
403
|
results: [],
|
342
404
|
};
|
343
405
|
nockInstance
|
@@ -101,7 +101,7 @@ const CVBreadcrumb = () => {
|
|
101
101
|
filterDetails, filterDetailsStatus, breadcrumbItems, setBreadcrumbItems]);
|
102
102
|
|
103
103
|
return (
|
104
|
-
<Breadcrumb className="margin-bottom-24">
|
104
|
+
<Breadcrumb ouiaId="cv-breadcrumb" className="margin-bottom-24">
|
105
105
|
{
|
106
106
|
Object.keys(breadcrumbItems)?.sort()?.map(key => (
|
107
107
|
<BreadcrumbItem
|
@@ -58,6 +58,7 @@ const EnvironmentPaths = ({
|
|
58
58
|
className="env-path__labels-with-pointer"
|
59
59
|
key={`${env.id}${index}`}
|
60
60
|
id={`${env.id}${index}`}
|
61
|
+
ouiaId={`${env.id}${index}`}
|
61
62
|
label={<EnvironmentLabels environments={env} isDisabled={isDisabled} />}
|
62
63
|
aria-label={env.label}
|
63
64
|
onChange={checked => oncheckedChange(checked, env)}
|
@@ -4,7 +4,15 @@ import { TextContent, Text, TextVariants } from '@patternfly/react-core';
|
|
4
4
|
|
5
5
|
const InactiveText = props => (
|
6
6
|
<TextContent>
|
7
|
-
<Text
|
7
|
+
<Text
|
8
|
+
ouiaId="inactive-text"
|
9
|
+
component={TextVariants.small}
|
10
|
+
style={{
|
11
|
+
display: 'inline-flex', alignItems: 'center', margin: 0,
|
12
|
+
}}
|
13
|
+
{...props}
|
14
|
+
>{props.text}
|
15
|
+
</Text>
|
8
16
|
</TextContent>
|
9
17
|
);
|
10
18
|
|
@@ -35,6 +35,7 @@ const RelatedCompositeContentViewsModal = ({
|
|
35
35
|
</Button>
|
36
36
|
<Modal
|
37
37
|
title={__('Related composite content views')}
|
38
|
+
ouiaId="related-composite-cvs"
|
38
39
|
variant={ModalVariant.large}
|
39
40
|
isOpen={isOpen}
|
40
41
|
description={description()}
|
@@ -45,10 +46,11 @@ const RelatedCompositeContentViewsModal = ({
|
|
45
46
|
>
|
46
47
|
<TableComposable
|
47
48
|
aria-label={`${cvId}_table`}
|
49
|
+
ouiaId={`${cvId}_table`}
|
48
50
|
variant="compact"
|
49
51
|
>
|
50
52
|
<Thead>
|
51
|
-
<Tr>
|
53
|
+
<Tr ouiaId="table-header-row">
|
52
54
|
{columns.map((column, columnIndex) => (
|
53
55
|
<Th key={columnIndex}>{column}</Th>
|
54
56
|
))}
|
@@ -56,7 +58,7 @@ const RelatedCompositeContentViewsModal = ({
|
|
56
58
|
</Thead>
|
57
59
|
<Tbody>
|
58
60
|
{relatedCompositeCVs.map(cv => (
|
59
|
-
<Tr key={cv.id}>
|
61
|
+
<Tr key={cv.id} ouiaId={`row-${cv.id}`}>
|
60
62
|
<Td key={`${cv.id}_${cv.name}`} dataLabel={columns[cv.id]}>
|
61
63
|
<Link to={`${urlBuilder('content_views', '')}${cv.id}`}>{cv.name}</Link>
|
62
64
|
</Td>
|
@@ -50,6 +50,7 @@ const RelatedContentViewsModal = ({ cvName, cvId, relatedCVCount }) => {
|
|
50
50
|
<GridItem span={12}>
|
51
51
|
<Modal
|
52
52
|
title={__('Related content views')}
|
53
|
+
ouiaId="related-cvs"
|
53
54
|
variant={ModalVariant.medium}
|
54
55
|
isOpen={isOpen}
|
55
56
|
description={description()}
|
@@ -76,13 +77,13 @@ const RelatedContentViewsModal = ({ cvName, cvId, relatedCVCount }) => {
|
|
76
77
|
emptySearchBody={__('Try changing your search settings.')}
|
77
78
|
>
|
78
79
|
<Thead>
|
79
|
-
<Tr>
|
80
|
+
<Tr ouiaId="column-headers">
|
80
81
|
<Th key="name_col">{__('Name')}</Th>
|
81
82
|
</Tr>
|
82
83
|
</Thead>
|
83
84
|
<Tbody>
|
84
85
|
{results?.map(details => (
|
85
|
-
<Tr key={`${details.content_view.id}`}>
|
86
|
+
<Tr key={`${details.content_view.id}`} ouiaId={`${details.content_view.id}`}>
|
86
87
|
<Td>
|
87
88
|
<Link to={urlBuilder(`content_views/${details.content_view.id}`, '')}>{details.content_view.name}</Link>
|
88
89
|
</Td>
|
@@ -3,19 +3,19 @@ import { foremanUrl } from 'foremanReact/common/helpers';
|
|
3
3
|
import { get, post, put } from 'foremanReact/redux/API';
|
4
4
|
import { translate as __ } from 'foremanReact/common/I18n';
|
5
5
|
|
6
|
-
import {
|
6
|
+
import {
|
7
|
+
CHANGE_CONTENT_SOURCE_DATA,
|
8
|
+
CHANGE_CONTENT_SOURCE_PROXY,
|
7
9
|
CHANGE_CONTENT_SOURCE,
|
8
|
-
CHANGE_CONTENT_SOURCE_VIEWS
|
10
|
+
CHANGE_CONTENT_SOURCE_VIEWS,
|
11
|
+
} from './constants';
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
params: { host_ids: getHostIds() },
|
17
|
-
errorToast: () => __('Something went wrong while getting the data. See the logs for more information'),
|
18
|
-
});
|
13
|
+
export const getFormData = (hostIds, search) => (post({
|
14
|
+
key: CHANGE_CONTENT_SOURCE_DATA,
|
15
|
+
url: foremanUrl('/change_host_content_source/data'),
|
16
|
+
params: { host_ids: hostIds, search },
|
17
|
+
errorToast: () => __('Something went wrong while getting the data. See the logs for more information'),
|
18
|
+
}));
|
19
19
|
|
20
20
|
export const changeContentSource = (environmentId, contentViewId, contentSourceId, hostIds) =>
|
21
21
|
put({
|
@@ -31,6 +31,13 @@ export const changeContentSource = (environmentId, contentViewId, contentSourceI
|
|
31
31
|
errorToast: () => __('Something went wrong while updating the content source. See the logs for more information'),
|
32
32
|
});
|
33
33
|
|
34
|
+
export const getProxy = id =>
|
35
|
+
get({
|
36
|
+
key: CHANGE_CONTENT_SOURCE_PROXY,
|
37
|
+
url: foremanUrl(`/katello/api/capsules/${id}`),
|
38
|
+
errorToast: () => __('Something went wrong while loading the Smart Proxy. See the logs for more information'),
|
39
|
+
});
|
40
|
+
|
34
41
|
export const getContentViews = environmentId =>
|
35
42
|
get({
|
36
43
|
key: CHANGE_CONTENT_SOURCE_VIEWS,
|
@@ -22,13 +22,20 @@ const ContentSourceForm = ({
|
|
22
22
|
contentSources,
|
23
23
|
handleContentSource,
|
24
24
|
contentSourceId,
|
25
|
-
|
25
|
+
contentHosts,
|
26
26
|
isLoading,
|
27
27
|
}) => {
|
28
28
|
const formIsValid = () => (!!environmentId &&
|
29
29
|
!!contentViewId &&
|
30
30
|
!!contentSourceId &&
|
31
|
-
|
31
|
+
contentHosts.length !== 0);
|
32
|
+
|
33
|
+
const contentSourcesIsDisabled = (isLoading || contentSources.length === 0 ||
|
34
|
+
contentHosts.length === 0);
|
35
|
+
const environmentIsDisabled = (isLoading || environments.length === 0 ||
|
36
|
+
contentSourceId === '');
|
37
|
+
const viewIsDisabled = (isLoading || contentViews.length === 0 ||
|
38
|
+
contentSourceId === '' || environmentId === '');
|
32
39
|
|
33
40
|
return (
|
34
41
|
<Form
|
@@ -36,10 +43,10 @@ const ContentSourceForm = ({
|
|
36
43
|
className="content_source_form"
|
37
44
|
isHorizontal
|
38
45
|
>
|
39
|
-
<Grid hasGutter>
|
40
|
-
<FormField label={__('
|
41
|
-
<FormField label={__('
|
42
|
-
<FormField label={__('Content
|
46
|
+
<Grid hasGutter className="margin-top-16">
|
47
|
+
<FormField label={__('Content source')} id="change_cs_content_source" value={contentSourceId} items={contentSources} onChange={handleContentSource} isDisabled={contentSourcesIsDisabled} />
|
48
|
+
<FormField label={__('Environment')} id="change_cs_environment" value={environmentId} items={environments} onChange={handleEnvironment} isDisabled={environmentIsDisabled} />
|
49
|
+
<FormField label={__('Content view')} id="change_cs_content_view" value={contentViewId} items={contentViews} onChange={handleContentView} isDisabled={viewIsDisabled} />
|
43
50
|
|
44
51
|
<GridItem>
|
45
52
|
<ActionGroup>
|
@@ -69,7 +76,7 @@ ContentSourceForm.propTypes = {
|
|
69
76
|
contentSources: PropTypes.arrayOf(PropTypes.shape({})),
|
70
77
|
handleContentSource: PropTypes.func.isRequired,
|
71
78
|
contentSourceId: PropTypes.string,
|
72
|
-
|
79
|
+
contentHosts: PropTypes.arrayOf(PropTypes.shape({})),
|
73
80
|
isLoading: PropTypes.bool,
|
74
81
|
};
|
75
82
|
|
@@ -80,7 +87,7 @@ ContentSourceForm.defaultProps = {
|
|
80
87
|
contentViewId: '',
|
81
88
|
contentSources: [],
|
82
89
|
contentSourceId: '',
|
83
|
-
|
90
|
+
contentHosts: [],
|
84
91
|
isLoading: false,
|
85
92
|
};
|
86
93
|
|
@@ -9,7 +9,7 @@ import { translate as __ } from 'foremanReact/common/I18n';
|
|
9
9
|
import PropTypes from 'prop-types';
|
10
10
|
|
11
11
|
const FormField = ({
|
12
|
-
label, id, value, items, onChange,
|
12
|
+
label, id, value, items, onChange, isDisabled,
|
13
13
|
}) => (
|
14
14
|
<GridItem span={7}>
|
15
15
|
<FormGroup label={label} fieldId={id} isRequired>
|
@@ -17,7 +17,7 @@ const FormField = ({
|
|
17
17
|
value={value}
|
18
18
|
onChange={v => onChange(v)}
|
19
19
|
className="without_select2"
|
20
|
-
isDisabled={
|
20
|
+
isDisabled={isDisabled}
|
21
21
|
id={`${id}_select`}
|
22
22
|
isRequired
|
23
23
|
>
|
@@ -36,8 +36,7 @@ FormField.propTypes = {
|
|
36
36
|
value: PropTypes.string.isRequired,
|
37
37
|
items: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
|
38
38
|
onChange: PropTypes.func.isRequired,
|
39
|
-
|
40
|
-
contentHostsCount: PropTypes.number.isRequired,
|
39
|
+
isDisabled: PropTypes.bool.isRequired,
|
41
40
|
};
|
42
41
|
|
43
42
|
export default FormField;
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import React, { useState } from 'react';
|
2
|
+
import {
|
3
|
+
GridItem,
|
4
|
+
Label,
|
5
|
+
} from '@patternfly/react-core';
|
6
|
+
|
7
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
8
|
+
import PropTypes from 'prop-types';
|
9
|
+
|
10
|
+
import HostsModal from './HostsModal';
|
11
|
+
|
12
|
+
const Hosts = ({
|
13
|
+
contentHosts, hostsWithoutContent,
|
14
|
+
}) => {
|
15
|
+
const [modalHosts, setModalHosts] = useState(false);
|
16
|
+
const [modalIgnored, setModalIgnored] = useState(false);
|
17
|
+
|
18
|
+
const titleHosts = __('Hosts to update');
|
19
|
+
const titleIgnored = __('Ignored hosts');
|
20
|
+
|
21
|
+
return (
|
22
|
+
<>
|
23
|
+
<GridItem span={7}>
|
24
|
+
{hostsWithoutContent.length > 0 &&
|
25
|
+
<p>
|
26
|
+
{ __('Some hosts are not registered as content hosts and will be ignored.') }
|
27
|
+
</p>
|
28
|
+
}
|
29
|
+
{contentHosts.length > 0 && (<Label color="green" href="#" onClick={() => setModalHosts(true)}>{titleHosts}: {contentHosts.length}</Label>)}
|
30
|
+
{' '}
|
31
|
+
{hostsWithoutContent.length > 0 && (<Label color="orange" href="#" onClick={() => setModalIgnored(true)}>{titleIgnored}: {hostsWithoutContent.length}</Label>)}
|
32
|
+
|
33
|
+
<HostsModal
|
34
|
+
hosts={contentHosts}
|
35
|
+
isOpen={modalHosts}
|
36
|
+
setModalOpenState={setModalHosts}
|
37
|
+
modalTitle={titleHosts}
|
38
|
+
/>
|
39
|
+
<HostsModal
|
40
|
+
hosts={hostsWithoutContent}
|
41
|
+
isOpen={modalIgnored}
|
42
|
+
setModalOpenState={setModalIgnored}
|
43
|
+
modalTitle={titleIgnored}
|
44
|
+
/>
|
45
|
+
</GridItem>
|
46
|
+
</>
|
47
|
+
);
|
48
|
+
};
|
49
|
+
|
50
|
+
Hosts.propTypes = {
|
51
|
+
contentHosts: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
|
52
|
+
hostsWithoutContent: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
|
53
|
+
};
|
54
|
+
|
55
|
+
export default Hosts;
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import React, { useState } from 'react';
|
2
|
+
import {
|
3
|
+
Button,
|
4
|
+
Modal,
|
5
|
+
ModalVariant,
|
6
|
+
List, ListItem,
|
7
|
+
SearchInput,
|
8
|
+
} from '@patternfly/react-core';
|
9
|
+
|
10
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
11
|
+
import { foremanUrl } from 'foremanReact/common/helpers';
|
12
|
+
|
13
|
+
import PropTypes from 'prop-types';
|
14
|
+
|
15
|
+
const HostsModal = ({
|
16
|
+
hosts, isOpen, setModalOpenState, modalTitle,
|
17
|
+
}) => {
|
18
|
+
const [search, setSearch] = useState('');
|
19
|
+
|
20
|
+
return (
|
21
|
+
<Modal
|
22
|
+
variant={ModalVariant.small}
|
23
|
+
title={modalTitle}
|
24
|
+
position="top"
|
25
|
+
isOpen={isOpen}
|
26
|
+
onClose={() => setModalOpenState(false)}
|
27
|
+
>
|
28
|
+
<SearchInput
|
29
|
+
placeholder={__('Search')}
|
30
|
+
value={search}
|
31
|
+
onChange={v => setSearch(v)}
|
32
|
+
onClear={() => setSearch('')}
|
33
|
+
/>
|
34
|
+
<List isPlain isBordered className="margin-top-16">
|
35
|
+
{(search ? hosts.filter(h => (`${h.name}`).includes(search)) : hosts).map(h => (
|
36
|
+
<ListItem key={h.id}>
|
37
|
+
<Button
|
38
|
+
component="a"
|
39
|
+
href={foremanUrl(`/new/hosts/${h.name}`)}
|
40
|
+
variant="link"
|
41
|
+
target="_blank"
|
42
|
+
isInline
|
43
|
+
>
|
44
|
+
{h.name}
|
45
|
+
</Button>
|
46
|
+
</ListItem>
|
47
|
+
))}
|
48
|
+
</List>
|
49
|
+
</Modal>);
|
50
|
+
};
|
51
|
+
|
52
|
+
HostsModal.propTypes = {
|
53
|
+
hosts: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
|
54
|
+
isOpen: PropTypes.bool.isRequired,
|
55
|
+
setModalOpenState: PropTypes.func.isRequired,
|
56
|
+
modalTitle: PropTypes.string.isRequired,
|
57
|
+
};
|
58
|
+
|
59
|
+
export default HostsModal;
|
@@ -1,3 +1,4 @@
|
|
1
1
|
export const CHANGE_CONTENT_SOURCE_DATA = 'CHANGE_CONTENT_SOURCE_DATA';
|
2
|
+
export const CHANGE_CONTENT_SOURCE_PROXY = 'CHANGE_CONTENT_SOURCE_PROXY';
|
2
3
|
export const CHANGE_CONTENT_SOURCE = 'CHANGE_CONTENT_SOURCE';
|
3
4
|
export const CHANGE_CONTENT_SOURCE_VIEWS = 'CHANGE_CONTENT_SOURCE_VIEWS';
|