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.
- checksums.yaml +4 -4
- data/app/controllers/katello/api/v2/errata_controller.rb +3 -1
- data/app/controllers/katello/api/v2/module_streams_controller.rb +3 -1
- data/app/controllers/katello/api/v2/package_groups_controller.rb +3 -1
- data/app/lib/actions/pulp3/repository/refresh_distribution.rb +1 -4
- data/app/lib/actions/pulp3/repository/save_distribution_references.rb +0 -2
- data/app/services/katello/content_unit_indexer.rb +1 -2
- data/app/services/katello/pulp3/erratum.rb +1 -1
- data/app/services/katello/pulp3/repository.rb +29 -1
- data/app/views/foreman/smart_proxies/show.html.erb +2 -0
- data/app/views/katello/api/v2/module_streams/show.json.rabl +0 -7
- data/db/migrate/20211220185935_clean_duplicate_content_units.rb +11 -9
- data/db/migrate/20220303160220_remove_duplicate_errata.rb +37 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/mirroring-policy.service.js +1 -1
- data/lib/katello/version.rb +1 -1
- data/webpack/components/Table/TableHooks.js +5 -4
- data/webpack/components/Table/__test__/useBulkSelect.test.js +99 -0
- data/webpack/components/extensions/HostDetails/Tabs/ErrataTab/ErrataTab.js +13 -1
- data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +1 -1
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +30 -3
- data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySetsTab.test.js +40 -15
- data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +2 -2
- data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +1 -1
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +1 -1
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js +2 -2
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/contentViewComponents.test.js +4 -4
- data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +1 -1
- data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +4 -4
- data/webpack/scenes/ContentViews/components/ContentViewsCounter.js +1 -1
- data/webpack/scenes/ContentViews/expansions/DetailsExpansion.js +2 -2
- data/webpack/scenes/ContentViews/expansions/RelatedContentViewComponentsModal.js +2 -2
- data/webpack/scenes/ContentViews/expansions/__tests__/contentViewComponentsModal.test.js +1 -1
- data/webpack/scenes/ModuleStreams/Details/ModuleDetailsSchema.js +1 -10
- data/webpack/scenes/ModuleStreams/Details/ModuleStreamDetails.js +13 -14
- data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetails.test.js.snap +17 -100
- metadata +10 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ba77185c8a7b69f5804f90eca22f14863b4eaf37311fbbfcdd30e95bff824cf
|
4
|
+
data.tar.gz: 024c9250e18577f8897698c4af3d21e432c3986a6b84599876412a715fe2bbc5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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:
|
54
|
+
sync_repository_associations(association_tracker, additive: filtered_indexing)
|
56
55
|
end
|
57
56
|
end
|
58
57
|
|
@@ -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,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
|
-
|
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)
|
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
|
-
|
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 = '
|
13
|
+
this.defaultMirroringPolicy = 'mirror_content_only';
|
14
14
|
|
15
15
|
this.mirroringPolicies = function(repoType) {
|
16
16
|
var policies = {
|
data/lib/katello/version.rb
CHANGED
@@ -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) && `${
|
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 `${
|
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
|
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
|
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')).
|
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
|
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
|
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
|
48
|
-
...
|
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(
|
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(
|
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(
|
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
|
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(
|
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')).
|
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
|
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(
|
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(
|
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(
|
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(
|
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(
|
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={__('
|
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
|
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('
|
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();
|
data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js
CHANGED
@@ -87,7 +87,7 @@ const ComponentContentViewAddModal = ({
|
|
87
87
|
|
88
88
|
return (
|
89
89
|
<Modal
|
90
|
-
title={componentId ? __('Update version') : __('Add
|
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`)}
|
data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewBulkAddModal.js
CHANGED
@@ -51,10 +51,10 @@ const ComponentContentViewBulkAddModal = ({ cvId, rowsToAdd, onClose }) => {
|
|
51
51
|
|
52
52
|
return (
|
53
53
|
<Modal
|
54
|
-
title={__('Add
|
54
|
+
title={__('Add content views')}
|
55
55
|
variant={ModalVariant.large}
|
56
56
|
isOpen
|
57
|
-
description={__('Select available version of
|
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
|
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
|
-
|
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(
|
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('
|
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') : __('
|
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(
|
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('
|
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('
|
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={__('
|
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
|
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
|
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
|
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
|
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
|
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,
|
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
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
{
|
57
|
-
|
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}
|
data/webpack/scenes/ModuleStreams/Details/__tests__/__snapshots__/ModuleStreamDetails.test.js.snap
CHANGED
@@ -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
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
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.
|
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
|
+
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.
|
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
|