katello 4.4.0.2 → 4.4.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of katello might be problematic. Click here for more details.

Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/errata_controller.rb +3 -1
  3. data/app/controllers/katello/api/v2/module_streams_controller.rb +3 -1
  4. data/app/controllers/katello/api/v2/package_groups_controller.rb +3 -1
  5. data/app/lib/actions/pulp3/repository/refresh_distribution.rb +1 -4
  6. data/app/lib/actions/pulp3/repository/save_distribution_references.rb +0 -2
  7. data/app/services/katello/content_unit_indexer.rb +1 -2
  8. data/app/services/katello/pulp3/erratum.rb +1 -1
  9. data/app/services/katello/pulp3/repository.rb +29 -1
  10. data/app/views/foreman/smart_proxies/show.html.erb +2 -0
  11. data/app/views/katello/api/v2/module_streams/show.json.rabl +0 -7
  12. data/db/migrate/20211220185935_clean_duplicate_content_units.rb +11 -9
  13. data/db/migrate/20220303160220_remove_duplicate_errata.rb +37 -2
  14. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/mirroring-policy.service.js +1 -1
  15. data/lib/katello/version.rb +1 -1
  16. data/webpack/components/Table/TableHooks.js +5 -4
  17. data/webpack/components/Table/__test__/useBulkSelect.test.js +99 -0
  18. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +13 -1
  19. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +1 -1
  20. data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +30 -3
  21. data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySetsTab.test.js +40 -15
  22. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +2 -2
  23. data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +1 -1
  24. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +1 -1
  25. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +2 -2
  26. data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/contentViewComponents.test.js +4 -4
  27. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +1 -1
  28. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +4 -4
  29. data/webpack/scenes/ContentViews/components/ContentViewsCounter.js +1 -1
  30. data/webpack/scenes/ContentViews/expansions/DetailsExpansion.js +2 -2
  31. data/webpack/scenes/ContentViews/expansions/RelatedContentViewComponentsModal.js +2 -2
  32. data/webpack/scenes/ContentViews/expansions/__tests__/contentViewComponentsModal.test.js +1 -1
  33. data/webpack/scenes/ModuleStreams/Details/ModuleDetailsSchema.js +1 -10
  34. data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetails.js +13 -14
  35. data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetails.test.js.snap +17 -100
  36. metadata +10 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9e2cbec78c4d297f09f1517b095e566c055bd14e2b3d4a534a5f904f8e9d43bc
4
- data.tar.gz: 5f96a7ce828a6ac081883643f8f79d55088ded4a5a06d86c4bfc69fababc315e
3
+ metadata.gz: 5ba77185c8a7b69f5804f90eca22f14863b4eaf37311fbbfcdd30e95bff824cf
4
+ data.tar.gz: 024c9250e18577f8897698c4af3d21e432c3986a6b84599876412a715fe2bbc5
5
5
  SHA512:
6
- metadata.gz: c109e2ed4481c10d8bc475b706aa00498f3cfce65fb2f9ec6cf589be8da2a47344561b31d45a5721aaab9743ccdbf751ec665663b858c26eb433803db59bbc6c
7
- data.tar.gz: 87d9b9ced044f3b34df8045a1ca1a02ca5ba695e4048999290fc0594f21186065c63036b93d4b1beef09162ddf9bb60c06dbd7cde7057df8a456a5701b8e9e3d
6
+ metadata.gz: 00ba2a8b933f5069920529d0780c48c290a157ff62123a0f530332497c5c34e5901d20eb7b4b832a2f7fb1ba3ed6a7dd591b3131e1f20e5b1f75335d67d487a0
7
+ data.tar.gz: 31d37614299b5877a287ef408d3f3a37b46f8b2c9111860ce438c60e69b7fbab11c3e7531e433d0d54eea7f18e73f25a4d117b3364315dd3103102df082f788d
@@ -35,7 +35,9 @@ module Katello
35
35
  end
36
36
 
37
37
  def all_for_content_view_filter(filter, _collection)
38
- Erratum.joins(:repositories).merge(filter.applicable_repos)
38
+ available_ids = Erratum.joins(:repositories).merge(filter.applicable_repos)&.pluck(:errata_id) || []
39
+ added_ids = filter&.erratum_rules&.pluck(:errata_id) || []
40
+ Erratum.where(errata_id: available_ids + added_ids)
39
41
  end
40
42
 
41
43
  def custom_index_relation(collection)
@@ -36,7 +36,9 @@ module Katello
36
36
  end
37
37
 
38
38
  def all_for_content_view_filter(filter, _collection)
39
- ModuleStream.joins(:repositories).merge(filter.applicable_repos)
39
+ available_ids = ModuleStream.joins(:repositories).merge(filter.applicable_repos)&.pluck(:id) || []
40
+ added_ids = filter&.module_stream_rules&.pluck(:module_stream_id) || []
41
+ ModuleStream.where(id: available_ids + added_ids)
40
42
  end
41
43
 
42
44
  def available_for_content_view_filter(filter, _collection)
@@ -67,7 +67,9 @@ module Katello
67
67
  end
68
68
 
69
69
  def all_for_content_view_filter(filter, _collection)
70
- PackageGroup.joins(:repositories).merge(filter.applicable_repos)
70
+ available_ids = PackageGroup.joins(:repositories).merge(filter.applicable_repos)&.pluck(:pulp_id) || []
71
+ added_ids = filter&.package_group_rules&.pluck(:uuid) || []
72
+ PackageGroup.where(pulp_id: available_ids + added_ids)
71
73
  end
72
74
 
73
75
  def default_sort
@@ -3,7 +3,6 @@ module Actions
3
3
  module Repository
4
4
  class RefreshDistribution < Pulp3::AbstractAsyncTask
5
5
  include Helpers::Presenter
6
- middleware.use Actions::Middleware::ExecuteIfContentsChanged
7
6
 
8
7
  def plan(repository, smart_proxy, options = {})
9
8
  smart_proxy = SmartProxy.unscoped.find_by(id: smart_proxy) #support bulk actions
@@ -16,11 +15,9 @@ module Actions
16
15
  :repository_id => repository.id,
17
16
  :smart_proxy_id => smart_proxy.id
18
17
  }
19
- refresh_options[:contents_changed] if options.key?(:contents_changed)
20
18
  action = plan_self(refresh_options)
21
19
 
22
- plan_action(SaveDistributionReferences, repository, smart_proxy,
23
- action.output, :contents_changed => options[:contents_changed])
20
+ plan_action(SaveDistributionReferences, repository, smart_proxy, action.output)
24
21
  end
25
22
  end
26
23
 
@@ -2,8 +2,6 @@ module Actions
2
2
  module Pulp3
3
3
  module Repository
4
4
  class SaveDistributionReferences < Pulp3::Abstract
5
- middleware.use Actions::Middleware::ExecuteIfContentsChanged
6
-
7
5
  def plan(repository, smart_proxy, tasks, options = {})
8
6
  plan_self(repository_id: repository.id, smart_proxy_id: smart_proxy.id, tasks: tasks, contents_changed: options[:contents_changed])
9
7
  end
@@ -22,7 +22,6 @@ module Katello
22
22
  end
23
23
 
24
24
  def import_all(filtered_indexing = false)
25
- additive = filtered_indexing || (@repository&.mirroring_policy == 'additive')
26
25
  association_tracker = RepoAssociationTracker.new(@content_type, @service_class, @repository)
27
26
  units_from_pulp.each do |units|
28
27
  units.each do |unit|
@@ -52,7 +51,7 @@ module Katello
52
51
  end
53
52
 
54
53
  if @model_class.many_repository_associations && @repository
55
- sync_repository_associations(association_tracker, additive: additive)
54
+ sync_repository_associations(association_tracker, additive: filtered_indexing)
56
55
  end
57
56
  end
58
57
 
@@ -119,7 +119,7 @@ module Katello
119
119
  date.to_i.to_s == date ? epoch_to_date(date) : date
120
120
  end
121
121
 
122
- def epoch_to_date(epoch)
122
+ def self.epoch_to_date(epoch)
123
123
  Time.at(epoch.to_i).to_s
124
124
  end
125
125
  end
@@ -285,11 +285,17 @@ module Katello
285
285
  return update_distribution
286
286
  end
287
287
 
288
- if dist_ref
288
+ if dist && dist_ref
289
+ # If the saved distribution reference is wrong, delete it and use the existing distribution
290
+ if dist.pulp_href != dist_ref.href
291
+ dist_ref.destroy
292
+ save_distribution_references([dist.pulp_href])
293
+ end
289
294
  return update_distribution
290
295
  end
291
296
 
292
297
  # Since we got this far, we need to create a new distribution
298
+ # Note: the distribution reference can't be saved yet because distribution creation is async
293
299
  begin
294
300
  create_distribution(relative_path)
295
301
  rescue api.client_module::ApiError => e
@@ -307,6 +313,9 @@ module Katello
307
313
 
308
314
  def create_distribution(path)
309
315
  distribution_data = api.distribution_class.new(secure_distribution_options(path))
316
+ unless ::Katello::RepositoryTypeManager.find(repo.content_type).pulp3_skip_publication
317
+ fail_missing_publication(distribution_data.publication)
318
+ end
310
319
  api.distributions_api.create(distribution_data)
311
320
  end
312
321
 
@@ -314,9 +323,16 @@ module Katello
314
323
  api.distributions_api.list(args).results
315
324
  end
316
325
 
326
+ def read_distribution(href = distribution_reference.href)
327
+ ignore_404_exception { api.distributions_api.read(href) }
328
+ end
329
+
317
330
  def update_distribution
318
331
  if distribution_reference
319
332
  options = secure_distribution_options(relative_path).except(:name)
333
+ unless ::Katello::RepositoryTypeManager.find(repo.content_type).pulp3_skip_publication
334
+ fail_missing_publication(options[:publication])
335
+ end
320
336
  distribution_reference.update(:content_guard_href => options[:content_guard])
321
337
  api.distributions_api.partial_update(distribution_reference.href, options)
322
338
  end
@@ -375,6 +391,12 @@ module Katello
375
391
  hrefs.each do |href|
376
392
  pulp3_distribution_data = api.get_distribution(href)
377
393
  path, content_guard_href = pulp3_distribution_data&.base_path, pulp3_distribution_data&.content_guard
394
+ if distribution_reference
395
+ found_distribution = read_distribution(distribution_reference.href)
396
+ unless found_distribution
397
+ distribution_reference.destroy
398
+ end
399
+ end
378
400
  unless distribution_reference
379
401
  # Ensure that duplicates won't be created in the case of a race condition
380
402
  DistributionReference.where(path: path, href: href, repository_id: repo.id, content_guard_href: content_guard_href).first_or_create!
@@ -529,6 +551,12 @@ module Katello
529
551
  return 0 if root.retain_package_versions_count.nil? || root.using_mirrored_content?
530
552
  root.retain_package_versions_count.to_i
531
553
  end
554
+
555
+ def fail_missing_publication(publication_href)
556
+ unless lookup_publication(publication_href)
557
+ fail _("The repository's publication is missing. Please run a 'complete sync' on %s." % repo.name)
558
+ end
559
+ end
532
560
  end
533
561
  end
534
562
  end
@@ -6,4 +6,6 @@
6
6
  <div ng-controller="PulpPrimaryController">
7
7
  <%= render :file => 'smart_proxies/show' %>
8
8
  </div>
9
+ <% else -%>
10
+ <%= render :file => 'smart_proxies/show' %>
9
11
  <% end -%>
@@ -6,13 +6,6 @@ child :artifacts => :artifacts do
6
6
  attributes :id, :name
7
7
  end
8
8
 
9
- child :profiles => :profiles do
10
- attributes :id, :name
11
- child :rpms => :rpms do
12
- attributes :id, :name
13
- end
14
- end
15
-
16
9
  child :library_repositories => :repositories do
17
10
  attributes :id, :name
18
11
  glue :product do
@@ -20,7 +20,7 @@ class CleanDuplicateContentUnits < ActiveRecord::Migration[6.0]
20
20
  to_delete = []
21
21
  to_update = []
22
22
  duplicate_models.each do |duplicate|
23
- query = {new_id_field => new_id}
23
+ query = { new_id_field => new_id }
24
24
  unique_fields.each do |field|
25
25
  query[field] = duplicate.send(field)
26
26
  end
@@ -52,28 +52,25 @@ class CleanDuplicateContentUnits < ActiveRecord::Migration[6.0]
52
52
  def up
53
53
  handle_null_pulp_ids
54
54
  add_foreign_keys
55
+ delete_deprecated_models
55
56
 
56
57
  handle_duplicate(Katello::ModuleStream,
57
58
  'module_stream_id',
58
59
  [:pulp_id],
59
- associated_models: {Katello::RepositoryModuleStream => :repository_id},
60
+ associated_models: { Katello::RepositoryModuleStream => :repository_id },
60
61
  child_models: [Katello::ContentViewModuleStreamFilterRule,
61
62
  Katello::ContentFacetApplicableModuleStream,
62
63
  Katello::ModuleProfile,
63
64
  Katello::ModuleStreamArtifact,
64
65
  Katello::ModuleStreamErratumPackage,
65
66
  Katello::ModuleStreamRpm])
66
- add_index :katello_module_streams, :pulp_id, :unique => true
67
67
 
68
- handle_duplicate(Katello::ModuleProfile, 'module_profile_id', [:module_stream_id, :name],
69
- child_models: [Katello::ModuleProfileRpm])
68
+ add_index :katello_module_streams, :pulp_id, :unique => true
70
69
  add_index :katello_module_profiles, [:module_stream_id, :name], :unique => true
71
-
72
- handle_duplicate(Katello::ModuleProfileRpm, 'module_profile_rpm_id', [:module_profile_id, :name])
73
70
  add_index :katello_module_profile_rpms, [:module_profile_id, :name], :unique => true
74
71
 
75
72
  handle_duplicate(Katello::AnsibleTag, 'ansible_tag_id', [:name],
76
- associated_models: {Katello::AnsibleCollectionTag => :ansible_collection_id})
73
+ associated_models: { Katello::AnsibleCollectionTag => :ansible_collection_id })
77
74
  add_index :katello_ansible_tags, [:name], :unique => true
78
75
 
79
76
  handle_duplicate(Katello::AnsibleCollectionTag, 'ansible_collection_tag_id', [:ansible_collection_id, :ansible_tag_id])
@@ -83,7 +80,7 @@ class CleanDuplicateContentUnits < ActiveRecord::Migration[6.0]
83
80
  handle_duplicate(Katello::GenericContentUnit,
84
81
  'generic_content_unit_id',
85
82
  [:pulp_id],
86
- associated_models: {Katello::RepositoryGenericContentUnit => :repository_id})
83
+ associated_models: { Katello::RepositoryGenericContentUnit => :repository_id })
87
84
  add_index :katello_generic_content_units, :pulp_id, :unique => true
88
85
 
89
86
  handle_duplicate(Katello::DockerManifestList, 'docker_manifest_list_id', [:pulp_id],
@@ -112,6 +109,11 @@ class CleanDuplicateContentUnits < ActiveRecord::Migration[6.0]
112
109
  change_column :katello_docker_manifests, :pulp_id, :string, :null => false
113
110
  end
114
111
 
112
+ def delete_deprecated_models
113
+ Katello::ModuleProfileRpm.delete_all
114
+ Katello::ModuleProfile.delete_all
115
+ end
116
+
115
117
  def add_foreign_keys
116
118
  Katello::DockerManifestListManifest.where.not(docker_manifest_list_id: Katello::DockerManifestList.pluck(:id)).delete_all
117
119
  add_foreign_key :katello_docker_manifest_list_manifests, :katello_docker_manifest_lists, column: :docker_manifest_list_id
@@ -1,4 +1,8 @@
1
1
  class RemoveDuplicateErrata < ActiveRecord::Migration[6.0]
2
+ # rubocop:disable Metrics/MethodLength
3
+ # rubocop:disable Metrics/AbcSize
4
+ # rubocop:disable Metrics/CyclomaticComplexity
5
+ # rubocop:disable Metrics/PerceivedComplexity
2
6
  def up
3
7
  #Update all unique errata records to have pulp_id = errata_id
4
8
  ::Katello::Erratum.group(:errata_id).having("count(errata_id) = 1").pluck(:errata_id).each do |original_errata_id|
@@ -24,9 +28,36 @@ class RemoveDuplicateErrata < ActiveRecord::Migration[6.0]
24
28
  repo_erratum.update(erratum_id: errata_to_keep.id)
25
29
  end
26
30
  end
31
+ ::Katello::ContentFacetErratum.where(erratum_id: dup_errata&.map(&:id)).each do |host_erratum|
32
+ if ::Katello::ContentFacetErratum.find_by(content_facet_id: host_erratum.content_facet_id, erratum_id: errata_to_keep.id)
33
+ host_erratum.delete
34
+ else
35
+ host_erratum.update(erratum_id: errata_to_keep.id)
36
+ end
37
+ end
38
+ dup_errata_ids = dup_errata&.pluck(:id)
39
+
40
+ erratum_packages = ::Katello::ErratumPackage.where(:erratum_id => dup_errata_ids)
41
+ erratum_packages.each do |dup_err_package|
42
+ erratum_package_to_keep = ::Katello::ErratumPackage.find_by(erratum_id: errata_to_keep.id, nvrea: dup_err_package.nvrea)
43
+ ::Katello::ModuleStreamErratumPackage.where(erratum_package_id: dup_err_package).each do |dup_mod_errata_package|
44
+ if ::Katello::ModuleStreamErratumPackage.find_by(module_stream_id: dup_mod_errata_package.module_stream_id, erratum_package_id: erratum_package_to_keep&.id)
45
+ dup_mod_errata_package.delete
46
+ else
47
+ begin
48
+ dup_mod_errata_package.update(erratum_package_id: erratum_package_to_keep&.id)
49
+ rescue
50
+ dup_mod_errata_package.delete
51
+ end
52
+ end
53
+ end
54
+ end
55
+
27
56
  dup_errata_ids = dup_errata&.pluck(:id)
28
57
  if dup_errata_ids&.present?
29
- ::Katello::ErratumPackage.where(:erratum_id => dup_errata_ids).delete_all
58
+ erratum_packages = ::Katello::ErratumPackage.where(:erratum_id => dup_errata_ids)
59
+ ::Katello::ModuleStreamErratumPackage.where(erratum_package_id: erratum_packages).delete_all
60
+ erratum_packages.delete_all
30
61
  ::Katello::ErratumBugzilla.where(:erratum_id => dup_errata_ids).delete_all
31
62
  ::Katello::ErratumCve.where(:erratum_id => dup_errata_ids).delete_all
32
63
  ::Katello::Erratum.where(:id => dup_errata_ids).delete_all
@@ -34,7 +65,11 @@ class RemoveDuplicateErrata < ActiveRecord::Migration[6.0]
34
65
  end
35
66
  end
36
67
 
68
+ # rubocop:enable Metrics/MethodLength
69
+ # rubocop:enable Metrics/AbcSize
70
+ # rubocop:enable Metrics/CyclomaticComplexity
71
+ # rubocop:enable Metrics/PerceivedComplexity
37
72
  def down
38
- fail ActiveRecord::IrreversibleMigration
73
+ #Don't do anything on reverse
39
74
  end
40
75
  end
@@ -10,7 +10,7 @@
10
10
  angular.module('Bastion.repositories').service('MirroringPolicy',
11
11
  ['translate', function (translate) {
12
12
 
13
- this.defaultMirroringPolicy = 'additive';
13
+ this.defaultMirroringPolicy = 'mirror_content_only';
14
14
 
15
15
  this.mirroringPolicies = function(repoType) {
16
16
  var policies = {
@@ -1,3 +1,3 @@
1
1
  module Katello
2
- VERSION = "4.4.0.2".freeze
2
+ VERSION = "4.4.2".freeze
3
3
  end
@@ -139,6 +139,7 @@ export const useBulkSelect = ({
139
139
  initialArry = [],
140
140
  initialSearchQuery = '',
141
141
  idColumn = 'id',
142
+ filtersQuery = '',
142
143
  isSelectable,
143
144
  }) => {
144
145
  const { selectionSet: inclusionSet, ...selectOptions } =
@@ -200,16 +201,16 @@ export const useBulkSelect = ({
200
201
  }
201
202
  };
202
203
 
203
- const fetchBulkParams = () => {
204
+ const fetchBulkParams = (idColumnName = idColumn) => {
204
205
  const searchQueryWithExclusionSet = () => {
205
- const query = [searchQuery,
206
- !isEmpty(exclusionSet) && `${idColumn} !^ (${[...exclusionSet].join(',')})`];
206
+ const query = [searchQuery, filtersQuery,
207
+ !isEmpty(exclusionSet) && `${idColumnName} !^ (${[...exclusionSet].join(',')})`];
207
208
  return query.filter(item => item).join(' and ');
208
209
  };
209
210
 
210
211
  const searchQueryWithInclusionSet = () => {
211
212
  if (isEmpty(inclusionSet)) throw new Error('Cannot build a search query with no items selected');
212
- return `${idColumn} ^ (${[...inclusionSet].join(',')})`;
213
+ return `${idColumnName} ^ (${[...inclusionSet].join(',')})`;
213
214
  };
214
215
 
215
216
  return selectAllMode ? searchQueryWithExclusionSet() : searchQueryWithInclusionSet();
@@ -0,0 +1,99 @@
1
+ import { act, renderHook } from '@testing-library/react-hooks';
2
+ import { useBulkSelect } from '../TableHooks';
3
+
4
+ const isSelectable = () => true;
5
+ const idColumn = 'errata_id';
6
+ const metadata = {
7
+ error: null, selectable: 2, subtotal: 2, total: 2,
8
+ };
9
+ const results = [
10
+ {
11
+ errata_id: 'RHSA-2022:2031',
12
+ id: 311,
13
+ severity: 'Low',
14
+ type: 'security',
15
+ },
16
+ {
17
+ errata_id: 'RHSA-2022:2110',
18
+ id: 17,
19
+ severity: 'Low',
20
+ type: 'security',
21
+ },
22
+ ];
23
+
24
+ it('returns a scoped search string based on inclusionSet', () => {
25
+ const { result } = renderHook(() => useBulkSelect({
26
+ results,
27
+ metadata,
28
+ idColumn,
29
+ isSelectable,
30
+ }));
31
+
32
+ act(() => {
33
+ result.current.selectOne(true, 'RHSA-2022:2031');
34
+ });
35
+
36
+ expect(result.current.fetchBulkParams()).toBe('errata_id ^ (RHSA-2022:2031)');
37
+ });
38
+
39
+ it('returns a scoped search string based on exclusionSet', () => {
40
+ const { result } = renderHook(() => useBulkSelect({
41
+ results,
42
+ metadata,
43
+ idColumn,
44
+ isSelectable,
45
+ }));
46
+
47
+ act(() => {
48
+ result.current.selectAll(true);
49
+ });
50
+
51
+ act(() => {
52
+ result.current.selectOne(false, 'RHSA-2022:2031');
53
+ });
54
+
55
+ expect(result.current.fetchBulkParams()).toBe('errata_id !^ (RHSA-2022:2031)');
56
+ });
57
+
58
+ it('adds search query to scoped search string based on exclusionSet', () => {
59
+ const { result } = renderHook(() => useBulkSelect({
60
+ results,
61
+ metadata,
62
+ idColumn,
63
+ isSelectable,
64
+ }));
65
+
66
+ act(() => {
67
+ result.current.updateSearchQuery('type=security');
68
+ });
69
+
70
+ act(() => {
71
+ result.current.selectAll(true);
72
+ });
73
+
74
+ act(() => {
75
+ result.current.selectOne(false, 'RHSA-2022:2031');
76
+ });
77
+
78
+ expect(result.current.fetchBulkParams()).toBe('type=security and errata_id !^ (RHSA-2022:2031)');
79
+ });
80
+
81
+ it('adds filter dropdown query to scoped search string', () => {
82
+ const { result } = renderHook(() => useBulkSelect({
83
+ results,
84
+ metadata,
85
+ idColumn,
86
+ isSelectable,
87
+ filtersQuery: 'severity=Low',
88
+ }));
89
+
90
+ act(() => {
91
+ result.current.selectAll(true);
92
+ });
93
+
94
+ act(() => {
95
+ result.current.selectOne(false, 'RHSA-2022:2031');
96
+ });
97
+
98
+ expect(result.current.fetchBulkParams()).toBe('severity=Low and errata_id !^ (RHSA-2022:2031)');
99
+ });
@@ -79,6 +79,17 @@ export const ErrataTab = () => {
79
79
  __('Published date'),
80
80
  ];
81
81
 
82
+ const filtersQuery = () => {
83
+ const query = [];
84
+ if (errataTypeSelected !== ERRATA_TYPE) {
85
+ query.push(`type=${TYPES_TO_PARAM[errataTypeSelected]}`);
86
+ }
87
+ if (errataSeveritySelected !== ERRATA_SEVERITY) {
88
+ query.push(`severity=${SEVERITIES_TO_PARAM[errataSeveritySelected]}`);
89
+ }
90
+ return query.join(' and ');
91
+ };
92
+
82
93
  const fetchItems = useCallback(
83
94
  (params) => {
84
95
  if (!hostId) return hostIdNotReady;
@@ -112,6 +123,7 @@ export const ErrataTab = () => {
112
123
  results,
113
124
  metadata,
114
125
  idColumn: 'errata_id',
126
+ filtersQuery: filtersQuery(),
115
127
  isSelectable: result => result.installable,
116
128
  initialSearchQuery: searchParam || '',
117
129
  });
@@ -248,7 +260,7 @@ export const ErrataTab = () => {
248
260
  );
249
261
 
250
262
  const hostIsNonLibrary = (
251
- contentFacet?.contentViewDefault === false && contentFacet.lifecycleEnvironmentLibrary === false
263
+ contentFacet?.contentViewDefault === false || contentFacet.lifecycleEnvironmentLibrary === false
252
264
  );
253
265
  const toggleGroup = (
254
266
  <Split hasGutter>
@@ -75,7 +75,7 @@ const RepositorySetsTab = () => {
75
75
  contentViewName,
76
76
  lifecycleEnvironmentName,
77
77
  } = contentFacet;
78
- const nonLibraryHost = contentViewDefault === false &&
78
+ const nonLibraryHost = contentViewDefault === false ||
79
79
  lifecycleEnvironmentLibrary === false;
80
80
  const simpleContentAccess = (Number(subscriptionStatus) === 5);
81
81
  const dispatch = useDispatch();
@@ -558,7 +558,7 @@ test('Toggle Group shows if it\'s not the default content view or library enviro
558
558
  assertNockRequest(scope, done); // Pass jest callback to confirm test is done
559
559
  });
560
560
 
561
- test('Toggle Group does not show if it\'s the default content view ', async (done) => {
561
+ test('Toggle Group shows if it\'s the default content view but non-library environment', async (done) => {
562
562
  const options = renderOptions({
563
563
  ...contentFacetAttributes,
564
564
  content_view_default: true,
@@ -579,14 +579,41 @@ test('Toggle Group does not show if it\'s the default content view ', async (don
579
579
 
580
580
  // Assert that the errata are now showing on the screen, but wait for them to appear.
581
581
  await patientlyWaitFor(() => expect(getAllByText('Important')[0]).toBeInTheDocument());
582
- expect(queryByLabelText('Installable Errata')).not.toBeInTheDocument();
582
+ expect(queryByLabelText('Installable Errata')).toBeInTheDocument();
583
+ assertNockRequest(autocompleteScope);
584
+ assertNockRequest(scope, done); // Pass jest callback to confirm test is done
585
+ });
586
+
587
+ test('Toggle Group shows if it\'s the library environment but non-default content view', async (done) => {
588
+ const options = renderOptions({
589
+ ...contentFacetAttributes,
590
+ lifecycle_environment_library: true,
591
+ });
592
+ // Setup autocomplete with mockForemanAutoComplete since we aren't adding /katello
593
+ const autocompleteScope = mockForemanAutocomplete(nockInstance, autocompleteUrl);
594
+ const mockErrata = makeMockErrata({});
595
+ // return errata data results when we look for errata
596
+ const scope = nockInstance
597
+ .get(hostErrata)
598
+ .query(defaultQuery)
599
+ .reply(200, mockErrata);
600
+
601
+ const {
602
+ queryByLabelText,
603
+ getAllByText,
604
+ } = renderWithRedux(<ErrataTab />, options);
605
+
606
+ // Assert that the errata are now showing on the screen, but wait for them to appear.
607
+ await patientlyWaitFor(() => expect(getAllByText('Important')[0]).toBeInTheDocument());
608
+ expect(queryByLabelText('Installable Errata')).toBeInTheDocument();
583
609
  assertNockRequest(autocompleteScope);
584
610
  assertNockRequest(scope, done); // Pass jest callback to confirm test is done
585
611
  });
586
612
 
587
- test('Toggle Group does not show if it\'s the library environment', async (done) => {
613
+ test('Toggle Group does not show if it\'s the default content view and library environment', async (done) => {
588
614
  const options = renderOptions({
589
615
  ...contentFacetAttributes,
616
+ content_view_default: true,
590
617
  lifecycle_environment_library: true,
591
618
  });
592
619
  // Setup autocomplete with mockForemanAutoComplete since we aren't adding /katello
@@ -36,7 +36,7 @@ const autocompleteUrl = '/repository_sets/auto_complete_search';
36
36
  const repositorySetBookmarks = foremanApi.getApiUrl('/bookmarks?search=controller%3Dkatello_product_contents');
37
37
  const contentOverride = foremanApi.getApiUrl('/hosts/1/subscriptions/content_override');
38
38
 
39
- const defaultQuery = {
39
+ const limitToEnvQuery = {
40
40
  content_access_mode_env: true,
41
41
  content_access_mode_all: true,
42
42
  host_id: 1,
@@ -44,8 +44,8 @@ const defaultQuery = {
44
44
  page: 1,
45
45
  search: '',
46
46
  };
47
- const libraryQuery = {
48
- ...defaultQuery,
47
+ const showAllQuery = {
48
+ ...limitToEnvQuery,
49
49
  content_access_mode_env: false,
50
50
  };
51
51
 
@@ -73,7 +73,7 @@ test('Can call API for repository sets and show basic table', async (done) => {
73
73
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
74
74
  const scope = nockInstance
75
75
  .get(hostRepositorySets)
76
- .query(defaultQuery)
76
+ .query(limitToEnvQuery)
77
77
  .reply(200, mockRepoSetData);
78
78
 
79
79
  const { getByText } = renderWithRedux(<RepositorySetsTab />, renderOptions());
@@ -97,7 +97,7 @@ test('Can handle no repository sets being present', async (done) => {
97
97
 
98
98
  const scope = nockInstance
99
99
  .get(hostRepositorySets)
100
- .query(defaultQuery)
100
+ .query(limitToEnvQuery)
101
101
  .reply(200, noResults);
102
102
 
103
103
  const { queryByText } = renderWithRedux(<RepositorySetsTab />, renderOptions());
@@ -113,7 +113,7 @@ test('Toggle Group shows if it\'s not the default content view or library enviro
113
113
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
114
114
  const scope = nockInstance
115
115
  .get(hostRepositorySets)
116
- .query(defaultQuery)
116
+ .query(limitToEnvQuery)
117
117
  .reply(200, mockRepoSetData);
118
118
 
119
119
  const {
@@ -128,7 +128,7 @@ test('Toggle Group shows if it\'s not the default content view or library enviro
128
128
  assertNockRequest(scope, done); // Pass jest callback to confirm test is done
129
129
  });
130
130
 
131
- test('Toggle Group does not show if it\'s the default content view ', async (done) => {
131
+ test('Toggle Group shows if it\'s the default content view but non-library environment', async (done) => {
132
132
  const options = renderOptions({
133
133
  ...contentFacetAttributes,
134
134
  content_view_default: true,
@@ -137,7 +137,7 @@ test('Toggle Group does not show if it\'s the default content view ', async (don
137
137
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
138
138
  const scope = nockInstance
139
139
  .get(hostRepositorySets)
140
- .query(libraryQuery)
140
+ .query(limitToEnvQuery)
141
141
  .reply(200, mockRepoSetData);
142
142
 
143
143
  const {
@@ -147,12 +147,12 @@ test('Toggle Group does not show if it\'s the default content view ', async (don
147
147
 
148
148
  // Assert that the errata are now showing on the screen, but wait for them to appear.
149
149
  await patientlyWaitFor(() => expect(getByText(firstRepoSet.contentUrl)).toBeInTheDocument());
150
- expect(queryByLabelText('Limit to environment')).not.toBeInTheDocument();
150
+ expect(queryByLabelText('Limit to environment')).toBeInTheDocument();
151
151
  assertNockRequest(autocompleteScope);
152
152
  assertNockRequest(scope, done); // Pass jest callback to confirm test is done
153
153
  });
154
154
 
155
- test('Toggle Group does not show if it\'s the library environment', async (done) => {
155
+ test('Toggle Group shows if it\'s the library environment but a non-default content view', async (done) => {
156
156
  const options = renderOptions({
157
157
  ...contentFacetAttributes,
158
158
  lifecycle_environment_library: true,
@@ -161,7 +161,32 @@ test('Toggle Group does not show if it\'s the library environment', async (done)
161
161
  // return errata data results when we look for errata
162
162
  const scope = nockInstance
163
163
  .get(hostRepositorySets)
164
- .query(libraryQuery)
164
+ .query(limitToEnvQuery)
165
+ .reply(200, mockRepoSetData);
166
+
167
+ const {
168
+ queryByLabelText,
169
+ getByText,
170
+ } = renderWithRedux(<RepositorySetsTab />, options);
171
+
172
+ // Assert that the errata are now showing on the screen, but wait for them to appear.
173
+ await patientlyWaitFor(() => expect(getByText(firstRepoSet.contentUrl)).toBeInTheDocument());
174
+ expect(queryByLabelText('Limit to environment')).toBeInTheDocument();
175
+ assertNockRequest(autocompleteScope);
176
+ assertNockRequest(scope, done); // Pass jest callback to confirm test is done
177
+ });
178
+
179
+ test('Toggle Group does not show if it\'s the library environment and default content view', async (done) => {
180
+ const options = renderOptions({
181
+ ...contentFacetAttributes,
182
+ lifecycle_environment_library: true,
183
+ content_view_default: true,
184
+ });
185
+ const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
186
+ // return errata data results when we look for errata
187
+ const scope = nockInstance
188
+ .get(hostRepositorySets)
189
+ .query(showAllQuery)
165
190
  .reply(200, mockRepoSetData);
166
191
 
167
192
  const {
@@ -182,7 +207,7 @@ test('Can toggle with the Toggle Group ', async (done) => {
182
207
  // return errata data results when we look for errata
183
208
  const scope = nockInstance
184
209
  .get(hostRepositorySets)
185
- .query(defaultQuery)
210
+ .query(limitToEnvQuery)
186
211
  .reply(200, mockRepoSetData);
187
212
 
188
213
  const {
@@ -202,7 +227,7 @@ test('Can override to disabled', async (done) => {
202
227
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
203
228
  const scope = nockInstance
204
229
  .get(hostRepositorySets)
205
- .query(defaultQuery)
230
+ .query(limitToEnvQuery)
206
231
  .reply(200, mockRepoSetData);
207
232
  const contentOverrideScope = nockInstance
208
233
  .put(contentOverride)
@@ -238,7 +263,7 @@ test('Can override to enabled', async (done) => {
238
263
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
239
264
  const scope = nockInstance
240
265
  .get(hostRepositorySets)
241
- .query(defaultQuery)
266
+ .query(limitToEnvQuery)
242
267
  .reply(200, mockRepoSetData);
243
268
  const contentOverrideScope = nockInstance
244
269
  .put(contentOverride)
@@ -274,7 +299,7 @@ test('Can reset to default', async (done) => {
274
299
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
275
300
  const scope = nockInstance
276
301
  .get(hostRepositorySets)
277
- .query(defaultQuery)
302
+ .query(limitToEnvQuery)
278
303
  .reply(200, mockRepoSetData);
279
304
  const contentOverrideScope = nockInstance
280
305
  .put(contentOverride)
@@ -115,7 +115,7 @@ const CreateContentViewForm = ({ setModalOpen }) => {
115
115
  aria-label="component_tile"
116
116
  icon={<ContentViewIcon composite={false} />}
117
117
  id="component"
118
- title={__('Component content view')}
118
+ title={__('Content view')}
119
119
  onClick={() => { setComponent(true); setComposite(false); }}
120
120
  isSelected={component}
121
121
  >
@@ -133,7 +133,7 @@ const CreateContentViewForm = ({ setModalOpen }) => {
133
133
  onClick={() => { setComposite(true); setComponent(false); }}
134
134
  isSelected={composite}
135
135
  >
136
- {__('Consisting of multiple component content views')}
136
+ {__('Consisting of multiple content views')}
137
137
  </Tile>
138
138
  </GridItem>
139
139
  </Grid>
@@ -68,7 +68,7 @@ test('Displays dependent fields correctly', () => {
68
68
  expect(getByText('Name')).toBeInTheDocument();
69
69
  expect(getByText('Label')).toBeInTheDocument();
70
70
  expect(getByText('Composite content view')).toBeInTheDocument();
71
- expect(getByText('Component content view')).toBeInTheDocument();
71
+ expect(getByText('Content view')).toBeInTheDocument();
72
72
  expect(getByText('Solve dependencies')).toBeInTheDocument();
73
73
  expect(queryByText('Auto publish')).not.toBeInTheDocument();
74
74
  expect(getByText('Import only')).toBeInTheDocument();
@@ -87,7 +87,7 @@ const ComponentContentViewAddModal = ({
87
87
 
88
88
  return (
89
89
  <Modal
90
- title={componentId ? __('Update version') : __('Add component')}
90
+ title={componentId ? __('Update version') : __('Add content view')}
91
91
  variant={ModalVariant.small}
92
92
  isOpen={show}
93
93
  description={__(`Select available version of ${cvName} to use`)}
@@ -51,10 +51,10 @@ const ComponentContentViewBulkAddModal = ({ cvId, rowsToAdd, onClose }) => {
51
51
 
52
52
  return (
53
53
  <Modal
54
- title={__('Add component content views')}
54
+ title={__('Add content views')}
55
55
  variant={ModalVariant.large}
56
56
  isOpen
57
- description={__('Select available version of components to use')}
57
+ description={__('Select available version of content views to use')}
58
58
  onClose={onClose}
59
59
  appendTo={document.body}
60
60
  >
@@ -212,7 +212,7 @@ test('Can add published component views to content view with modal', async (done
212
212
  });
213
213
  fireEvent.click(getByText('Add'));
214
214
  await patientlyWaitFor(() => {
215
- expect(getByText('Add component')).toBeInTheDocument();
215
+ expect(getByText('Add content view')).toBeInTheDocument();
216
216
  });
217
217
  fireEvent.click(getByLabelText('add_component'));
218
218
  await patientlyWaitFor(() => {
@@ -317,7 +317,7 @@ test('Can bulk add component views to content view with modal', async (done) =>
317
317
  .reply(200, {});
318
318
 
319
319
  const {
320
- getByText, getByLabelText, queryByText,
320
+ getAllByText, getByLabelText, queryByText,
321
321
  } = renderWithRedux(
322
322
  <ContentViewComponents cvId={4} details={cvDetails} />,
323
323
  renderOptions,
@@ -333,14 +333,14 @@ test('Can bulk add component views to content view with modal', async (done) =>
333
333
  });
334
334
  fireEvent.click(getByLabelText('bulk_add_components'));
335
335
  await patientlyWaitFor(() => {
336
- expect(getByText('Add component content views')).toBeInTheDocument();
336
+ expect(getAllByText('Add content views')[1]).toBeInTheDocument();
337
337
  });
338
338
  fireEvent.click(getByLabelText('version-select-cv-10'));
339
339
  fireEvent.click(getByLabelText('cv-10-3.0'));
340
340
 
341
341
  fireEvent.click(getByLabelText('add_components'));
342
342
  await patientlyWaitFor(() => {
343
- expect(queryByText('Add component content views')).not.toBeInTheDocument();
343
+ expect(queryByText('Select available version of content views to use')).not.toBeInTheDocument();
344
344
  expect(getByLabelText('bulk_add_components')).toHaveAttribute('aria-disabled', 'false');
345
345
  });
346
346
 
@@ -70,7 +70,7 @@ const ContentViewInfo = ({ cvId, details }) => {
70
70
  <TextListItem component={TextListItemVariants.dd} className="foreman-spaced-list">
71
71
  <Flex>
72
72
  <FlexItem spacer={{ default: 'spacerXs' }}>
73
- <ContentViewIcon composite={composite} description={composite ? __('Composite') : __('Component')} />
73
+ <ContentViewIcon composite={composite} description={composite ? __('Composite') : __('Content view')} />
74
74
  </FlexItem>
75
75
  </Flex>
76
76
  </TextListItem>
@@ -43,14 +43,14 @@ test('Can call API for CVs and show on screen on page load', async (done) => {
43
43
  .query(true)
44
44
  .reply(200, cvIndexData);
45
45
 
46
- const { queryByText } = renderWithRedux(<ContentViewsPage />, renderOptions);
46
+ const { queryByText, queryAllByText } = renderWithRedux(<ContentViewsPage />, renderOptions);
47
47
 
48
48
  expect(queryByText(firstCV.name)).toBeNull();
49
49
 
50
50
  // Assert that the CV name is now showing on the screen, but wait for it to appear.
51
51
  await patientlyWaitFor(() => {
52
52
  expect(queryByText(firstCV.name)).toBeInTheDocument();
53
- expect(queryByText('Component content views')).toBeInTheDocument();
53
+ expect(queryAllByText('Content views')[0]).toBeInTheDocument();
54
54
  expect(queryByText('Composite content views')).toBeInTheDocument();
55
55
  });
56
56
 
@@ -354,7 +354,7 @@ test('Displays Create Content View and opens modal with Form', async () => {
354
354
  expect(queryByText('Name')).not.toBeInTheDocument();
355
355
  expect(queryByText('Label')).not.toBeInTheDocument();
356
356
  expect(queryByText('Composite content view')).not.toBeInTheDocument();
357
- expect(queryByText('Component content view')).not.toBeInTheDocument();
357
+ expect(queryByText('Content view')).not.toBeInTheDocument();
358
358
  expect(queryByText('Solve dependencies')).not.toBeInTheDocument();
359
359
  expect(queryByText('Auto publish')).not.toBeInTheDocument();
360
360
  expect(queryByText('Import only')).not.toBeInTheDocument();
@@ -365,7 +365,7 @@ test('Displays Create Content View and opens modal with Form', async () => {
365
365
  expect(getByText('Name')).toBeInTheDocument();
366
366
  expect(getByText('Label')).toBeInTheDocument();
367
367
  expect(getByText('Composite content view')).toBeInTheDocument();
368
- expect(getByText('Component content view')).toBeInTheDocument();
368
+ expect(getByText('Content view')).toBeInTheDocument();
369
369
  expect(getByText('Solve dependencies')).toBeInTheDocument();
370
370
  expect(queryByText('Auto publish')).not.toBeInTheDocument();
371
371
  expect(getByText('Import only')).toBeInTheDocument();
@@ -18,7 +18,7 @@ const ContentViewsCounter = () => {
18
18
  <b>
19
19
  <Flex>
20
20
  <FlexItem spacer={{ default: 'spacerXs' }}>
21
- <ContentViewIcon composite={false} description={__('Component content views')} count={(component || component === 0) ? component : <InProgressIcon />} />
21
+ <ContentViewIcon composite={false} description={__('Content views')} count={(component || component === 0) ? component : <InProgressIcon />} />
22
22
  </FlexItem>
23
23
  <FlexItem>
24
24
  <Tooltip
@@ -14,14 +14,14 @@ const DetailsExpansion = ({
14
14
  if (cvComposite) {
15
15
  return (
16
16
  <>
17
- {__('Related component cvs: ')}
17
+ {__('Related content views: ')}
18
18
  <RelatedContentViewComponentsModal key="cvId" {...{ cvName, cvId, relatedCVCount }} />
19
19
  </>
20
20
  );
21
21
  }
22
22
  return (
23
23
  <>
24
- {__('Related composite cvs: ')}
24
+ {__('Related composite content views: ')}
25
25
  <RelatedCompositeContentViewsModal
26
26
  key={cvId}
27
27
  {...{
@@ -29,7 +29,7 @@ const RelatedContentViewsModal = ({ cvName, cvId, relatedCVCount }) => {
29
29
  <FlexItem>
30
30
  <RegistryIcon />
31
31
  <b>{` ${cvName}`}</b>
32
- {__(' content view is used in listed component content views. For more information, ')}
32
+ {__(' content view is used in listed content views. For more information, ')}
33
33
  <Link to={urlBuilder(`content_views/${cvId}#/contentviews`, '')}>
34
34
  {__('view content view tabs.')}
35
35
  </Link>
@@ -49,7 +49,7 @@ const RelatedContentViewsModal = ({ cvName, cvId, relatedCVCount }) => {
49
49
  <Grid>
50
50
  <GridItem span={12}>
51
51
  <Modal
52
- title={__('Related component content views')}
52
+ title={__('Related content views')}
53
53
  variant={ModalVariant.medium}
54
54
  isOpen={isOpen}
55
55
  description={description()}
@@ -30,7 +30,7 @@ test('Can call API and show Related Content Views Components Modal', async (done
30
30
 
31
31
  await patientlyWaitFor(() => expect(getByLabelText(`button_${cvId}`)).toBeInTheDocument());
32
32
  fireEvent.click(getByLabelText(`button_${cvId}`));
33
- await patientlyWaitFor(() => expect(getByText('Related component content views')).toBeInTheDocument());
33
+ await patientlyWaitFor(() => expect(getByText('Related content views')).toBeInTheDocument());
34
34
 
35
35
  assertNockRequest(scope, done);
36
36
  });
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import { translate as __ } from 'foremanReact/common/I18n';
3
3
  import ModuleStreamDetailArtifacts from './ModuleStreamDetailArtifacts';
4
- import ModuleStreamDetailProfiles from './Profiles/ModuleStreamDetailProfiles';
5
4
  import ContentDetailInfo from '../../../components/Content/Details/ContentDetailInfo';
6
5
  import ContentDetailRepositories from '../../../components/Content/Details/ContentDetailRepositories';
7
6
 
@@ -17,7 +16,7 @@ export const displayMap = new Map([
17
16
  ]);
18
17
 
19
18
  export default (detailInfo) => {
20
- const { repositories, profiles, artifacts } = detailInfo;
19
+ const { repositories, artifacts } = detailInfo;
21
20
 
22
21
  return [
23
22
  {
@@ -37,14 +36,6 @@ export default (detailInfo) => {
37
36
  },
38
37
  {
39
38
  key: 3,
40
- tabHeader: __('Profiles'),
41
- tabContent: (profiles && profiles.length ?
42
- <ModuleStreamDetailProfiles profiles={profiles} /> :
43
- __('No profiles to show')
44
- ),
45
- },
46
- {
47
- key: 4,
48
39
  tabHeader: __('Artifacts'),
49
40
  tabContent: (artifacts && artifacts.length ?
50
41
  <ModuleStreamDetailArtifacts artifacts={artifacts} /> :
@@ -44,21 +44,20 @@ class ModuleStreamDetails extends Component {
44
44
  return (
45
45
  <div>
46
46
  {!loading && <BreadcrumbsBar
47
+ isLoadingResources={loading}
47
48
  onSwitcherItemClick={(e, url) => this.handleBreadcrumbSwitcherItem(e, url)}
48
- data={{
49
- isSwitchable: true,
50
- breadcrumbItems: [
51
- {
52
- caption: __('Module Streams'),
53
- onClick: () =>
54
- this.props.history.push('/module_streams'),
55
- },
56
- {
57
- caption: `${name} ${stream}`,
58
- },
59
- ],
60
- resource,
61
- }}
49
+ isSwitchable
50
+ breadcrumbItems={[
51
+ {
52
+ caption: __('Module Streams'),
53
+ onClick: () =>
54
+ this.props.history.push('/module_streams'),
55
+ },
56
+ {
57
+ caption: `${name} ${stream}`,
58
+ },
59
+ ]}
60
+ resource={resource}
62
61
  />}
63
62
  <ContentDetails
64
63
  contentDetails={moduleStreamDetails}
@@ -76,11 +76,6 @@ exports[`Module stream details page rendering renders with loading state 1`] = `
76
76
  },
77
77
  Object {
78
78
  "key": 3,
79
- "tabContent": "No profiles to show",
80
- "tabHeader": "Profiles",
81
- },
82
- Object {
83
- "key": 4,
84
79
  "tabContent": "No artifacts to show",
85
80
  "tabHeader": "Artifacts",
86
81
  },
@@ -93,26 +88,26 @@ exports[`Module stream details page rendering renders with loading state 1`] = `
93
88
  exports[`Module stream details page rendering renders with module stream provided 1`] = `
94
89
  <div>
95
90
  <BreadcrumbsBar
96
- data={
97
- Object {
98
- "breadcrumbItems": Array [
99
- Object {
100
- "caption": "Module Streams",
101
- "onClick": [Function],
102
- },
103
- Object {
104
- "caption": "avocado latest",
105
- },
106
- ],
107
- "isSwitchable": true,
108
- "resource": Object {
109
- "nameField": "name",
110
- "resourceUrl": "/katello/api/v2/module_streams",
111
- "switcherItemUrl": "/module_streams/:id",
91
+ breadcrumbItems={
92
+ Array [
93
+ Object {
94
+ "caption": "Module Streams",
95
+ "onClick": [Function],
112
96
  },
113
- }
97
+ Object {
98
+ "caption": "avocado latest",
99
+ },
100
+ ]
114
101
  }
102
+ isSwitchable={true}
115
103
  onSwitcherItemClick={[Function]}
104
+ resource={
105
+ Object {
106
+ "nameField": "name",
107
+ "resourceUrl": "/katello/api/v2/module_streams",
108
+ "switcherItemUrl": "/module_streams/:id",
109
+ }
110
+ }
116
111
  />
117
112
  <ContentDetails
118
113
  contentDetails={
@@ -397,84 +392,6 @@ exports[`Module stream details page rendering renders with module stream provide
397
392
  },
398
393
  Object {
399
394
  "key": 3,
400
- "tabContent": <ModuleStreamDetailProfiles
401
- profiles={
402
- Array [
403
- Object {
404
- "id": 37,
405
- "name": "default",
406
- "rpms": Array [
407
- Object {
408
- "id": 108,
409
- "name": "perl",
410
- },
411
- Object {
412
- "id": 110,
413
- "name": "foo",
414
- },
415
- Object {
416
- "id": 111,
417
- "name": "rpm_0",
418
- },
419
- Object {
420
- "id": 112,
421
- "name": "rpm_1",
422
- },
423
- Object {
424
- "id": 113,
425
- "name": "rpm_2",
426
- },
427
- Object {
428
- "id": 114,
429
- "name": "rpm_3",
430
- },
431
- Object {
432
- "id": 115,
433
- "name": "rpm_4",
434
- },
435
- Object {
436
- "id": 116,
437
- "name": "rpm_5",
438
- },
439
- Object {
440
- "id": 117,
441
- "name": "rpm_6",
442
- },
443
- Object {
444
- "id": 118,
445
- "name": "rpm_7",
446
- },
447
- Object {
448
- "id": 119,
449
- "name": "rpm_8",
450
- },
451
- Object {
452
- "id": 120,
453
- "name": "rpm_9",
454
- },
455
- Object {
456
- "id": 121,
457
- "name": "rpm_10",
458
- },
459
- ],
460
- },
461
- Object {
462
- "id": 38,
463
- "name": "minimal",
464
- "rpms": Array [
465
- Object {
466
- "id": 84,
467
- "name": "python2-avocado",
468
- },
469
- ],
470
- },
471
- ]
472
- }
473
- />,
474
- "tabHeader": "Profiles",
475
- },
476
- Object {
477
- "key": 4,
478
395
  "tabContent": <ModuleStreamDetailArtifacts
479
396
  artifacts={
480
397
  Array [
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: katello
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.0.2
4
+ version: 4.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - N/A
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-11 00:00:00.000000000 Z
11
+ date: 2022-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -87,6 +87,9 @@ dependencies:
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '5.0'
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: '7.0'
90
93
  type: :runtime
91
94
  prerelease: false
92
95
  version_requirements: !ruby/object:Gem::Requirement
@@ -94,6 +97,9 @@ dependencies:
94
97
  - - ">="
95
98
  - !ruby/object:Gem::Version
96
99
  version: '5.0'
100
+ - - "<"
101
+ - !ruby/object:Gem::Version
102
+ version: '7.0'
97
103
  - !ruby/object:Gem::Dependency
98
104
  name: foreman_remote_execution
99
105
  requirement: !ruby/object:Gem::Requirement
@@ -4690,6 +4696,7 @@ files:
4690
4696
  - webpack/components/Table/PageControls.js
4691
4697
  - webpack/components/Table/TableHooks.js
4692
4698
  - webpack/components/Table/TableWrapper.js
4699
+ - webpack/components/Table/__test__/useBulkSelect.test.js
4693
4700
  - webpack/components/Table/helpers.js
4694
4701
  - webpack/components/TooltipButton/TooltipButton.js
4695
4702
  - webpack/components/TooltipButton/TooltipButton.scss
@@ -5388,7 +5395,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
5388
5395
  - !ruby/object:Gem::Version
5389
5396
  version: '0'
5390
5397
  requirements: []
5391
- rubygems_version: 3.2.22
5398
+ rubygems_version: 3.2.33
5392
5399
  signing_key:
5393
5400
  specification_version: 4
5394
5401
  summary: Content and Subscription Management plugin for Foreman