katello 3.16.2 → 3.17.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/stylesheets/katello/katello.scss +3 -7
- data/app/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +1 -1
- data/app/controllers/katello/api/v2/activation_keys_controller.rb +8 -0
- data/app/controllers/katello/api/v2/host_subscriptions_controller.rb +10 -4
- data/app/controllers/katello/api/v2/host_tracer_controller.rb +33 -8
- data/app/controllers/katello/api/v2/hosts_bulk_actions_controller.rb +11 -11
- data/app/controllers/katello/api/v2/products_bulk_actions_controller.rb +0 -15
- data/app/controllers/katello/api/v2/repositories_controller.rb +5 -11
- data/app/controllers/katello/api/v2/upstream_subscriptions_controller.rb +16 -0
- data/app/controllers/katello/concerns/api/v2/bulk_hosts_extensions.rb +4 -4
- data/app/controllers/katello/concerns/api/v2/hostgroups_controller_extensions.rb +1 -1
- data/app/controllers/katello/concerns/hosts_controller_extensions.rb +5 -11
- data/app/helpers/katello/concerns/dashboard_helper_extensions.rb +10 -0
- data/app/helpers/katello/hosts_and_hostgroups_helper.rb +6 -7
- data/app/lib/actions/candlepin/product/content_add.rb +2 -1
- data/app/lib/actions/candlepin/product/content_update_enablement.rb +18 -0
- data/app/lib/actions/katello/applicability/hosts/bulk_generate.rb +2 -6
- data/app/lib/actions/katello/capsule_content/refresh_repos.rb +1 -1
- data/app/lib/actions/katello/capsule_content/sync.rb +1 -1
- data/app/lib/actions/katello/capsule_content/sync_capsule.rb +3 -17
- data/app/lib/actions/katello/content_view_version/incremental_update.rb +2 -3
- data/app/lib/actions/katello/organization/simple_content_access/disable.rb +17 -0
- data/app/lib/actions/katello/organization/simple_content_access/enable.rb +17 -0
- data/app/lib/actions/katello/organization/simple_content_access/toggle.rb +36 -0
- data/app/lib/actions/katello/orphan_cleanup/remove_orphans.rb +13 -0
- data/app/lib/actions/katello/product/content_create.rb +3 -3
- data/app/lib/actions/katello/product/destroy.rb +4 -25
- data/app/lib/actions/katello/repository/content_update.rb +41 -0
- data/app/lib/actions/katello/repository/destroy.rb +1 -5
- data/app/lib/actions/katello/repository/export.rb +1 -1
- data/app/lib/actions/katello/repository/multi_clone_contents.rb +15 -13
- data/app/lib/actions/katello/repository/sync.rb +25 -35
- data/app/lib/actions/katello/repository/update.rb +19 -30
- data/app/lib/actions/katello/repository/update_cv_repo_cert_guard.rb +17 -0
- data/app/lib/actions/pulp/orchestration/repository/smart_proxy_sync.rb +1 -0
- data/app/lib/actions/pulp/orchestration/repository/sync.rb +1 -2
- data/app/lib/actions/pulp/repository/sync.rb +1 -2
- data/app/lib/actions/pulp3/abstract_async_task.rb +0 -1
- data/app/lib/actions/pulp3/capsule_content/sync.rb +1 -3
- data/app/lib/actions/pulp3/content_view/delete_repository_references.rb +1 -1
- data/app/lib/actions/pulp3/orchestration/repository/copy_all_units.rb +2 -1
- data/app/lib/actions/pulp3/orchestration/repository/sync.rb +1 -3
- data/app/lib/actions/pulp3/repository/copy_content.rb +1 -0
- data/app/lib/actions/pulp3/repository/delete.rb +1 -1
- data/app/lib/actions/pulp3/repository/multi_copy_content.rb +1 -1
- data/app/lib/actions/pulp3/repository/save_version.rb +16 -20
- data/app/lib/actions/pulp3/repository/sync.rb +1 -1
- data/app/lib/actions/pulp3/repository/update_cv_repository_cert_guard.rb +2 -6
- data/app/lib/actions/pulp3/repository/upload_file.rb +1 -1
- data/app/lib/katello/resources/candlepin/product.rb +11 -0
- data/app/lib/katello/resources/cdn.rb +2 -3
- data/app/lib/katello/util/cdn_var_substitutor.rb +7 -9
- data/app/lib/katello/validators/hostgroup_kickstart_repository_validator.rb +11 -11
- data/app/models/katello/activation_key.rb +1 -1
- data/app/models/katello/concerns/content_facet_host_extensions.rb +7 -0
- data/app/models/katello/concerns/host_managed_extensions.rb +39 -0
- data/app/models/katello/concerns/hostgroup_extensions.rb +46 -24
- data/app/models/katello/concerns/smart_proxy_extensions.rb +5 -19
- data/app/models/katello/concerns/widget_extensions.rb +23 -0
- data/app/models/katello/content_view.rb +9 -1
- data/app/models/katello/content_view_package_filter.rb +1 -1
- data/app/models/katello/content_view_version.rb +7 -0
- data/app/models/katello/erratum.rb +13 -0
- data/app/models/katello/erratum_cve.rb +8 -0
- data/app/models/katello/glue/pulp/repo.rb +1 -1
- data/app/models/katello/host/content_facet.rb +18 -1
- data/app/models/katello/host_collection.rb +6 -0
- data/app/models/katello/hostgroup/content_facet.rb +18 -0
- data/app/models/katello/installed_package.rb +8 -0
- data/app/models/katello/kt_environment.rb +9 -1
- data/app/models/katello/model.rb +16 -0
- data/app/models/katello/pool.rb +17 -0
- data/app/models/katello/product.rb +6 -0
- data/app/models/katello/purpose_addons_status.rb +1 -0
- data/app/models/katello/purpose_role_status.rb +1 -0
- data/app/models/katello/purpose_sla_status.rb +1 -0
- data/app/models/katello/purpose_usage_status.rb +1 -0
- data/app/models/katello/repository.rb +3 -6
- data/app/models/katello/root_repository.rb +24 -16
- data/app/models/katello/subscription_status.rb +1 -1
- data/app/models/katello/trace_status.rb +1 -1
- data/app/models/setting/content.rb +6 -2
- data/app/services/cert/certs.rb +2 -10
- data/app/services/katello/event_daemon.rb +7 -8
- data/app/services/katello/host_status_manager.rb +13 -0
- data/app/services/katello/pulp3/migration.rb +1 -1
- data/app/services/katello/pulp3/repository/yum.rb +6 -72
- data/app/services/katello/pulp3/repository.rb +11 -10
- data/app/services/katello/pulp3/smart_proxy_mirror_repository.rb +1 -1
- data/app/services/katello/pulp3/task.rb +3 -3
- data/app/services/katello/pulp3/task_group.rb +0 -6
- data/app/services/katello/smart_proxy_helper.rb +16 -13
- data/app/views/foreman/smart_proxies/_content_sync.html.erb +1 -1
- data/app/views/katello/api/v2/repositories/base.json.rabl +1 -1
- data/config/routes/api/rhsm.rb +0 -1
- data/config/routes/api/v2.rb +8 -2
- data/config/routes/overrides.rb +0 -4
- data/db/migrate/20141222151001_add_host_content_view_environment.rb +1 -1
- data/db/migrate/20180904122343_create_hostgroup_content_facet.katello.rb +16 -0
- data/db/migrate/20200514092553_move_katello_fields_from_hostgroups.katello.rb +53 -0
- data/db/migrate/20200610112009_remove_audits_of_root_repo_with_content_id.rb +9 -0
- data/db/migrate/20200701150946_add_auto_enabled_to_root_repository.rb +5 -0
- data/db/seeds.d/75-job_templates.rb +2 -2
- data/engines/bastion/app/assets/javascripts/bastion/components/nutupane.factory.js +3 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-associations.controller.js +5 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/activation-key-details.controller.js +4 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-add-subscriptions.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-associations-content-hosts.html +2 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-details.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-errata-modal.controller.js +4 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-packages-modal.controller.js +4 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-subscriptions-modal.controller.js +1 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-traces-modal.controller.js +4 -3
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-environment-modal.html +7 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-errata-modal.html +1 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-packages-modal.html +1 -0
- 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/content-hosts.routes.js +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details-info.controller.js +7 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/content-host-details.controller.js +4 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-add-subscriptions.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-details.html +1 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-info.html +14 -6
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/details/views/content-host-subscriptions-list.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/views/content-hosts.html +6 -6
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/host-collection-details.controller.js +5 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/host-collections/details/views/host-collection-info.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host-bulk-action.factory.js +1 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/hosts/host-traces-resolve.factory.js +18 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +45 -4
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de.po +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/es.po +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/fr.po +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/it.po +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ja.po +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ko.po +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pt_BR.po +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ru.po +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_CN.po +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_TW.po +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/product-bulk-action.factory.js +0 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +0 -6
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +1 -7
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +11 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +16 -4
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repository.factory.js +0 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/products.controller.js +0 -15
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/views/products.html +0 -6
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/subscriptions/views/content-access-mode-banner.html +1 -1
- data/lib/katello/engine.rb +6 -5
- data/lib/katello/permission_creator.rb +3 -3
- data/lib/katello/permissions/host_permissions.rb +0 -1
- data/lib/katello/plugin.rb +20 -16
- data/lib/katello/tasks/pulp3_post_migration_check.rake +1 -2
- data/lib/katello/tasks/reimport.rake +1 -1
- data/lib/katello/tasks/reports.rake +0 -12
- data/lib/katello/tasks/test.rake +15 -0
- data/lib/katello/version.rb +1 -1
- data/locale/action_names.rb +48 -48
- data/locale/bn/katello.po +137 -14
- data/locale/cs/katello.po +137 -14
- data/locale/de/katello.po +138 -15
- data/locale/en/katello.po +137 -14
- data/locale/es/katello.po +138 -15
- data/locale/fr/katello.po +138 -15
- data/locale/gu/katello.po +137 -14
- data/locale/hi/katello.po +137 -14
- data/locale/it/katello.po +138 -15
- data/locale/ja/katello.po +138 -15
- data/locale/katello.pot +969 -769
- data/locale/kn/katello.po +137 -14
- data/locale/ko/katello.po +138 -15
- data/locale/mr/katello.po +137 -14
- data/locale/or/katello.po +137 -14
- data/locale/pa/katello.po +137 -14
- data/locale/pt/katello.po +137 -14
- data/locale/pt_BR/katello.po +138 -15
- data/locale/ru/katello.po +138 -15
- data/locale/ta/katello.po +137 -14
- data/locale/te/katello.po +137 -14
- data/locale/zh_CN/katello.po +138 -15
- data/locale/zh_TW/katello.po +138 -15
- data/package.json +8 -25
- data/webpack/__mocks__/foremanReact/Root/Context/ForemanContext.js +3 -0
- data/webpack/components/ActionableDetail.js +63 -0
- data/webpack/components/Content/ContentTable.js +2 -2
- data/webpack/components/Content/Details/ContentDetailRepositoryTableSchema.js +1 -1
- data/webpack/components/Content/Details/ContentDetails.js +1 -1
- data/webpack/components/Content/__tests__/ContentTable.test.js +2 -2
- data/webpack/components/Content/__tests__/__snapshots__/ContentPage.test.js.snap +1 -1
- data/webpack/components/EditableSwitch.js +30 -0
- data/webpack/components/EditableTextInput/EditableTextInput.js +120 -0
- data/webpack/components/EditableTextInput/__tests__/editableTextInput.test.js +52 -0
- data/webpack/components/EditableTextInput/editableTextInput.scss +14 -0
- data/webpack/components/EditableTextInput/index.js +3 -0
- data/webpack/{scenes/ContentViews/components → components}/Loading.js +8 -5
- data/webpack/{move_to_pf → components}/LoadingState/LoadingState.js +0 -0
- data/webpack/{move_to_pf → components}/LoadingState/LoadingState.scss +0 -0
- data/webpack/{move_to_pf → components}/LoadingState/LoadingState.test.js +0 -0
- data/webpack/{move_to_pf → components}/LoadingState/__snapshots__/LoadingState.test.js.snap +0 -0
- data/webpack/{move_to_pf → components}/LoadingState/index.js +0 -0
- data/webpack/components/MultiSelect/index.js +1 -1
- data/webpack/{move_to_pf → components}/OptionTooltip/OptionTooltip.scss +0 -0
- data/webpack/{move_to_pf → components}/OptionTooltip/__tests__/OptionTooltip.test.js +0 -0
- data/webpack/{move_to_pf → components}/OptionTooltip/__tests__/__snapshots__/OptionTooltip.test.js.snap +0 -0
- data/webpack/{move_to_pf → components}/OptionTooltip/index.js +0 -0
- data/webpack/components/Search/Search.js +124 -0
- data/webpack/components/Search/Search.test.js +2 -1
- data/webpack/components/Search/__snapshots__/Search.test.js.snap +2 -0
- data/webpack/components/Search/__tests__/search.test.js +124 -0
- data/webpack/components/Search/index.js +11 -87
- data/webpack/{move_to_pf → components}/Select/Select.js +0 -0
- data/webpack/components/SelectOrg/SetOrganization.js +2 -2
- data/webpack/components/TabWrapper/TabWrapper.js +26 -0
- data/webpack/components/TabWrapper/index.js +3 -0
- data/webpack/components/TabbedView/TabbedView.js +38 -0
- data/webpack/components/TabbedView/TabbedView.scss +3 -0
- data/webpack/components/TabbedView/index.js +3 -0
- data/webpack/components/Table/EmptyStateMessage.js +61 -0
- data/webpack/{scenes/ContentViews/Table/TableWrapper.js → components/Table/MainTable.js} +23 -12
- data/webpack/components/Table/TableWrapper.js +94 -0
- data/webpack/{move_to_pf → components}/TooltipButton/TooltipButton.js +0 -0
- data/webpack/{move_to_pf → components}/TooltipButton/TooltipButton.scss +0 -0
- data/webpack/{move_to_pf → components}/TooltipButton/TooltipButton.test.js +0 -0
- data/webpack/{move_to_pf → components}/TooltipButton/__snapshots__/TooltipButton.test.js.snap +0 -0
- data/webpack/{move_to_pf → components}/TooltipButton/index.js +0 -0
- data/webpack/components/TypeAhead/TypeAhead.js +109 -0
- data/webpack/{move_to_pf → components}/TypeAhead/TypeAhead.scss +0 -0
- data/webpack/components/TypeAhead/helpers/commonPropTypes.js +35 -0
- data/webpack/components/TypeAhead/helpers/helpers.js +32 -0
- data/webpack/components/TypeAhead/index.js +3 -0
- data/webpack/{move_to_pf/TypeAhead → components/TypeAhead/pf3Search}/TypeAheadInput.js +3 -6
- data/webpack/{move_to_pf/TypeAhead → components/TypeAhead/pf3Search}/TypeAheadItems.js +3 -7
- data/webpack/components/TypeAhead/pf3Search/TypeAheadSearch.js +52 -0
- data/webpack/components/TypeAhead/pf4Search/TypeAheadInput.js +44 -0
- data/webpack/components/TypeAhead/pf4Search/TypeAheadInput.scss +11 -0
- data/webpack/components/TypeAhead/pf4Search/TypeAheadItems.js +57 -0
- data/webpack/components/TypeAhead/pf4Search/TypeAheadSearch.js +66 -0
- data/webpack/components/TypeAhead/pf4Search/TypeAheadSearch.scss +5 -0
- data/webpack/components/extensions/about/__tests__/SystemStatuses.test.js +1 -1
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/CollapseSubscriptionGroupButton.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/CollapseSubscriptionGroupButton.test.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/Table.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/Table.test.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/TableBody.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/TableBody.test.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/TableBodyMessage.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/TableBodyMessage.test.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/TableFixtures.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/TableSelectionCell.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/TableSelectionCell.test.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/TableSelectionHeaderCell.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/TableSelectionHeaderCell.test.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/__snapshots__/CollapseSubscriptionGroupButton.test.js.snap +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/__snapshots__/Table.test.js.snap +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/__snapshots__/TableBody.test.js.snap +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/__snapshots__/TableBodyMessage.test.js.snap +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/__snapshots__/TableSelectionCell.test.js.snap +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/__snapshots__/TableSelectionHeaderCell.test.js.snap +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/components/index.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/formatters/EntitlementsInlineEditFormatter.js +1 -1
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/formatters/__tests__/EntitlementsInlineEditFormatter.test.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/formatters/__tests__/__snapshots__/EntitlementsInlineEditFormatter.test.js.snap +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/formatters/cellFormatter.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/formatters/collapseableAndSelectionCellFormatter.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/formatters/ellipsisCellFormatter.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/formatters/headerFormatter.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/formatters/index.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/formatters/selectionCellFormatter.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/formatters/selectionHeaderCellFormatter.js +0 -0
- data/webpack/{move_to_foreman/components/common/table → components/pf3Table}/index.js +0 -0
- data/webpack/{move_to_pf → components}/react-bootstrap-select/index.js +0 -0
- data/webpack/containers/Application/config.js +5 -0
- data/webpack/containers/Application/overrides.scss +5 -0
- data/webpack/global_test_setup.js +3 -1
- data/webpack/redux/OrganizationProducts/OrganizationProductsActions.js +1 -1
- data/webpack/redux/OrganizationProducts/__tests__/OrganizationProductsActions.test.js +2 -2
- data/webpack/redux/actions/RedHatRepositories/enabled.js +1 -1
- data/webpack/redux/actions/RedHatRepositories/helpers.js +1 -1
- data/webpack/redux/actions/RedHatRepositories/repositorySetRepositories.js +1 -1
- data/webpack/redux/reducers/index.js +2 -0
- data/webpack/scenes/AnsibleCollections/AnsibleCollectionsActions.js +1 -1
- data/webpack/scenes/AnsibleCollections/AnsibleCollectionsTableSchema.js +1 -1
- data/webpack/scenes/AnsibleCollections/Details/AnsibleCollectionDetailsActions.js +1 -1
- data/webpack/scenes/AnsibleCollections/Details/__tests__/AnsibleCollectionDetailsActions.test.js +2 -2
- data/webpack/scenes/AnsibleCollections/__tests__/AnsibleCollectionsTable.test.js +1 -1
- data/webpack/scenes/ContentViews/ContentViewSelectors.js +1 -2
- data/webpack/scenes/ContentViews/ContentViewsActions.js +4 -4
- data/webpack/scenes/ContentViews/ContentViewsConstants.js +4 -1
- data/webpack/scenes/ContentViews/ContentViewsPage.js +12 -6
- data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +44 -0
- data/webpack/scenes/ContentViews/Details/ContentViewDetailReducer.js +23 -0
- data/webpack/scenes/ContentViews/{details → Details}/ContentViewDetailSelectors.js +3 -0
- data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +70 -0
- data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +116 -0
- data/webpack/scenes/ContentViews/{details → Details}/DetailsContainer.js +8 -4
- data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetail.test.js +101 -0
- data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetails.fixtures.json +106 -0
- data/webpack/scenes/ContentViews/Details/contentViewInfo.scss +8 -0
- data/webpack/scenes/ContentViews/Details/index.js +7 -0
- data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +51 -36
- data/webpack/scenes/ContentViews/Table/tableDataGenerator.js +47 -44
- data/webpack/scenes/ContentViews/__tests__/basicContentViews.fixtures.js +31 -0
- data/webpack/scenes/ContentViews/__tests__/contentViewList.fixtures.json +2 -1
- data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +173 -23
- data/webpack/scenes/ContentViews/components/ContentViewIcon.js +26 -0
- data/webpack/scenes/ContentViews/components/{contentViewName.scss → contentViewIcon.scss} +0 -0
- data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetailsActions.js +1 -1
- data/webpack/scenes/ModuleStreams/Details/Profiles/TableSchema.js +1 -1
- data/webpack/scenes/ModuleStreams/Details/__tests__/ModuleStreamDetailsActions.test.js +2 -2
- data/webpack/scenes/ModuleStreams/ModuleStreamsActions.js +1 -1
- data/webpack/scenes/ModuleStreams/ModuleStreamsTableSchema.js +1 -1
- data/webpack/scenes/ModuleStreams/__tests__/ModuleStreamsTable.test.js +1 -1
- data/webpack/scenes/Organizations/OrganizationSelectors.js +14 -0
- data/webpack/scenes/Products/ProductActions.js +1 -1
- data/webpack/scenes/RedHatRepositories/RedHatRepositoriesPage.js +1 -1
- data/webpack/scenes/Settings/SettingsConstants.js +3 -0
- data/webpack/scenes/Settings/SettingsReducer.js +33 -0
- data/webpack/scenes/Settings/SettingsSelectors.js +4 -0
- data/webpack/scenes/Settings/index.js +2 -1
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailActions.js +1 -1
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.js +1 -1
- data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +59 -73
- data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.scss +15 -0
- data/webpack/scenes/Subscriptions/Manifest/ManifestActions.js +43 -1
- data/webpack/scenes/Subscriptions/Manifest/ManifestConstants.js +8 -0
- data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryTableSchema.js +1 -1
- data/webpack/scenes/Subscriptions/Manifest/SimpleContentAccess.js +78 -0
- data/webpack/scenes/Subscriptions/Manifest/__tests__/ManageManifestModal.test.js +2 -0
- data/webpack/scenes/Subscriptions/Manifest/__tests__/ManifestActions.test.js +56 -1
- data/webpack/scenes/Subscriptions/Manifest/__tests__/SimpleContentAccess.test.js +114 -0
- data/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap +6 -6
- data/webpack/scenes/Subscriptions/Manifest/__tests__/manifest.fixtures.js +36 -0
- data/webpack/scenes/Subscriptions/Manifest/index.js +3 -1
- data/webpack/scenes/Subscriptions/SubscriptionActions.js +1 -1
- data/webpack/scenes/Subscriptions/SubscriptionConstants.js +4 -0
- data/webpack/scenes/Subscriptions/SubscriptionHelpers.js +0 -3
- data/webpack/scenes/Subscriptions/SubscriptionReducer.js +38 -11
- data/webpack/scenes/Subscriptions/SubscriptionsPage.js +30 -18
- data/webpack/scenes/Subscriptions/SubscriptionsSelectors.js +0 -3
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsActions.js +1 -1
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +2 -2
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsTableSchema.js +1 -1
- data/webpack/scenes/Subscriptions/__tests__/SubscriptionHelpers.test.js +0 -11
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsActions.test.js.snap +2 -2
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +4 -4
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsReducer.test.js.snap +26 -1
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionTypeFormatter.js +2 -2
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTable.js +27 -21
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableHelpers.js +6 -2
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableSchema.js +2 -2
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionTypeFormatter.test.js.snap +3 -3
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/components/Table.js +1 -1
- data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.js +28 -3
- data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/__snapshots__/SubscriptionsToolbar.test.js.snap +5 -10
- data/webpack/scenes/Subscriptions/index.js +6 -2
- data/webpack/test-utils/nockWrapper.js +39 -5
- data/webpack/test-utils/react-testing-lib-wrapper.js +35 -9
- data/webpack/{move_to_foreman/common → utils}/helpers.js +12 -8
- data/webpack/utils/useEventListener.js +37 -0
- metadata +143 -83
- data/app/lib/actions/katello/repository/verify_checksum.rb +0 -28
- data/app/lib/actions/pulp3/orchestration/repository/trigger_update_repo_cert_guard.rb +0 -22
- data/app/lib/actions/pulp3/repository/presenters/repair_presenter.rb +0 -85
- data/app/lib/actions/pulp3/repository/repair.rb +0 -29
- data/app/services/katello/host_trace_manager.rb +0 -38
- data/vendor/assets/stylesheets/katello/jquery.loadmask.css.scss +0 -40
- data/vendor/assets/stylesheets/katello/ui.spinner.css.scss +0 -3
- data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalActions.js +0 -2
- data/webpack/__mocks__/foremanReact/components/ForemanModal/ForemanModalSelectors.js +0 -2
- data/webpack/__mocks__/foremanReact/components/ForemanModal/index.js +0 -4
- data/webpack/__mocks__/foremanReact/components/Settings/SettingsActions.js +0 -4
- data/webpack/__mocks__/foremanReact/components/Settings/SettingsConstants.js +0 -2
- data/webpack/move_to_pf/TypeAhead/TypeAhead.js +0 -138
- data/webpack/move_to_pf/TypeAhead/helpers.js +0 -5
- data/webpack/scenes/ContentViews/components/ContentViewName.js +0 -33
- data/webpack/scenes/ContentViews/components/EmptyStateMessage.js +0 -43
- data/webpack/scenes/ContentViews/details/ContentViewDetailActions.js +0 -12
- data/webpack/scenes/ContentViews/expansions/RepositoriesExpansion.js +0 -12
@@ -1,39 +1,40 @@
|
|
1
1
|
import React from 'react';
|
2
|
-
import { compoundExpand } from '@patternfly/react-table';
|
3
|
-
import {
|
2
|
+
import { compoundExpand, fitContent } from '@patternfly/react-table';
|
3
|
+
import {
|
4
|
+
ScreenIcon,
|
5
|
+
ContainerNodeIcon,
|
6
|
+
} from '@patternfly/react-icons';
|
7
|
+
import { Link } from 'react-router-dom';
|
8
|
+
import { urlBuilder } from 'foremanReact/common/urlHelpers';
|
4
9
|
import { translate as __ } from 'foremanReact/common/I18n';
|
5
10
|
|
6
11
|
import IconWithCount from '../components/IconWithCount';
|
7
12
|
import DetailsExpansion from '../expansions/DetailsExpansion';
|
8
|
-
import RepositoriesExpansion from '../expansions/RepositoriesExpansion';
|
9
13
|
import EnvironmentsExpansion from '../expansions/EnvironmentsExpansion';
|
10
14
|
import VersionsExpansion from '../expansions/VersionsExpansion';
|
11
|
-
import
|
12
|
-
import DetailsContainer from '../
|
15
|
+
import ContentViewIcon from '../components/ContentViewIcon';
|
16
|
+
import DetailsContainer from '../Details/DetailsContainer';
|
13
17
|
|
14
18
|
export const buildColumns = () => [
|
19
|
+
{ title: __('Type'), transforms: [fitContent] },
|
15
20
|
__('Name'), __('Last published'), __('Details'),
|
16
21
|
{ title: __('Environments'), cellTransforms: [compoundExpand] },
|
17
|
-
{ title: __('Repositories'), cellTransforms: [compoundExpand] },
|
18
22
|
{ title: __('Versions'), cellTransforms: [compoundExpand] },
|
19
23
|
];
|
20
24
|
|
21
25
|
const buildRow = (contentView, openColumn) => {
|
22
26
|
const {
|
23
|
-
id, composite, name, environments,
|
27
|
+
id, composite, name, environments, versions, last_published: lastPublished,
|
24
28
|
} = contentView;
|
25
29
|
const row = [
|
26
|
-
{ title: <
|
30
|
+
{ title: <ContentViewIcon composite={composite ? true : undefined} /> },
|
31
|
+
{ title: <Link to={urlBuilder('labs/content_views', '', id)}>{name}</Link> },
|
27
32
|
lastPublished || 'Not yet published',
|
28
33
|
{ title: __('Details'), props: { isOpen: false, ariaControls: `cv-details-expansion-${id}` } },
|
29
34
|
{
|
30
35
|
title: <IconWithCount Icon={ScreenIcon} count={environments.length} title={`environments-icon-${id}`} />,
|
31
36
|
props: { isOpen: false, ariaControls: `cv-environments-expansion-${id}` },
|
32
37
|
},
|
33
|
-
{
|
34
|
-
title: <IconWithCount Icon={RepositoryIcon} count={repositories.length} title={`repositories-icon-${id}`} />,
|
35
|
-
props: { isOpen: false, ariaControls: `cv-repositories-expansion-${id}` },
|
36
|
-
},
|
37
38
|
{
|
38
39
|
title: <IconWithCount Icon={ContainerNodeIcon} count={versions.length} title={`versions-icon-${id}`} />,
|
39
40
|
props: { isOpen: false, ariaControls: `cv-versions-expansion-${id}` },
|
@@ -48,14 +49,15 @@ const buildDetailDropdowns = (id, rowIndex, openColumn) => {
|
|
48
49
|
const cvId = { cvId: id };
|
49
50
|
const expansionProps = { ...cvId, className: 'pf-m-no-padding' };
|
50
51
|
const containerProps = column => ({ ...cvId, isOpen: openColumn === column });
|
52
|
+
const offsetColumn = 3; // index of first expandable column
|
51
53
|
|
52
54
|
let detailDropdowns = [
|
53
55
|
{
|
54
|
-
compoundParent:
|
56
|
+
compoundParent: offsetColumn,
|
55
57
|
cells: [
|
56
58
|
{
|
57
59
|
title: (
|
58
|
-
<DetailsContainer {...containerProps(
|
60
|
+
<DetailsContainer {...containerProps(offsetColumn + 1)}>
|
59
61
|
<DetailsExpansion {...expansionProps} />
|
60
62
|
</DetailsContainer>),
|
61
63
|
props: { colSpan: 6 },
|
@@ -63,11 +65,11 @@ const buildDetailDropdowns = (id, rowIndex, openColumn) => {
|
|
63
65
|
],
|
64
66
|
},
|
65
67
|
{
|
66
|
-
compoundParent:
|
68
|
+
compoundParent: offsetColumn + 1,
|
67
69
|
cells: [
|
68
70
|
{
|
69
71
|
title: (
|
70
|
-
<DetailsContainer {...containerProps(
|
72
|
+
<DetailsContainer {...containerProps(offsetColumn + 2)}>
|
71
73
|
<EnvironmentsExpansion {...expansionProps} />
|
72
74
|
</DetailsContainer>),
|
73
75
|
props: { colSpan: 6 },
|
@@ -75,23 +77,11 @@ const buildDetailDropdowns = (id, rowIndex, openColumn) => {
|
|
75
77
|
],
|
76
78
|
},
|
77
79
|
{
|
78
|
-
compoundParent:
|
79
|
-
cells: [
|
80
|
-
{
|
81
|
-
title: (
|
82
|
-
<DetailsContainer {...containerProps(5)}>
|
83
|
-
<RepositoriesExpansion {...expansionProps} />
|
84
|
-
</DetailsContainer>),
|
85
|
-
props: { colSpan: 6 },
|
86
|
-
},
|
87
|
-
],
|
88
|
-
},
|
89
|
-
{
|
90
|
-
compoundParent: 5,
|
80
|
+
compoundParent: offsetColumn + 2,
|
91
81
|
cells: [
|
92
82
|
{
|
93
83
|
title: (
|
94
|
-
<DetailsContainer {...containerProps(
|
84
|
+
<DetailsContainer {...containerProps(offsetColumn + 3)}>
|
95
85
|
<VersionsExpansion {...expansionProps} />
|
96
86
|
</DetailsContainer>),
|
97
87
|
props: { colSpan: 6 },
|
@@ -100,26 +90,22 @@ const buildDetailDropdowns = (id, rowIndex, openColumn) => {
|
|
100
90
|
},
|
101
91
|
];
|
102
92
|
|
103
|
-
|
104
|
-
const rowOffset = detailDropdowns.length + 1;
|
105
|
-
detailDropdowns = detailDropdowns.map(detail => ({ ...detail, parent: rowIndex * rowOffset }));
|
93
|
+
detailDropdowns = detailDropdowns.map(detail => ({ ...detail, parent: rowIndex }));
|
106
94
|
|
107
95
|
return detailDropdowns;
|
108
96
|
};
|
109
97
|
|
110
|
-
const
|
111
|
-
const
|
112
|
-
const contentViews = results || [];
|
113
|
-
const columns = buildColumns();
|
98
|
+
const buildRowsAndMapping = (contentViews, newRowMapping) => {
|
99
|
+
const updatedRowMap = { ...newRowMapping };
|
114
100
|
const rows = [];
|
115
101
|
|
116
|
-
contentViews.forEach((contentView
|
102
|
+
contentViews.forEach((contentView) => {
|
117
103
|
const { id } = contentView;
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
}
|
122
|
-
const openColumn =
|
104
|
+
const rowIndex = rows.length;
|
105
|
+
const needsUpdate = !Object.keys(updatedRowMap).find(i => updatedRowMap[i].id === id) ||
|
106
|
+
!Object.keys(updatedRowMap[rowIndex] || {}).includes('expandedColumn');
|
107
|
+
if (needsUpdate) updatedRowMap[rowIndex] = { expandedColumn: null, id };
|
108
|
+
const openColumn = updatedRowMap[rowIndex].expandedColumn;
|
123
109
|
const cells = buildRow(contentView, openColumn);
|
124
110
|
const isOpen = !!openColumn;
|
125
111
|
|
@@ -127,7 +113,24 @@ const tableDataGenerator = (results, rowMapping) => {
|
|
127
113
|
rows.push(...buildDetailDropdowns(id, rowIndex, openColumn));
|
128
114
|
});
|
129
115
|
|
130
|
-
return {
|
116
|
+
return { rows, updatedRowMap };
|
117
|
+
};
|
118
|
+
|
119
|
+
const tableDataGenerator = (results, rowMapping) => {
|
120
|
+
// If a search was performed or perPage has changed, we can clear mapping
|
121
|
+
const prevRowMapping = (results.length === Object.keys(rowMapping).length) ? rowMapping : {};
|
122
|
+
const newRowMapping = {};
|
123
|
+
const contentViews = results || [];
|
124
|
+
const columns = buildColumns();
|
125
|
+
const contentViewIds = contentViews.map(cv => cv.id);
|
126
|
+
|
127
|
+
// Only keep the relevant rows to keep the table status check accurate
|
128
|
+
Object.entries(prevRowMapping).forEach(([rowId, value]) => {
|
129
|
+
if (contentViewIds.includes(value.id)) newRowMapping[rowId] = value;
|
130
|
+
});
|
131
|
+
const { updatedRowMap, rows } = buildRowsAndMapping(contentViews, newRowMapping);
|
132
|
+
|
133
|
+
return { updatedRowMap, rows, columns };
|
131
134
|
};
|
132
135
|
|
133
136
|
export default tableDataGenerator;
|
@@ -0,0 +1,31 @@
|
|
1
|
+
const buildContentView = id => ({
|
2
|
+
id,
|
3
|
+
composite: 'false',
|
4
|
+
name: `contentView${id}`,
|
5
|
+
environments: [],
|
6
|
+
repositories: [],
|
7
|
+
versions: [],
|
8
|
+
last_published: 'Not Yet Published',
|
9
|
+
});
|
10
|
+
|
11
|
+
const createBasicCVs = (amount) => {
|
12
|
+
const response = {
|
13
|
+
total: 100,
|
14
|
+
subtotal: 100,
|
15
|
+
page: 1,
|
16
|
+
per_page: 20,
|
17
|
+
error: null,
|
18
|
+
search: null,
|
19
|
+
sort: {
|
20
|
+
by: 'name',
|
21
|
+
order: 'asc',
|
22
|
+
},
|
23
|
+
results: [],
|
24
|
+
};
|
25
|
+
|
26
|
+
[...Array(amount).keys()].forEach((_, i) => response.results.push(buildContentView(i)));
|
27
|
+
|
28
|
+
return response;
|
29
|
+
};
|
30
|
+
|
31
|
+
export default createBasicCVs;
|
@@ -1,24 +1,41 @@
|
|
1
|
+
/* eslint-disable no-useless-escape */
|
1
2
|
import React from 'react';
|
2
|
-
import {
|
3
|
+
import { renderWithRedux, patientlyWaitFor, fireEvent } from 'react-testing-lib-wrapper';
|
3
4
|
|
4
5
|
import CONTENT_VIEWS_KEY from '../ContentViewsConstants';
|
6
|
+
import { createContentViewsParams } from '../ContentViewsActions';
|
5
7
|
import ContentViewsPage from '../../ContentViews';
|
6
8
|
import api from '../../../services/api';
|
7
|
-
import
|
8
|
-
|
9
|
+
import nock, {
|
10
|
+
nockInstance, assertNockRequest, mockAutocomplete, mockSetting,
|
11
|
+
} from '../../../test-utils/nockWrapper';
|
12
|
+
import createBasicCVs from './basicContentViews.fixtures';
|
9
13
|
|
10
14
|
const cvIndexData = require('./contentViewList.fixtures.json');
|
11
15
|
|
12
16
|
const cvIndexPath = api.getApiUrl('/content_views');
|
13
|
-
const
|
17
|
+
const autocompleteUrl = '/content_views/auto_complete_search';
|
18
|
+
const renderOptions = { apiNamespace: CONTENT_VIEWS_KEY };
|
14
19
|
|
15
20
|
let firstCV;
|
21
|
+
let searchDelayScope;
|
22
|
+
let autoSearchScope;
|
16
23
|
beforeEach(() => {
|
17
24
|
const { results } = cvIndexData;
|
18
25
|
[firstCV] = results;
|
26
|
+
searchDelayScope = mockSetting(nockInstance, 'autosearch_delay', 500);
|
27
|
+
autoSearchScope = mockSetting(nockInstance, 'autosearch_while_typing', true);
|
28
|
+
});
|
29
|
+
|
30
|
+
afterEach(() => {
|
31
|
+
nock.cleanAll();
|
32
|
+
assertNockRequest(searchDelayScope);
|
33
|
+
assertNockRequest(autoSearchScope);
|
19
34
|
});
|
20
35
|
|
21
|
-
test('Can call API for CVs and show on screen on page load', async () => {
|
36
|
+
test('Can call API for CVs and show on screen on page load', async (done) => {
|
37
|
+
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
38
|
+
|
22
39
|
// Mocking API call with nock so it returns the fixture data
|
23
40
|
const scope = nockInstance
|
24
41
|
.get(cvIndexPath)
|
@@ -27,19 +44,22 @@ test('Can call API for CVs and show on screen on page load', async () => {
|
|
27
44
|
|
28
45
|
// Using a custom rendering function that sets up both redux and react-router.
|
29
46
|
// This allows us to use the component as it is normally used
|
30
|
-
const { queryByText } =
|
47
|
+
const { queryByText } = renderWithRedux(<ContentViewsPage />, renderOptions);
|
31
48
|
|
32
49
|
// query* functions will return the element or null if it cannot be found
|
33
50
|
// get* functions will return the element or throw an error if it cannot be found
|
34
51
|
// Assert that the CV is not showing yet by searching by name and the query returning null
|
35
52
|
expect(queryByText(firstCV.name)).toBeNull();
|
36
53
|
// Assert that the CV name is now showing on the screen, but wait for it to appear.
|
37
|
-
await
|
54
|
+
await patientlyWaitFor(() => expect(queryByText(firstCV.name)).toBeTruthy());
|
38
55
|
// Assert request was made and completed, see helper function
|
39
|
-
assertNockRequest(
|
56
|
+
assertNockRequest(autocompleteScope);
|
57
|
+
assertNockRequest(scope, done); // Pass jest callback to confirm test is done
|
40
58
|
});
|
41
59
|
|
42
|
-
test('Can handle no Content Views being present', async () => {
|
60
|
+
test('Can handle no Content Views being present', async (done) => {
|
61
|
+
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
62
|
+
|
43
63
|
const noResults = {
|
44
64
|
total: 0,
|
45
65
|
subtotal: 0,
|
@@ -51,49 +71,179 @@ test('Can handle no Content Views being present', async () => {
|
|
51
71
|
.get(cvIndexPath)
|
52
72
|
.query(true)
|
53
73
|
.reply(200, noResults);
|
54
|
-
const { queryByText } =
|
74
|
+
const { queryByText } = renderWithRedux(<ContentViewsPage />, renderOptions);
|
55
75
|
|
56
76
|
expect(queryByText(firstCV.name)).toBeNull();
|
57
|
-
await
|
58
|
-
assertNockRequest(
|
77
|
+
await patientlyWaitFor(() => expect(queryByText(/don't have any Content Views/i)).toBeTruthy());
|
78
|
+
assertNockRequest(autocompleteScope);
|
79
|
+
assertNockRequest(scope, done);
|
59
80
|
});
|
60
81
|
|
61
|
-
test('Can handle errored response', async () => {
|
82
|
+
test('Can handle errored response', async (done) => {
|
83
|
+
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
62
84
|
const scope = nockInstance
|
63
85
|
.get(cvIndexPath)
|
64
86
|
.query(true)
|
65
87
|
.reply(500);
|
66
|
-
|
88
|
+
|
89
|
+
const { queryByText } = renderWithRedux(<ContentViewsPage />, renderOptions);
|
67
90
|
|
68
91
|
expect(queryByText(firstCV.name)).toBeNull();
|
69
|
-
await
|
70
|
-
assertNockRequest(
|
92
|
+
await patientlyWaitFor(() => expect(queryByText(/unable to connect/i)).toBeTruthy());
|
93
|
+
assertNockRequest(autocompleteScope);
|
94
|
+
assertNockRequest(scope, done);
|
71
95
|
});
|
72
96
|
|
73
|
-
test('Can handle loading state while request is being made', () => {
|
97
|
+
test('Can handle loading state while request is being made', async (done) => {
|
98
|
+
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
74
99
|
const scope = nockInstance
|
75
100
|
.get(cvIndexPath)
|
76
101
|
.delay(2000) // Delay the response so we can check loading state properly
|
77
102
|
.query(true)
|
78
103
|
.reply(200);
|
79
104
|
|
80
|
-
const { queryByText } =
|
105
|
+
const { queryByText } = renderWithRedux(<ContentViewsPage />, renderOptions);
|
81
106
|
|
82
107
|
expect(queryByText('Loading')).toBeTruthy();
|
83
|
-
|
108
|
+
assertNockRequest(autocompleteScope);
|
109
|
+
assertNockRequest(scope, done);
|
84
110
|
});
|
85
111
|
|
86
|
-
test('Can handle unpublished Content Views', async () => {
|
112
|
+
test('Can handle unpublished Content Views', async (done) => {
|
87
113
|
const { results } = cvIndexData;
|
88
114
|
const unpublishedCVs = results.map(cv => ({ ...cv, last_published: null }));
|
89
115
|
const unpublishedCVData = { ...cvIndexData, results: unpublishedCVs };
|
116
|
+
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
90
117
|
const scope = nockInstance
|
91
118
|
.get(cvIndexPath)
|
92
119
|
.query(true)
|
93
120
|
.reply(200, unpublishedCVData);
|
94
121
|
|
95
|
-
const { getAllByText } =
|
122
|
+
const { getAllByText } = renderWithRedux(<ContentViewsPage />, renderOptions);
|
123
|
+
|
124
|
+
await patientlyWaitFor(() => expect(getAllByText(/not yet published/i).length).toBeGreaterThan(0));
|
125
|
+
assertNockRequest(autocompleteScope);
|
126
|
+
assertNockRequest(scope, done);
|
127
|
+
});
|
128
|
+
|
129
|
+
test('Can handle pagination', async (done) => {
|
130
|
+
const cvIndexLarge = createBasicCVs(100);
|
131
|
+
const { results } = cvIndexLarge;
|
132
|
+
const cvIndexFirstPage = { ...cvIndexLarge, ...{ results: results.slice(0, 20) } };
|
133
|
+
const cvIndexSecondPage = { ...cvIndexLarge, page: 2, results: results.slice(20, 40) };
|
134
|
+
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
135
|
+
|
136
|
+
// Match first page API request
|
137
|
+
const firstPageScope = nockInstance
|
138
|
+
.get(cvIndexPath)
|
139
|
+
.query(createContentViewsParams())
|
140
|
+
.reply(200, cvIndexFirstPage);
|
141
|
+
|
142
|
+
// Match second page API request
|
143
|
+
const secondPageScope = nockInstance
|
144
|
+
.get(cvIndexPath)
|
145
|
+
// Using a custom query params matcher because parameters can be strings
|
146
|
+
.query(actualQueryObject => parseInt(actualQueryObject.page, 10) === 2)
|
147
|
+
.reply(200, cvIndexSecondPage);
|
148
|
+
|
149
|
+
const { queryByText, getByLabelText } = renderWithRedux(<ContentViewsPage />, renderOptions);
|
150
|
+
|
151
|
+
// Wait for first paginated page to load and assert only the first page of results are present
|
152
|
+
await patientlyWaitFor(() => {
|
153
|
+
expect(queryByText(results[0].name)).toBeInTheDocument();
|
154
|
+
expect(queryByText(results[19].name)).toBeInTheDocument();
|
155
|
+
expect(queryByText(results[21].name)).not.toBeInTheDocument();
|
156
|
+
});
|
157
|
+
|
158
|
+
// Label comes from patternfly, if this test fails, check if patternfly updated the label.
|
159
|
+
expect(getByLabelText('Go to next page')).toBeTruthy();
|
160
|
+
getByLabelText('Go to next page').click();
|
161
|
+
|
162
|
+
// Wait for second paginated page to load and assert only the second page of results are present
|
163
|
+
await patientlyWaitFor(() => {
|
164
|
+
expect(queryByText(results[20].name)).toBeInTheDocument();
|
165
|
+
expect(queryByText(results[39].name)).toBeInTheDocument();
|
166
|
+
expect(queryByText(results[41].name)).not.toBeInTheDocument();
|
167
|
+
});
|
168
|
+
|
169
|
+
assertNockRequest(autocompleteScope);
|
170
|
+
assertNockRequest(firstPageScope);
|
171
|
+
assertNockRequest(secondPageScope, done); // Only pass jest callback to the last API request
|
172
|
+
});
|
173
|
+
|
174
|
+
test('Can search for specific Content View', async (done) => {
|
175
|
+
const cvname = 'composite one';
|
176
|
+
const { results } = cvIndexData;
|
177
|
+
const matchQuery = actualParams => actualParams?.search?.includes(cvname);
|
178
|
+
const searchResults = {
|
179
|
+
...cvIndexData,
|
180
|
+
...{ total: 1, subtotal: 1, results: results.slice(-1) },
|
181
|
+
};
|
182
|
+
|
183
|
+
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
184
|
+
const withSearchScope = mockAutocomplete(nockInstance, autocompleteUrl, matchQuery);
|
185
|
+
const initialScope = nockInstance
|
186
|
+
.get(cvIndexPath)
|
187
|
+
.query(true)
|
188
|
+
.reply(200, cvIndexData);
|
189
|
+
const searchResultScope = nockInstance
|
190
|
+
.get(cvIndexPath)
|
191
|
+
.query(matchQuery)
|
192
|
+
.reply(200, searchResults);
|
193
|
+
|
194
|
+
const {
|
195
|
+
getByLabelText,
|
196
|
+
getByText,
|
197
|
+
queryByText,
|
198
|
+
} = renderWithRedux(<ContentViewsPage />, renderOptions);
|
199
|
+
|
200
|
+
await patientlyWaitFor(() => expect(getByText(firstCV.name)).toBeInTheDocument());
|
201
|
+
|
202
|
+
const searchInput = getByLabelText(/text input for search/i);
|
203
|
+
expect(searchInput).toBeInTheDocument();
|
204
|
+
fireEvent.change(searchInput, { target: { value: `name = \"${cvname}\"` } });
|
205
|
+
|
206
|
+
await patientlyWaitFor(() => {
|
207
|
+
expect(getByText(cvname)).toBeInTheDocument();
|
208
|
+
expect(queryByText(firstCV.name)).not.toBeInTheDocument();
|
209
|
+
});
|
210
|
+
|
211
|
+
assertNockRequest(autocompleteScope);
|
212
|
+
assertNockRequest(initialScope);
|
213
|
+
assertNockRequest(withSearchScope);
|
214
|
+
assertNockRequest(searchResultScope, done);
|
215
|
+
});
|
216
|
+
|
217
|
+
test('No results message is shown for empty search', async (done) => {
|
218
|
+
const cvname = 'notanactualname';
|
219
|
+
const query = `name = \"${cvname}\"`;
|
220
|
+
const matchQuery = actualParams => actualParams?.search?.includes(cvname);
|
221
|
+
const emptyResults = {
|
222
|
+
total: 1, subtotal: 1, page: 1, per_page: 20, search: query, results: [],
|
223
|
+
};
|
224
|
+
|
225
|
+
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
226
|
+
const withSearchScope = mockAutocomplete(nockInstance, autocompleteUrl, matchQuery);
|
227
|
+
const initialScope = nockInstance
|
228
|
+
.get(cvIndexPath)
|
229
|
+
.query(true)
|
230
|
+
.reply(200, cvIndexData);
|
231
|
+
const searchResultScope = nockInstance
|
232
|
+
.get(cvIndexPath)
|
233
|
+
.query(matchQuery)
|
234
|
+
.reply(200, emptyResults);
|
235
|
+
|
236
|
+
const { getByLabelText, getByText } = renderWithRedux(<ContentViewsPage />, renderOptions);
|
237
|
+
|
238
|
+
await patientlyWaitFor(() => expect(getByText(firstCV.name)).toBeInTheDocument());
|
239
|
+
|
240
|
+
fireEvent.change(getByLabelText(/text input for search/i), { target: { value: query } });
|
241
|
+
|
242
|
+
await patientlyWaitFor(() => expect(getByText(/No matching Content Views found/i)).toBeInTheDocument());
|
96
243
|
|
97
|
-
|
98
|
-
assertNockRequest(
|
244
|
+
assertNockRequest(autocompleteScope);
|
245
|
+
assertNockRequest(initialScope);
|
246
|
+
assertNockRequest(withSearchScope);
|
247
|
+
assertNockRequest(searchResultScope, done);
|
99
248
|
});
|
249
|
+
/* eslint-enable no-useless-escape */
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { CubesIcon, CubeIcon } from '@patternfly/react-icons';
|
4
|
+
import './contentViewIcon.scss';
|
5
|
+
|
6
|
+
const ContentViewIcon = ({ composite }) => {
|
7
|
+
const props = {
|
8
|
+
title: composite ? 'composite' : 'single',
|
9
|
+
className: 'svg-icon-centered',
|
10
|
+
};
|
11
|
+
return (
|
12
|
+
<div className="svg-centered-container">
|
13
|
+
{composite ? <CubesIcon {...props} /> : <CubeIcon {...props} />}
|
14
|
+
</div>
|
15
|
+
);
|
16
|
+
};
|
17
|
+
|
18
|
+
ContentViewIcon.propTypes = {
|
19
|
+
composite: PropTypes.bool,
|
20
|
+
};
|
21
|
+
|
22
|
+
ContentViewIcon.defaultProps = {
|
23
|
+
composite: false,
|
24
|
+
};
|
25
|
+
|
26
|
+
export default ContentViewIcon;
|
File without changes
|
@@ -4,7 +4,7 @@ import {
|
|
4
4
|
MODULE_STREAM_DETAILS_SUCCESS,
|
5
5
|
MODULE_STREAM_DETAILS_FAILURE,
|
6
6
|
} from './ModuleStreamDetailsConstants';
|
7
|
-
import { apiError } from '../../../
|
7
|
+
import { apiError } from '../../../utils/helpers.js';
|
8
8
|
|
9
9
|
export const loadModuleStreamDetails = moduleStreamId => async (dispatch) => {
|
10
10
|
dispatch({ type: MODULE_STREAM_DETAILS_REQUEST });
|
@@ -3,7 +3,7 @@ import { translate as __ } from 'foremanReact/common/I18n';
|
|
3
3
|
import {
|
4
4
|
headerFormatter,
|
5
5
|
cellFormatter,
|
6
|
-
} from '../../../../
|
6
|
+
} from '../../../../components/pf3Table';
|
7
7
|
import ProfileRpmsCellFormatter from './ProfileRpmsCellFormatter';
|
8
8
|
|
9
9
|
const TableSchema = [
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import { testActionSnapshotWithFixtures } from 'react-redux-test-utils';
|
2
2
|
import api from '../../../../services/api';
|
3
|
-
import { apiError } from '../../../../
|
3
|
+
import { apiError } from '../../../../utils/helpers';
|
4
4
|
import { loadModuleStreamDetails } from '../ModuleStreamDetailsActions';
|
5
5
|
import { details } from './moduleStreamDetails.fixtures';
|
6
6
|
|
7
7
|
jest.mock('../../../../services/api');
|
8
|
-
jest.mock('../../../../
|
8
|
+
jest.mock('../../../../utils/helpers');
|
9
9
|
|
10
10
|
const fixtures = {
|
11
11
|
'should load module stream details on success': () => async (dispatch) => {
|
@@ -6,7 +6,7 @@ import {
|
|
6
6
|
MODULE_STREAMS_SUCCESS,
|
7
7
|
MODULE_STREAMS_FAILURE,
|
8
8
|
} from './ModuleStreamsConstants';
|
9
|
-
import { apiError } from '../../
|
9
|
+
import { apiError } from '../../utils/helpers.js';
|
10
10
|
|
11
11
|
export const getModuleStreams = (extendedParams = {}) => async (dispatch) => {
|
12
12
|
dispatch({ type: MODULE_STREAMS_REQUEST });
|
@@ -3,7 +3,7 @@ import { shallow } from 'enzyme';
|
|
3
3
|
import toJson from 'enzyme-to-json';
|
4
4
|
import ContentTable from '../../../components/Content/ContentTable';
|
5
5
|
import TableSchema from '../../ModuleStreams/ModuleStreamsTableSchema';
|
6
|
-
import { Table } from '../../../
|
6
|
+
import { Table } from '../../../components/pf3Table';
|
7
7
|
|
8
8
|
jest.mock('foremanReact/components/Pagination/PaginationWrapper', () => (<div>Pagination Mock</div>));
|
9
9
|
|
@@ -1,4 +1,18 @@
|
|
1
1
|
export const selectOrganizationState = state => state.katello.organization;
|
2
2
|
|
3
|
+
export const selectManifestName = state =>
|
4
|
+
selectOrganizationState(state).owner_details?.upstreamConsumer?.name;
|
5
|
+
|
6
|
+
// for use in ManageManifestModal to replace getManifestName()
|
7
|
+
export const selectManifestHref = state =>
|
8
|
+
selectManifestName(state) && [
|
9
|
+
'https://',
|
10
|
+
selectOrganizationState(state).owner_details.upstreamConsumer.webUrl,
|
11
|
+
selectOrganizationState(state).owner_details.upstreamConsumer.uuid,
|
12
|
+
].join('/');
|
13
|
+
|
14
|
+
export const selectIsManifestImported = state =>
|
15
|
+
!!selectOrganizationState(state).owner_details?.upstreamConsumer?.webUrl;
|
16
|
+
|
3
17
|
export const selectSimpleContentAccessEnabled = state =>
|
4
18
|
selectOrganizationState(state).simple_content_access;
|
@@ -5,7 +5,7 @@ import {
|
|
5
5
|
PRODUCTS_SUCCESS,
|
6
6
|
PRODUCTS_FAILURE,
|
7
7
|
} from './ProductConstants';
|
8
|
-
import { apiError } from '../../
|
8
|
+
import { apiError } from '../../utils/helpers.js';
|
9
9
|
|
10
10
|
export const loadProducts = (params = {}) => async (dispatch) => {
|
11
11
|
dispatch({ type: PRODUCTS_REQUEST });
|
@@ -9,7 +9,7 @@ import { Grid, Row, Col } from 'react-bootstrap';
|
|
9
9
|
import { Button } from 'patternfly-react';
|
10
10
|
import { translate as __ } from 'foremanReact/common/I18n';
|
11
11
|
import PermissionDenied from 'foremanReact/components/PermissionDenied';
|
12
|
-
import { LoadingState } from '../../
|
12
|
+
import { LoadingState } from '../../components/LoadingState';
|
13
13
|
import { createEnabledRepoParams } from '../../redux/actions/RedHatRepositories/enabled';
|
14
14
|
import SearchBar from './components/SearchBar';
|
15
15
|
import RecommendedRepositorySetsToggler from './components/RecommendedRepositorySetsToggler';
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import Immutable from 'seamless-immutable';
|
2
|
+
import { GET_SETTING_SUCCESS } from 'foremanReact/components/Settings/SettingsConstants';
|
3
|
+
import {
|
4
|
+
AUTOSEARCH_DELAY,
|
5
|
+
AUTOSEARCH_WHILE_TYPING,
|
6
|
+
CONTENT_DISCONNECTED,
|
7
|
+
} from './SettingsConstants';
|
8
|
+
|
9
|
+
export const initialSettingsState = Immutable({
|
10
|
+
autoSearchEnabled: true,
|
11
|
+
autoSearchDelay: 500,
|
12
|
+
});
|
13
|
+
|
14
|
+
export default (state = initialSettingsState, action) => {
|
15
|
+
switch (action.type) {
|
16
|
+
case GET_SETTING_SUCCESS: {
|
17
|
+
const { name, value } = action.response;
|
18
|
+
switch (name) {
|
19
|
+
case AUTOSEARCH_DELAY:
|
20
|
+
return state.set('autoSearchDelay', value);
|
21
|
+
case AUTOSEARCH_WHILE_TYPING:
|
22
|
+
return state.set('autoSearchEnabled', value);
|
23
|
+
case CONTENT_DISCONNECTED:
|
24
|
+
return state.set('disconnected', value);
|
25
|
+
default:
|
26
|
+
return state;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
default:
|
31
|
+
return state;
|
32
|
+
}
|
33
|
+
};
|